]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
sdp: rewrite orphan count logic
authorEldad Zinger <eldadz@mellanox.co.il>
Thu, 22 Jul 2010 05:03:49 +0000 (08:03 +0300)
committerMukesh Kacker <mukesh.kacker@oracle.com>
Tue, 6 Oct 2015 12:05:13 +0000 (05:05 -0700)
orphan count is increased on every call to sdp_common_release and decreased on
every call to sdp_destruct (just before the socket is freed).

Signed-off-by: Eldad Zinger <eldadz@mellanox.co.il>
drivers/infiniband/ulp/sdp/sdp.h
drivers/infiniband/ulp/sdp/sdp_cma.c
drivers/infiniband/ulp/sdp/sdp_dbg.h
drivers/infiniband/ulp/sdp/sdp_main.c

index 9d1d661344c45b7b0ad2c8e2072a2d3d7c2b6a75..69137fb2bf87b5b3f0534e5e1c9fd240a46f33bd 100644 (file)
@@ -117,6 +117,14 @@ struct sdp_skb_cb {
                }                                                       \
        } while (0)
 
+#define sdp_common_release(sk) do { \
+               sdp_dbg(sk, "%s:%d - sock_put(" SOCK_REF_ALIVE \
+                       ") - refcount = %d from withing sk_common_release\n",\
+                       __func__, __LINE__, atomic_read(&(sk)->sk_refcnt));\
+               percpu_counter_inc((sk)->sk_prot->orphan_count);\
+               sk_common_release(sk); \
+} while (0)
+
 extern int sdp_zcopy_thresh;
 extern struct workqueue_struct *sdp_wq;
 extern struct list_head sock_list;
index bcdbcdb609df2a96b9475bd67176ac50360ec2b2..cc44fb7b4c74d3a5b81a869e6f782ceead7bd676 100644 (file)
@@ -511,7 +511,7 @@ int sdp_cma_handler(struct rdma_cm_id *id, struct rdma_cm_event *event)
 done:
                release_sock(parent);
                if (child)
-                       sk_common_release(child);
+                       sdp_common_release(child);
        }
        return rc;
 }
index a9fcf0241e8670aa0f5e2e970be4fa4438e194df..ba4d8c083feb381ba34904639e6e5005ab9ce83c 100644 (file)
@@ -112,13 +112,6 @@ extern int sdp_debug_level;
        }\
 })
 
-#define sk_common_release(sk) do { \
-               sdp_dbg(sk, "%s:%d - sock_put(" SOCK_REF_ALIVE \
-                       ") - refcount = %d from withing sk_common_release\n",\
-                       __func__, __LINE__, atomic_read(&(sk)->sk_refcnt));\
-               sk_common_release(sk); \
-} while (0)
-
 #else /* CONFIG_INFINIBAND_SDP_DEBUG */
 #define sdp_dbg(priv, format, arg...)                        \
        do { (void) (priv); } while (0)
index 3a82c9747c4c4d15960ef24daee3e40bcf8a038e..44dd7de403a32b032ae16fa013e467861493d642 100644 (file)
@@ -517,6 +517,7 @@ static void sdp_destruct(struct sock *sk)
                return;
        }
 
+       percpu_counter_dec(sk->sk_prot->orphan_count);
        cancel_delayed_work(&ssk->srcavail_cancel_work);
 
        ssk->destructed_already = 1;
@@ -534,10 +535,10 @@ static void sdp_destruct(struct sock *sk)
                goto done;
 
        list_for_each_entry_safe(s, t, &ssk->backlog_queue, backlog_queue) {
-               sk_common_release(&s->isk.sk);
+               sdp_common_release(&s->isk.sk);
        }
        list_for_each_entry_safe(s, t, &ssk->accept_queue, accept_queue) {
-               sk_common_release(&s->isk.sk);
+               sdp_common_release(&s->isk.sk);
        }
 
 done:
@@ -663,7 +664,7 @@ static void sdp_close(struct sock *sk, long timeout)
 
                /* Special case: stop listening.
                   This is done by sdp_destruct. */
-               goto adjudge_to_death;
+               goto out;
        }
 
        sock_hold(sk, SOCK_REF_CMA);
@@ -719,46 +720,10 @@ static void sdp_close(struct sock *sk, long timeout)
                               TCPF_CLOSE_WAIT, TCP_CLOSE);
 
        sk_stream_wait_close(sk, timeout);
-
-adjudge_to_death:
-       /* It is the last release_sock in its life. It will remove backlog. */
-       release_sock(sk);
-       /* Now socket is owned by kernel and we acquire lock
-          to finish close. No need to check for user refs.
-        */
-       lock_sock(sk);
-
-       sock_orphan(sk);
-
-       /*      This is a (useful) BSD violating of the RFC. There is a
-        *      problem with TCP as specified in that the other end could
-        *      keep a socket open forever with no application left this end.
-        *      We use a 3 minute timeout (about the same as BSD) then kill
-        *      our end. If they send after that then tough - BUT: long enough
-        *      that we won't make the old 4*rto = almost no time - whoops
-        *      reset mistake.
-        *
-        *      Nope, it was not mistake. It is really desired behaviour
-        *      f.e. on http servers, when such sockets are useless, but
-        *      consume significant resources. Let's do it with special
-        *      linger2 option.                                 --ANK
-        */
-       if ((1 << sk->sk_state) & (TCPF_FIN_WAIT1 | TCPF_TIME_WAIT | TCPF_LAST_ACK)) {
-               /* TODO: liger2 unimplemented.
-                  We should wait 3.5 * rto. How do I know rto? */
-               /* TODO: tcp_fin_time to get timeout */
-               sdp_dbg(sk, "%s: entering time wait refcnt %d\n", __func__,
-                       atomic_read(&sk->sk_refcnt));
-               percpu_counter_inc(sk->sk_prot->orphan_count);
-       }
-
-       /* TODO: limit number of orphaned sockets.
-          TCP has sysctl_tcp_mem and sysctl_tcp_max_orphans */
-
 out:
        release_sock(sk);
 
-       sk_common_release(sk);
+       sdp_common_release(sk);
 }
 
 static int sdp_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
@@ -841,10 +806,10 @@ static int sdp_disconnect(struct sock *sk, int flags)
                rdma_destroy_id(id);
 
        list_for_each_entry_safe(s, t, &ssk->backlog_queue, backlog_queue) {
-               sk_common_release(&s->isk.sk);
+               sdp_common_release(&s->isk.sk);
        }
        list_for_each_entry_safe(s, t, &ssk->accept_queue, accept_queue) {
-               sk_common_release(&s->isk.sk);
+               sdp_common_release(&s->isk.sk);
        }
 
        lock_sock(sk);
@@ -1025,8 +990,6 @@ void sdp_cancel_dreq_wait_timeout(struct sdp_sock *ssk)
                /* The timeout hasn't reached - need to clean ref count */
                sock_put(&ssk->isk.sk, SOCK_REF_DREQ_TO);
        }
-
-       percpu_counter_dec(ssk->isk.sk.sk_prot->orphan_count);
 }
 
 static void sdp_destroy_work(struct work_struct *work)
@@ -1089,10 +1052,6 @@ static void sdp_dreq_wait_timeout_work(struct work_struct *work)
                 "going into abortive close.\n");
 
        sdp_sk(sk)->dreq_wait_timeout = 0;
-
-       if (sk->sk_state == TCP_FIN_WAIT1)
-               percpu_counter_dec(ssk->isk.sk.sk_prot->orphan_count);
-
        sdp_exch_state(sk, TCPF_LAST_ACK | TCPF_FIN_WAIT1, TCP_TIME_WAIT);
 
        release_sock(sk);
@@ -1195,8 +1154,6 @@ static void sdp_shutdown(struct sock *sk, int how)
        if (ssk->nonagle & TCP_NAGLE_OFF)
                ssk->nonagle |= TCP_NAGLE_PUSH;
 
-       percpu_counter_inc(ssk->isk.sk.sk_prot->orphan_count);
-
        sdp_send_disconnect(sk);
 }
 
@@ -2746,7 +2703,7 @@ static int sdp_create_socket(struct net *net, struct socket *sock, int protocol)
        rc = sdp_init_sock(sk);
        if (rc) {
                sdp_warn(sk, "SDP: failed to init sock.\n");
-               sk_common_release(sk);
+               sdp_common_release(sk);
                return -ENOMEM;
        }