[ofa-general] [PATCH] for-2.6.25: ib/cm: flush workqueue when removing device

Sean Hefty sean.hefty at intel.com
Fri Feb 22 10:40:45 PST 2008


When a cm mad is received, it is queued to a cm workqueue for
processing.  The queued work item references the port and device
on which the mad was received.  If that device is removed from
the system before the work item can execute, the work item will
reference freed memory.

To fix this, flush the workqueue after unregistering to receive
mads, and before the device can be freed.

Signed-off-by: Sean Hefty <sean.hefty at intel.com>
---
Bug found with SDP testing on OFED 1.3.  The patch is also available at:

	git://git.openfabrics.org/~shefty/rdma-dev.git for-roland

 drivers/infiniband/core/cm.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c
index b10ade9..4df4051 100644
--- a/drivers/infiniband/core/cm.c
+++ b/drivers/infiniband/core/cm.c
@@ -3759,6 +3759,7 @@ static void cm_remove_one(struct ib_device *device)
 		port = cm_dev->port[i-1];
 		ib_modify_port(device, port->port_num, 0, &port_modify);
 		ib_unregister_mad_agent(port->mad_agent);
+		flush_workqueue(cm.wq);
 		cm_remove_port_fs(port);
 	}
 	kobject_put(&cm_dev->dev_obj);
@@ -3813,6 +3814,7 @@ static void __exit ib_cm_cleanup(void)
 		cancel_delayed_work(&timewait_info->work.work);
 	spin_unlock_irq(&cm.lock);
 
+	ib_unregister_client(&cm_client);
 	destroy_workqueue(cm.wq);
 
 	list_for_each_entry_safe(timewait_info, tmp, &cm.timewait_list, list) {
@@ -3820,7 +3822,6 @@ static void __exit ib_cm_cleanup(void)
 		kfree(timewait_info);
 	}
 
-	ib_unregister_client(&cm_client);
 	class_unregister(&cm_class);
 	idr_destroy(&cm.local_id_table);
 }






More information about the general mailing list