[openib-general] [PATCH] ib_mad.c: On completion, use first entry rather than walking send/receive lists
Hal Rosenstock
halr at voltaire.com
Mon Sep 13 05:43:14 PDT 2004
ib_mad.c: On completion, use first entry rather than walking
send/receive lists
Index: ib_mad.c
===================================================================
--- ib_mad.c (revision 795)
+++ ib_mad.c (working copy)
@@ -144,7 +144,10 @@
goto error1;
}
} else if (mad_reg_req->mgmt_class == 0) {
- /* Class 0 is reserved and used for aliasing
IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE */
+ /*
+ * Class 0 is reserved in IBA and is used here for
+ * aliasing of IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE
+ */
ret = ERR_PTR(-EINVAL);
goto error1;
}
@@ -564,31 +567,31 @@
struct ib_wc *wc)
{
struct ib_mad_recv_wc recv_wc;
- struct ib_mad_private_header *entry, *temp;
- struct ib_mad_private *recv = NULL;
+ struct ib_mad_private *recv;
unsigned long flags;
u32 qp_num;
/* WC WRID is the QP number */
qp_num = wc->wr_id;
- /* Find entry on posted MAD receive list which corresponds to this
completion */
+ /*
+ * Completion corresponds to first entry on
+ * posted MAD receive list based on WRID in completion
+ */
spin_lock_irqsave(&priv->recv_list_lock, flags);
- list_for_each_entry_safe(entry, temp,
- &priv->recv_posted_mad_list[convert_qpnum(qp_num)],
- mad_list) {
- if ((unsigned long)entry == wc->wr_id) {
- recv = (struct ib_mad_private *)entry;
- /* Remove from posted receive MAD list */
- list_del(&entry->mad_list);
- priv->recv_posted_mad_count[convert_qpnum(qp_num)]--;
- break;
- }
+ if (!list_empty(&priv->recv_posted_mad_list[convert_qpnum(qp_num)])) {
+ recv = list_entry(&priv->recv_posted_mad_list[convert_qpnum(qp_num)],
+ struct ib_mad_private,
+ header.mad_list);
+ /* Remove from posted receive MAD list */
+ list_del(&recv->header.mad_list);
+ priv->recv_posted_mad_count[convert_qpnum(qp_num)]--;
+ } else {
+ printk(KERN_ERR "Receive completion WR ID 0x%Lx on QP %d with no
posted receive\n", wc->wr_id, qp_num);
+ spin_unlock_irqrestore(&priv->recv_list_lock, flags);
+ return;
}
spin_unlock_irqrestore(&priv->recv_list_lock, flags);
- if (!recv) {
- printk(KERN_ERR "No matching posted receive WR 0x%Lx\n", wc->wr_id);
- }
/* Setup MAD receive work completion from normal one */
recv_wc.wr_id = wc->wr_id;
@@ -609,43 +612,51 @@
recv_wc.sl = wc->sl;
recv_wc.dlid_path_bits = wc->dlid_path_bits;
- /* Need to figure out MAD agent !!! */
+ /* Determine corresponding MAD agent for incoming receive MAD */
/* Invoke client receive callback */
- /* Receive reposting ? !!! */
+ /* When to repost receive request ? !!! */
}
static void ib_mad_send_done_handler(struct ib_mad_port_private *priv,
struct ib_wc *wc)
{
- struct ib_mad_send_wr_private *entry, *temp, *send_wr = NULL;
+ struct ib_mad_send_wr_private *send_wr;
unsigned long flags;
- /* Find entry on posted MAD send list which corresponds to this
completion */
+ /* Completion corresponds to first entry on posted MAD send list */
spin_lock_irqsave(&priv->send_list_lock, flags);
- list_for_each_entry_safe(entry, temp,
- &priv->send_posted_mad_list, send_list) {
- if (entry->wr_id == wc->wr_id) {
- send_wr = entry;
- /* Remove from posted send MAD list */
- list_del(&entry->send_list);
- priv->send_posted_mad_count--;
- break;
+ if (!list_empty(&priv->send_posted_mad_list)) {
+ send_wr = list_entry(&priv->send_posted_mad_list,
+ struct ib_mad_send_wr_private,
+ send_list);
+ if (send_wr->wr_id != wc->wr_id) {
+ printk(KERN_ERR "Send completion WR ID 0x%Lx doesn't match posted
send WR ID 0x%Lx\n", wc->wr_id, send_wr->wr_id);
+
+ goto error;
}
+ /* Remove from posted send MAD list */
+ list_del(&send_wr->send_list);
+ priv->send_posted_mad_count--;
+ } else {
+ printk(KERN_ERR "Send completion WR ID 0x%Lx but send list is
empty\n", wc->wr_id);
+ goto error;
}
spin_unlock_irqrestore(&priv->send_list_lock, flags);
- if (!send_wr) {
- printk(KERN_ERR "No matching posted send WR 0x%Lx\n", wc->wr_id);
- } else {
- /* Restore client wr_id in WC */
- wc->wr_id = send_wr->wr_id;
- /* Invoke client send callback */
- send_wr->agent->send_handler(send_wr->agent,
- (struct ib_mad_send_wc *)wc);
- /* Release send MAD WR tracking structure */
- kfree(send_wr);
- }
+
+ /* Restore client wr_id in WC */
+ wc->wr_id = send_wr->wr_id;
+ /* Invoke client send callback */
+ send_wr->agent->send_handler(send_wr->agent,
+ (struct ib_mad_send_wc *)wc);
+ /* Release send MAD WR tracking structure */
+ kfree(send_wr);
+ return;
+
+error:
+ spin_unlock_irqrestore(&priv->send_list_lock, flags);
+ return;
}
/*
More information about the general
mailing list