[openib-general] [PATCH 1 of 2] core extensions to fix race at module unloading

Michael S. Tsirkin mst at mellanox.co.il
Fri Apr 21 00:28:13 PDT 2006


Hi!
The only viable approach left that I see to solve module unloading races is
adding APIs to flush running callbacks.

Please review the following.

---

Add APIs to flush outstanding callbacks - required for loadable modules
where module text could go away while callback is still running.

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

Index: openib/drivers/infiniband/include/rdma/ib_mad.h
===================================================================
--- openib/drivers/infiniband/include/rdma/ib_mad.h	(revision 6545)
+++ openib/drivers/infiniband/include/rdma/ib_mad.h	(working copy)
@@ -482,6 +482,12 @@ struct ib_mad_agent *ib_register_mad_sno
 int ib_unregister_mad_agent(struct ib_mad_agent *mad_agent);
 
 /**
+ * ib_flush_mad_agent - flush any callbacks in flight for this client.
+ * @mad_agent: Corresponding MAD registration request to flush.
+ */
+int ib_flush_mad_agent(struct ib_mad_agent *mad_agent);
+
+/**
  * ib_post_send_mad - Posts MAD(s) to the send queue of the QP associated
  *   with the registered client.
  * @send_buf: Specifies the information needed to send the MAD(s).
Index: openib/drivers/infiniband/include/rdma/ib_sa.h
===================================================================
--- openib/drivers/infiniband/include/rdma/ib_sa.h	(revision 6545)
+++ openib/drivers/infiniband/include/rdma/ib_sa.h	(working copy)
@@ -253,6 +253,7 @@ struct ib_sa_service_rec {
 struct ib_sa_query;
 
 void ib_sa_cancel_query(int id, struct ib_sa_query *query);
+void ib_sa_flush(struct ib_device *device);
 
 int ib_sa_path_rec_get(struct ib_device *device, u8 port_num,
 		       struct ib_sa_path_rec *rec,
Index: openib/drivers/infiniband/include/rdma/ib_addr.h
===================================================================
--- openib/drivers/infiniband/include/rdma/ib_addr.h	(revision 6545)
+++ openib/drivers/infiniband/include/rdma/ib_addr.h	(working copy)
@@ -71,6 +71,7 @@ int rdma_resolve_ip(struct sockaddr *src
 		    void *context);
 
 void rdma_addr_cancel(struct rdma_dev_addr *addr);
+void rdma_addr_flush();
 
 static inline int ip_addr_size(struct sockaddr *addr)
 {
Index: openib/drivers/infiniband/core/addr.c
===================================================================
--- openib/drivers/infiniband/core/addr.c	(revision 6545)
+++ openib/drivers/infiniband/core/addr.c	(working copy)
@@ -356,6 +356,12 @@ void rdma_addr_cancel(struct rdma_dev_ad
 }
 EXPORT_SYMBOL(rdma_addr_cancel);
 
+void rdma_addr_flush(void)
+{
+	flush_workqueue(addr_wq);
+}
+EXPORT_SYMBOL(rdma_addr_flush);
+
 static int addr_arp_recv(struct sk_buff *skb, struct net_device *dev,
 			 struct packet_type *pkt, struct net_device *orig_dev)
 {
Index: openib/drivers/infiniband/core/sa_query.c
===================================================================
--- openib/drivers/infiniband/core/sa_query.c	(revision 6545)
+++ openib/drivers/infiniband/core/sa_query.c	(working copy)
@@ -440,6 +440,20 @@ void ib_sa_cancel_query(int id, struct i
 }
 EXPORT_SYMBOL(ib_sa_cancel_query);
 
+void ib_sa_flush(struct ib_device *device)
+{
+	struct ib_sa_device *sa_dev = ib_get_client_data(device, &sa_client);
+	int i;
+
+	if (!sa_dev)
+		return;
+
+	for (i = 0; i <= sa_dev->end_port - sa_dev->start_port; ++i) {
+		ib_flush_mad_agent(sa_dev->port[i].agent);
+	}
+}
+EXPORT_SYMBOL(ib_sa_flush);
+
 int ib_sa_pack_attr(void *dst, void *src, int attr_id)
 {
 	switch (attr_id) {
Index: openib/drivers/infiniband/core/mad.c
===================================================================
--- openib/drivers/infiniband/core/mad.c	(revision 6545)
+++ openib/drivers/infiniband/core/mad.c	(working copy)
@@ -486,6 +486,13 @@ error1:
 }
 EXPORT_SYMBOL(ib_register_mad_snoop);
 
+static void ib_flush_mad_agent(struct ib_mad_agent_private *mad_agent_priv)
+{
+	port_priv = mad_agent_priv->qp_info->port_priv;
+	flush_workqueue(port_priv->wq);
+}
+EXPORT_SYMBOL(ib_flush_mad_agent);
+
 static void unregister_mad_agent(struct ib_mad_agent_private *mad_agent_priv)
 {
 	struct ib_mad_port_private *port_priv;
-- 
MST



More information about the general mailing list