[openib-general] Re: RE: Re: [PATCH] ipoib_flush_paths

Michael S. Tsirkin mst at mellanox.co.il
Thu Apr 6 08:26:49 PDT 2006


Quoting r. Michael S. Tsirkin <mst at mellanox.co.il>:
> Actually, it turned out to be the simplest solution - and quite
> elegant since there's no room for mistakes: if query is going to be running
> this means module is still loaded so we can take a reference to it
> without races.

And Here's the patch to ib_addr. Sean, Roland, please comment.

---

Prevent module from being unloaded while callback from ib_addr has signaled
completion but is still running.

Signed-off-by: Michael S. Tsirkin <mst at mellanox.co.il>

Index: linux-2.6.16/include/rdma/ib_addr.h
===================================================================
--- linux-2.6.16/include/rdma/ib_addr.h	(revision 6281)
+++ linux-2.6.16/include/rdma/ib_addr.h	(working copy)
@@ -63,12 +63,13 @@
  * @callback: Call invoked once address resolution has completed, timed out,
  *   or been canceled.  A status of 0 indicates success.
  * @context: User-specified context associated with the call.
+ * @owner: Module that owns the callback.
  */
 int rdma_resolve_ip(struct sockaddr *src_addr, struct sockaddr *dst_addr,
 		    struct rdma_dev_addr *addr, int timeout_ms,
 		    void (*callback)(int status, struct sockaddr *src_addr,
 				     struct rdma_dev_addr *addr, void *context),
-		    void *context);
+		    void *context, struct module *owner);
 
 void rdma_addr_cancel(struct rdma_dev_addr *addr);
 
Index: linux-2.6.16/drivers/infiniband/core/addr.c
===================================================================
--- linux-2.6.16/drivers/infiniband/core/addr.c	(revision 6281)
+++ linux-2.6.16/drivers/infiniband/core/addr.c	(working copy)
@@ -76,6 +76,7 @@
 	void *context;
 	void (*callback)(int status, struct sockaddr *src_addr,
 			 struct rdma_dev_addr *addr, void *context);
+	struct module *owner;
 	unsigned long timeout;
 	int status;
 };
@@ -252,8 +253,10 @@
 
 	list_for_each_entry_safe(req, temp_req, &done_list, list) {
 		list_del(&req->list);
+		__module_get(req->owner);
 		req->callback(req->status, &req->src_addr, req->addr,
 			      req->context);
+		module_put(req->owner);
 		kfree(req);
 	}
 }
@@ -293,7 +296,7 @@
 		    struct rdma_dev_addr *addr, int timeout_ms,
 		    void (*callback)(int status, struct sockaddr *src_addr,
 				     struct rdma_dev_addr *addr, void *context),
-		    void *context)
+		    void *context, struct module *owner)
 {
 	struct sockaddr_in *src_in, *dst_in;
 	struct addr_req *req;
@@ -310,6 +313,7 @@
 	req->addr = addr;
 	req->callback = callback;
 	req->context = context;
+	req->owner = owner;
 
 	src_in = (struct sockaddr_in *) &req->src_addr;
 	dst_in = (struct sockaddr_in *) &req->dst_addr;

-- 
MST



More information about the general mailing list