diff options
-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, | |||
954 | /* Timeout will be updated after send completes */ | 954 | /* Timeout will be updated after send completes */ |
955 | mad_send_wr->timeout = msecs_to_jiffies(send_wr->wr. | 955 | mad_send_wr->timeout = msecs_to_jiffies(send_wr->wr. |
956 | ud.timeout_ms); | 956 | ud.timeout_ms); |
957 | mad_send_wr->retry = 0; | 957 | mad_send_wr->retries = mad_send_wr->send_wr.wr.ud.retries; |
958 | /* One reference for each work request to QP + response */ | 958 | /* One reference for each work request to QP + response */ |
959 | mad_send_wr->refcount = 1 + (mad_send_wr->timeout > 0); | 959 | mad_send_wr->refcount = 1 + (mad_send_wr->timeout > 0); |
960 | mad_send_wr->status = IB_WC_SUCCESS; | 960 | mad_send_wr->status = IB_WC_SUCCESS; |
@@ -2174,6 +2174,27 @@ local_send_completion: | |||
2174 | spin_unlock_irqrestore(&mad_agent_priv->lock, flags); | 2174 | spin_unlock_irqrestore(&mad_agent_priv->lock, flags); |
2175 | } | 2175 | } |
2176 | 2176 | ||
2177 | static int retry_send(struct ib_mad_send_wr_private *mad_send_wr) | ||
2178 | { | ||
2179 | int ret; | ||
2180 | |||
2181 | if (!mad_send_wr->retries--) | ||
2182 | return -ETIMEDOUT; | ||
2183 | |||
2184 | mad_send_wr->timeout = msecs_to_jiffies(mad_send_wr->send_wr. | ||
2185 | wr.ud.timeout_ms); | ||
2186 | |||
2187 | ret = ib_send_mad(mad_send_wr); | ||
2188 | |||
2189 | if (!ret) { | ||
2190 | mad_send_wr->refcount++; | ||
2191 | list_del(&mad_send_wr->agent_list); | ||
2192 | list_add_tail(&mad_send_wr->agent_list, | ||
2193 | &mad_send_wr->mad_agent_priv->send_list); | ||
2194 | } | ||
2195 | return ret; | ||
2196 | } | ||
2197 | |||
2177 | static void timeout_sends(void *data) | 2198 | static void timeout_sends(void *data) |
2178 | { | 2199 | { |
2179 | struct ib_mad_agent_private *mad_agent_priv; | 2200 | struct ib_mad_agent_private *mad_agent_priv; |
@@ -2202,6 +2223,9 @@ static void timeout_sends(void *data) | |||
2202 | break; | 2223 | break; |
2203 | } | 2224 | } |
2204 | 2225 | ||
2226 | if (!retry_send(mad_send_wr)) | ||
2227 | continue; | ||
2228 | |||
2205 | list_del(&mad_send_wr->agent_list); | 2229 | list_del(&mad_send_wr->agent_list); |
2206 | spin_unlock_irqrestore(&mad_agent_priv->lock, flags); | 2230 | spin_unlock_irqrestore(&mad_agent_priv->lock, flags); |
2207 | 2231 | ||
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 { | |||
123 | u64 wr_id; /* client WR ID */ | 123 | u64 wr_id; /* client WR ID */ |
124 | u64 tid; | 124 | u64 tid; |
125 | unsigned long timeout; | 125 | unsigned long timeout; |
126 | int retries; | ||
126 | int retry; | 127 | int retry; |
127 | int refcount; | 128 | int refcount; |
128 | enum ib_wc_status status; | 129 | enum ib_wc_status status; |
@@ -136,6 +137,7 @@ struct ib_mad_local_private { | |||
136 | struct ib_sge sg_list[IB_MAD_SEND_REQ_MAX_SG]; | 137 | struct ib_sge sg_list[IB_MAD_SEND_REQ_MAX_SG]; |
137 | u64 wr_id; /* client WR ID */ | 138 | u64 wr_id; /* client WR ID */ |
138 | u64 tid; | 139 | u64 tid; |
140 | int retries; | ||
139 | }; | 141 | }; |
140 | 142 | ||
141 | struct ib_mad_mgmt_method_table { | 143 | 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) | |||
462 | .mad_hdr = &query->mad->mad_hdr, | 462 | .mad_hdr = &query->mad->mad_hdr, |
463 | .remote_qpn = 1, | 463 | .remote_qpn = 1, |
464 | .remote_qkey = IB_QP1_QKEY, | 464 | .remote_qkey = IB_QP1_QKEY, |
465 | .timeout_ms = timeout_ms | 465 | .timeout_ms = timeout_ms, |
466 | .retries = 0 | ||
466 | } | 467 | } |
467 | } | 468 | } |
468 | }; | 469 | }; |
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, | |||
322 | wr.wr.ud.remote_qpn = be32_to_cpu(packet->mad.qpn); | 322 | wr.wr.ud.remote_qpn = be32_to_cpu(packet->mad.qpn); |
323 | wr.wr.ud.remote_qkey = be32_to_cpu(packet->mad.qkey); | 323 | wr.wr.ud.remote_qkey = be32_to_cpu(packet->mad.qkey); |
324 | wr.wr.ud.timeout_ms = packet->mad.timeout_ms; | 324 | wr.wr.ud.timeout_ms = packet->mad.timeout_ms; |
325 | wr.wr.ud.retries = 0; | ||
325 | 326 | ||
326 | wr.wr_id = (unsigned long) packet; | 327 | wr.wr_id = (unsigned long) packet; |
327 | 328 | ||
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 { | |||
566 | u32 remote_qpn; | 566 | u32 remote_qpn; |
567 | u32 remote_qkey; | 567 | u32 remote_qkey; |
568 | int timeout_ms; /* valid for MADs only */ | 568 | int timeout_ms; /* valid for MADs only */ |
569 | int retries; /* valid for MADs only */ | ||
569 | u16 pkey_index; /* valid for GSI only */ | 570 | u16 pkey_index; /* valid for GSI only */ |
570 | u8 port_num; /* valid for DR SMPs on switch only */ | 571 | u8 port_num; /* valid for DR SMPs on switch only */ |
571 | } ud; | 572 | } ud; |