[ofa-general] [PATCH 1/1 V2] SDP - Fix reference count bug that prevents mlx4_ib and ib_sdp unload

Jim Mott jim at mellanox.com
Tue Nov 6 14:53:35 PST 2007


Add code to fix a problem found by the Mellanox regression group.  When
mlx4_ib driver is unloaded while SDP connections are active, the unloads
would hang.
    
The original fix for this problem called an rdma_cm service that can
block
with 2 spin locks held.  This version does not hold any locks during the

call.
    
Signed-off-by: Jim Mott <jim at mellanox.com>
---

--- ofed_1_3.orig/drivers/infiniband/ulp/sdp/sdp_main.c 2007-11-06
14:21:26.000000000 -0800
+++ ofed_1_3/drivers/infiniband/ulp/sdp/sdp_main.c      2007-11-06
14:22:19.000000000 -0800
@@ -2234,10 +2234,12 @@ static void sdp_add_device(struct ib_dev

 static void sdp_remove_device(struct ib_device *device)
 {
-       struct list_head *p;
-       struct sdp_sock  *ssk;
-       struct sock      *sk;
+       struct list_head  *p;
+       struct sdp_sock   *ssk;
+       struct sock       *sk;
+       struct rdma_cm_id *id;

+do_next:
        write_lock(&device_removal_lock);

        spin_lock_irq(&sock_list_lock);
@@ -2245,16 +2247,30 @@ static void sdp_remove_device(struct ib_
                ssk = list_entry(p, struct sdp_sock, sock_list);
                if (ssk->ib_device == device) {
                        sk = &ssk->isk.sk;
+                       id = ssk->id;

-                       if (ssk->id) {
-                               rdma_destroy_id(ssk->id);
+                       if (id) {
                                ssk->id = NULL;
+
+                               spin_unlock_irq(&sock_list_lock);
+                               write_unlock(&device_removal_lock);
+                               rdma_destroy_id(id);
+
+                               goto do_next;
                        }
+               }
+       }
+
+       list_for_each(p, &sock_list) {
+               ssk = list_entry(p, struct sdp_sock, sock_list);
+               if (ssk->ib_device == device) {
+                       sk = &ssk->isk.sk;

                        sk->sk_shutdown |= RCV_SHUTDOWN;
                        sdp_reset(sk);
                }
        }
+
        spin_unlock_irq(&sock_list_lock);

        write_unlock(&device_removal_lock);




More information about the general mailing list