[ofa-general] Race condition in core/sysfs.c (kernel panic) when unloading the driver

Roland Dreier rdreier at cisco.com
Sun Feb 22 20:40:53 PST 2009


 > There is still a problem, which we do not see with ConnectX (because
 > of the separation between mlx4_ib and mlx4_core -- and we are
 > unloading only mlx4_ib, leaving all the mlx4_core infrastructure
 > intact).
 > 
 > I tried your test with a Sinai card (mthca, and got the following
 > Kernel Oops (on Kernel 2,6,27.4) (Note that ib_mthca is still loaded,
 > but with "(-)" following).

Oh I see... we leave the sysfs stuff around way too long, since we want
to use it for tracking the lifetime of our class device.  the patch
below fixes things for me here... there's still room for substantial
cleanup but I think this gets the crashes fixed at least:

diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c
index 7913b80..d1fba41 100644
--- a/drivers/infiniband/core/device.c
+++ b/drivers/infiniband/core/device.c
@@ -193,7 +193,7 @@ void ib_dealloc_device(struct ib_device *device)
 
 	BUG_ON(device->reg_state != IB_DEV_UNREGISTERED);
 
-	ib_device_unregister_sysfs(device);
+	kobject_put(&device->dev.kobj);
 }
 EXPORT_SYMBOL(ib_dealloc_device);
 
@@ -348,6 +348,8 @@ void ib_unregister_device(struct ib_device *device)
 
 	mutex_unlock(&device_mutex);
 
+	ib_device_unregister_sysfs(device);
+
 	spin_lock_irqsave(&device->client_data_lock, flags);
 	list_for_each_entry_safe(context, tmp, &device->client_data_list, list)
 		kfree(context);
diff --git a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c
index b43f7d3..5270aeb 100644
--- a/drivers/infiniband/core/sysfs.c
+++ b/drivers/infiniband/core/sysfs.c
@@ -848,6 +848,9 @@ void ib_device_unregister_sysfs(struct ib_device *device)
 	struct kobject *p, *t;
 	struct ib_port *port;
 
+	/* Hold kobject until ib_dealloc_device() */
+	kobject_get(&device->dev.kobj);
+
 	list_for_each_entry_safe(p, t, &device->port_list, entry) {
 		list_del(&p->entry);
 		port = container_of(p, struct ib_port, kobj);



More information about the general mailing list