diff options
author | Hal Rosenstock | 2005-07-27 20:45:29 +0200 |
---|---|---|
committer | Linus Torvalds | 2005-07-28 01:26:10 +0200 |
commit | f75b7a5294949cd1b7bc301e3087c7bb78e22520 (patch) | |
tree | faea8070eb47b3526daa32dbb60f405f958e4a7e | |
parent | [PATCH] IB: Add ib_coalesce_recv_mad to MAD (diff) | |
download | kernel-qcow2-linux-f75b7a5294949cd1b7bc301e3087c7bb78e22520.tar.gz kernel-qcow2-linux-f75b7a5294949cd1b7bc301e3087c7bb78e22520.tar.xz kernel-qcow2-linux-f75b7a5294949cd1b7bc301e3087c7bb78e22520.zip |
[PATCH] IB: Add automatic retries to MAD layer
Add automatic retries to MAD layer.
Signed-off-by: Sean Hefty <sean.hefty@intel.com>
Signed-off-by: Hal Rosenstock <halr@voltaire.com>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r-- | drivers/infiniband/core/mad.c | 26 | ||||
-rw-r--r-- | drivers/infiniband/core/mad_priv.h | 2 | ||||
-rw-r--r-- | drivers/infiniband/core/sa_query.c | 3 | ||||
-rw-r--r-- | drivers/infiniband/core/user_mad.c | 1 | ||||
-rw-r--r-- | drivers/infiniband/include/ib_verbs.h | 1 |
5 files changed, 31 insertions, 2 deletions
diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c index 430a6ee89877..04f88d337388 100644 --- a/drivers/infiniband/core/mad.c +++ b/drivers/infiniband/core/mad.c @@ -954,7 +954,7 @@ int ib_post_send_mad(struct ib_mad_agent *mad_agent, /* Timeout will be updated after send completes */ mad_send_wr->timeout = msecs_to_jiffies(send_wr->wr. ud.timeout_ms); - mad_send_wr->retry = 0; + mad_send_wr->retries = mad_send_wr->send_wr.wr.ud.retries; /* One reference for each work request to QP + response */ mad_send_wr->refcount = 1 + (mad_send_wr->timeout > 0); mad_send_wr->status = IB_WC_SUCCESS; @@ -2174,6 +2174,27 @@ local_send_completion: spin_unlock_irqrestore(&mad_agent_priv->lock, flags); } +static int retry_send(struct ib_mad_send_wr_private *mad_send_wr) +{ + int ret; + + if (!mad_send_wr->retries--) + return -ETIMEDOUT; + + mad_send_wr->timeout = msecs_to_jiffies(mad_send_wr->send_wr. + wr.ud.timeout_ms); + + ret = ib_send_mad(mad_send_wr); + + if (!ret) { + mad_send_wr->refcount++; + list_del(&mad_send_wr->agent_list); + list_add_tail(&mad_send_wr->agent_list, + &mad_send_wr->mad_agent_priv->send_list); + } + return ret; +} + static void timeout_sends(void *data) { struct ib_mad_agent_private *mad_agent_priv; @@ -2202,6 +2223,9 @@ static void timeout_sends(void *data) break; } + if (!retry_send(mad_send_wr)) + continue; + list_del(&mad_send_wr->agent_list); spin_unlock_irqrestore(&mad_agent_priv->lock, flags); diff --git a/drivers/infiniband/core/mad_priv.h b/drivers/infiniband/core/mad_priv.h index 6fcab0009bb9..8a61dd921d29 100644 --- a/drivers/infiniband/core/mad_priv.h +++ b/drivers/infiniband/core/mad_priv.h @@ -123,6 +123,7 @@ struct ib_mad_send_wr_private { u64 wr_id; /* client WR ID */ u64 tid; unsigned long timeout; + int retries; int retry; int refcount; enum ib_wc_status status; @@ -136,6 +137,7 @@ struct ib_mad_local_private { struct ib_sge sg_list[IB_MAD_SEND_REQ_MAX_SG]; u64 wr_id; /* client WR ID */ u64 tid; + int retries; }; struct ib_mad_mgmt_method_table { diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c index 649824e33253..9ef8fe0163dd 100644 --- a/drivers/infiniband/core/sa_query.c +++ b/drivers/infiniband/core/sa_query.c @@ -462,7 +462,8 @@ static int send_mad(struct ib_sa_query *query, int timeout_ms) .mad_hdr = &query->mad->mad_hdr, .remote_qpn = 1, .remote_qkey = IB_QP1_QKEY, - .timeout_ms = timeout_ms + .timeout_ms = timeout_ms, + .retries = 0 } } }; diff --git a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c index 9d912d6877ff..088bb1f0f514 100644 --- a/drivers/infiniband/core/user_mad.c +++ b/drivers/infiniband/core/user_mad.c @@ -322,6 +322,7 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf, wr.wr.ud.remote_qpn = be32_to_cpu(packet->mad.qpn); wr.wr.ud.remote_qkey = be32_to_cpu(packet->mad.qkey); wr.wr.ud.timeout_ms = packet->mad.timeout_ms; + wr.wr.ud.retries = 0; wr.wr_id = (unsigned long) packet; diff --git a/drivers/infiniband/include/ib_verbs.h b/drivers/infiniband/include/ib_verbs.h index e5bd9a10c201..b6107c4b683a 100644 --- a/drivers/infiniband/include/ib_verbs.h +++ b/drivers/infiniband/include/ib_verbs.h @@ -566,6 +566,7 @@ struct ib_send_wr { u32 remote_qpn; u32 remote_qkey; int timeout_ms; /* valid for MADs only */ + int retries; /* valid for MADs only */ u16 pkey_index; /* valid for GSI only */ u8 port_num; /* valid for DR SMPs on switch only */ } ud; |