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 <[EMAIL PROTECTED]>

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
_______________________________________________
openib-general mailing list
[email protected]
http://openib.org/mailman/listinfo/openib-general

To unsubscribe, please visit http://openib.org/mailman/listinfo/openib-general

Reply via email to