]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
sdp: flush rx_comp_work before destroying socket + make dreq_wait_timeout_work flushi...
authorAmir Vadai <amirv@mellanox.co.il>
Thu, 26 Nov 2009 15:10:57 +0000 (17:10 +0200)
committerMukesh Kacker <mukesh.kacker@oracle.com>
Tue, 6 Oct 2015 12:04:42 +0000 (05:04 -0700)
Signed-off-by: Amir Vadai <amirv@mellanox.co.il>
drivers/infiniband/ulp/sdp/sdp.h
drivers/infiniband/ulp/sdp/sdp_main.c

index d6ba236ec1c88f3ed3afd98b9139bfbe8bbf6059..d67a973d1b55ec44c26f02d78f480f3f07c7bc55 100644 (file)
@@ -726,9 +726,7 @@ void sdp_start_keepalive_timer(struct sock *sk);
 void sdp_remove_sock(struct sdp_sock *ssk);
 void sdp_add_sock(struct sdp_sock *ssk);
 void sdp_urg(struct sdp_sock *ssk, struct sk_buff *skb);
-void sdp_dreq_wait_timeout_work(struct work_struct *work);
 void sdp_cancel_dreq_wait_timeout(struct sdp_sock *ssk);
-void sdp_destroy_work(struct work_struct *work);
 void sdp_reset_sk(struct sock *sk, int rc);
 void sdp_reset(struct sock *sk);
 int sdp_tx_wait_memory(struct sdp_sock *ssk, long *timeo_p, int *credits_needed);
index bb8a15be71085eaf67a961633a0f6c2201772f9b..61ad1c8898a05a56b4c8c88d27187d14a1fedda5 100644 (file)
@@ -958,7 +958,7 @@ void sdp_cancel_dreq_wait_timeout(struct sdp_sock *ssk)
        sdp_dbg(&ssk->isk.sk, "cancelling dreq wait timeout\n");
 
        ssk->dreq_wait_timeout = 0;
-       if (cancel_delayed_work(&ssk->dreq_wait_work)) {
+       if (cancel_delayed_work_sync(&ssk->dreq_wait_work)) {
                /* The timeout hasn't reached - need to clean ref count */
                sock_put(&ssk->isk.sk, SOCK_REF_DREQ_TO);
        }
@@ -966,7 +966,7 @@ void sdp_cancel_dreq_wait_timeout(struct sdp_sock *ssk)
        percpu_counter_dec(ssk->isk.sk.sk_prot->orphan_count);
 }
 
-void sdp_destroy_work(struct work_struct *work)
+static void sdp_destroy_work(struct work_struct *work)
 {
        struct sdp_sock *ssk = container_of(work, struct sdp_sock,
                        destroy_work);
@@ -975,6 +975,13 @@ void sdp_destroy_work(struct work_struct *work)
 
        sdp_destroy_qp(ssk);
 
+       /* Can be sure that rx_comp_work won't be queued from here cause
+        * ssk->rx_ring.cq is NULL from here
+        */
+       if (cancel_work_sync(&ssk->rx_comp_work)) {
+               sdp_dbg(sk, "RX completion work was queued during destroy\n");
+       }
+
        memset((void *)&ssk->id, 0, sizeof(*ssk) - offsetof(typeof(*ssk), id));
 
        sdp_cancel_dreq_wait_timeout(ssk);
@@ -991,15 +998,18 @@ void sdp_destroy_work(struct work_struct *work)
        sock_put(sk, SOCK_REF_RESET);
 }
 
-void sdp_dreq_wait_timeout_work(struct work_struct *work)
+static void sdp_dreq_wait_timeout_work(struct work_struct *work)
 {
        struct sdp_sock *ssk =
                container_of(work, struct sdp_sock, dreq_wait_work.work);
        struct sock *sk = &ssk->isk.sk;
+       
+       if (!ssk->dreq_wait_timeout)
+               goto out;
 
        lock_sock(sk);
 
-       if (!sdp_sk(sk)->dreq_wait_timeout ||
+       if (!ssk->dreq_wait_timeout ||
            !((1 << sk->sk_state) & (TCPF_FIN_WAIT1 | TCPF_LAST_ACK))) {
                release_sock(sk);
                goto out;
@@ -1036,6 +1046,9 @@ static struct lock_class_key ib_sdp_sk_receive_queue_lock_key;
 
 static struct lock_class_key ib_sdp_sk_callback_lock_key;
 
+static void sdp_destroy_work(struct work_struct *work);
+static void sdp_dreq_wait_timeout_work(struct work_struct *work);
+
 int sdp_init_sock(struct sock *sk)
 {
        struct sdp_sock *ssk = sdp_sk(sk);