Here's a patch for discussion for an API and implementation that should allow 
canceling a sent MAD.

The primary use of the call is to cancel a MAD with a large timeout, but it should 
also allow cancel sending a large RMPP MAD.

- Sean

-- 
Index: access/ib_mad.c
===================================================================
--- access/ib_mad.c     (revision 913)
+++ access/ib_mad.c     (working copy)
@@ -1028,6 +1028,54 @@
        }
 }
 
+int ib_cancel_mad(struct ib_mad_agent *mad_agent,
+                 u64 wr_id)
+{
+       struct ib_mad_agent_private *mad_agent_priv;
+       struct ib_mad_send_wr_private *mad_send_wr;
+       struct ib_mad_send_wc mad_send_wc;
+       unsigned long flags;
+
+       mad_agent_priv = container_of(mad_agent, struct ib_mad_agent_private,
+                                     agent);
+       spin_lock_irqsave(&mad_agent_priv->send_list_lock, flags);
+       list_for_each_entry(mad_send_wr, &mad_agent_priv->send_list,
+                           agent_send_list) {
+               if (mad_send_wr->wr_id == wr_id)
+                       goto found;
+       }
+       spin_unlock_irqrestore(&mad_agent_priv->send_list_lock, flags);
+       return -EINVAL;
+
+found:
+       if (mad_send_wr->status == IB_WC_SUCCESS)
+               mad_send_wr->status = IB_WC_WR_FLUSH_ERR;
+
+       if (mad_send_wr->timeout_ms) {
+               mad_send_wr->timeout_ms = 0;
+               mad_send_wr->refcount--;
+       }
+
+       if (mad_send_wr->refcount == 0) {
+               list_del(&mad_send_wr->agent_send_list);
+               spin_unlock_irqrestore(&mad_agent_priv->send_list_lock, flags);
+
+               mad_send_wc.status = IB_WC_WR_FLUSH_ERR;
+               mad_send_wc.vendor_err = 0;
+               mad_send_wc.wr_id = mad_send_wr->wr_id;
+               mad_agent_priv->agent.send_handler(&mad_agent_priv->agent,
+                                                       &mad_send_wc);
+
+               kfree(mad_send_wr);
+               if (atomic_dec_and_test(&mad_agent_priv->refcount))
+                       wake_up(&mad_agent_priv->wait);
+               return 0;
+       }
+       spin_unlock_irqrestore(&mad_agent_priv->send_list_lock, flags);
+       return -EBUSY;
+}
+EXPORT_SYMBOL(ib_cancel_mad);
+
 /*
  * IB MAD thread
  */
Index: include/ib_mad.h
===================================================================
--- include/ib_mad.h    (revision 913)
+++ include/ib_mad.h    (working copy)
@@ -275,6 +275,17 @@
 void ib_free_recv_mad(struct ib_mad_recv_wc *mad_recv_wc);
 
 /**
+ * ib_cancel_mad - Cancels an outstanding send MAD operation.
+ * @mad_agent - Specifies the registration associated with sent MAD.
+ * @wr_id - Indicates the work request identifier of the MAD to cancel.
+ *
+ * If the MAD is successfully canceled, it will be returned to the user through
+ * the corresponding ib_mad_send_handler.
+ */
+int ib_cancel_mad(struct ib_mad_agent *mad_agent,
+                 u64 wr_id);
+
+/**
  * ib_redirect_mad_qp - Registers a QP for MAD services.
  * @qp - Reference to a QP that requires MAD services.
  * @rmpp_version - If set, indicates that the client will send
_______________________________________________
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