aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband
diff options
context:
space:
mode:
authorOr Gerlitz <ogerlitz@voltaire.com>2010-02-08 08:17:11 -0500
committerRoland Dreier <rolandd@cisco.com>2010-02-24 12:41:09 -0500
commit1cef4659850eeb862c248c7670e404d7a1711ed1 (patch)
tree3fa1699654b4aceab045bcf2d8acd5d2ecaf4c41 /drivers/infiniband
parent676ad585531e965416fd958747894541dabcec96 (diff)
IB/iser: Revert commit bba7ebb "avoid recv buffer exhaustion"
We will make a major change in the recv buffer posting logic, after which the problem commit bba7ebb "avoid recv buffer exhaustion caused by unexpected PDUs" comes to solve doesn't exist any more, so revert it. Signed-off-by: Or Gerlitz <ogerlitz@voltaire.com> Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r--drivers/infiniband/ulp/iser/iscsi_iser.h3
-rw-r--r--drivers/infiniband/ulp/iser/iser_initiator.c132
-rw-r--r--drivers/infiniband/ulp/iser/iser_verbs.c1
3 files changed, 41 insertions, 95 deletions
diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.h b/drivers/infiniband/ulp/iser/iscsi_iser.h
index 9d529cae1f0d..e8dfdcfa1daf 100644
--- a/drivers/infiniband/ulp/iser/iscsi_iser.h
+++ b/drivers/infiniband/ulp/iser/iscsi_iser.h
@@ -252,9 +252,6 @@ struct iser_conn {
252 wait_queue_head_t wait; /* waitq for conn/disconn */ 252 wait_queue_head_t wait; /* waitq for conn/disconn */
253 atomic_t post_recv_buf_count; /* posted rx count */ 253 atomic_t post_recv_buf_count; /* posted rx count */
254 atomic_t post_send_buf_count; /* posted tx count */ 254 atomic_t post_send_buf_count; /* posted tx count */
255 atomic_t unexpected_pdu_count;/* count of received *
256 * unexpected pdus *
257 * not yet retired */
258 char name[ISER_OBJECT_NAME_SIZE]; 255 char name[ISER_OBJECT_NAME_SIZE];
259 struct iser_page_vec *page_vec; /* represents SG to fmr maps* 256 struct iser_page_vec *page_vec; /* represents SG to fmr maps*
260 * maps serialized as tx is*/ 257 * maps serialized as tx is*/
diff --git a/drivers/infiniband/ulp/iser/iser_initiator.c b/drivers/infiniband/ulp/iser/iser_initiator.c
index 9de640200ad3..5f42fbe3080c 100644
--- a/drivers/infiniband/ulp/iser/iser_initiator.c
+++ b/drivers/infiniband/ulp/iser/iser_initiator.c
@@ -183,8 +183,14 @@ static int iser_post_receive_control(struct iscsi_conn *conn)
183 struct iser_regd_buf *regd_data; 183 struct iser_regd_buf *regd_data;
184 struct iser_dto *recv_dto = NULL; 184 struct iser_dto *recv_dto = NULL;
185 struct iser_device *device = iser_conn->ib_conn->device; 185 struct iser_device *device = iser_conn->ib_conn->device;
186 int rx_data_size, err; 186 int rx_data_size, err = 0;
187 int posts, outstanding_unexp_pdus; 187
188 rx_desc = kmem_cache_alloc(ig.desc_cache, GFP_NOIO);
189 if (rx_desc == NULL) {
190 iser_err("Failed to alloc desc for post recv\n");
191 return -ENOMEM;
192 }
193 rx_desc->type = ISCSI_RX;
188 194
189 /* for the login sequence we must support rx of upto 8K; login is done 195 /* for the login sequence we must support rx of upto 8K; login is done
190 * after conn create/bind (connect) and conn stop/bind (reconnect), 196 * after conn create/bind (connect) and conn stop/bind (reconnect),
@@ -195,80 +201,46 @@ static int iser_post_receive_control(struct iscsi_conn *conn)
195 else /* FIXME till user space sets conn->max_recv_dlength correctly */ 201 else /* FIXME till user space sets conn->max_recv_dlength correctly */
196 rx_data_size = 128; 202 rx_data_size = 128;
197 203
198 outstanding_unexp_pdus = 204 rx_desc->data = kmalloc(rx_data_size, GFP_NOIO);
199 atomic_xchg(&iser_conn->ib_conn->unexpected_pdu_count, 0); 205 if (rx_desc->data == NULL) {
200 206 iser_err("Failed to alloc data buf for post recv\n");
201 /* 207 err = -ENOMEM;
202 * in addition to the response buffer, replace those consumed by 208 goto post_rx_kmalloc_failure;
203 * unexpected pdus. 209 }
204 */
205 for (posts = 0; posts < 1 + outstanding_unexp_pdus; posts++) {
206 rx_desc = kmem_cache_alloc(ig.desc_cache, GFP_NOIO);
207 if (rx_desc == NULL) {
208 iser_err("Failed to alloc desc for post recv %d\n",
209 posts);
210 err = -ENOMEM;
211 goto post_rx_cache_alloc_failure;
212 }
213 rx_desc->type = ISCSI_RX;
214 rx_desc->data = kmalloc(rx_data_size, GFP_NOIO);
215 if (rx_desc->data == NULL) {
216 iser_err("Failed to alloc data buf for post recv %d\n",
217 posts);
218 err = -ENOMEM;
219 goto post_rx_kmalloc_failure;
220 }
221 210
222 recv_dto = &rx_desc->dto; 211 recv_dto = &rx_desc->dto;
223 recv_dto->ib_conn = iser_conn->ib_conn; 212 recv_dto->ib_conn = iser_conn->ib_conn;
224 recv_dto->regd_vector_len = 0; 213 recv_dto->regd_vector_len = 0;
225 214
226 regd_hdr = &rx_desc->hdr_regd_buf; 215 regd_hdr = &rx_desc->hdr_regd_buf;
227 memset(regd_hdr, 0, sizeof(struct iser_regd_buf)); 216 memset(regd_hdr, 0, sizeof(struct iser_regd_buf));
228 regd_hdr->device = device; 217 regd_hdr->device = device;
229 regd_hdr->virt_addr = rx_desc; /* == &rx_desc->iser_header */ 218 regd_hdr->virt_addr = rx_desc; /* == &rx_desc->iser_header */
230 regd_hdr->data_size = ISER_TOTAL_HEADERS_LEN; 219 regd_hdr->data_size = ISER_TOTAL_HEADERS_LEN;
231 220
232 iser_reg_single(device, regd_hdr, DMA_FROM_DEVICE); 221 iser_reg_single(device, regd_hdr, DMA_FROM_DEVICE);
233 222
234 iser_dto_add_regd_buff(recv_dto, regd_hdr, 0, 0); 223 iser_dto_add_regd_buff(recv_dto, regd_hdr, 0, 0);
235 224
236 regd_data = &rx_desc->data_regd_buf; 225 regd_data = &rx_desc->data_regd_buf;
237 memset(regd_data, 0, sizeof(struct iser_regd_buf)); 226 memset(regd_data, 0, sizeof(struct iser_regd_buf));
238 regd_data->device = device; 227 regd_data->device = device;
239 regd_data->virt_addr = rx_desc->data; 228 regd_data->virt_addr = rx_desc->data;
240 regd_data->data_size = rx_data_size; 229 regd_data->data_size = rx_data_size;
241 230
242 iser_reg_single(device, regd_data, DMA_FROM_DEVICE); 231 iser_reg_single(device, regd_data, DMA_FROM_DEVICE);
243 232
244 iser_dto_add_regd_buff(recv_dto, regd_data, 0, 0); 233 iser_dto_add_regd_buff(recv_dto, regd_data, 0, 0);
245 234
246 err = iser_post_recv(rx_desc); 235 err = iser_post_recv(rx_desc);
247 if (err) { 236 if (!err)
248 iser_err("Failed iser_post_recv for post %d\n", posts); 237 return 0;
249 goto post_rx_post_recv_failure;
250 }
251 }
252 /* all posts successful */
253 return 0;
254 238
255post_rx_post_recv_failure: 239 /* iser_post_recv failed */
256 iser_dto_buffs_release(recv_dto); 240 iser_dto_buffs_release(recv_dto);
257 kfree(rx_desc->data); 241 kfree(rx_desc->data);
258post_rx_kmalloc_failure: 242post_rx_kmalloc_failure:
259 kmem_cache_free(ig.desc_cache, rx_desc); 243 kmem_cache_free(ig.desc_cache, rx_desc);
260post_rx_cache_alloc_failure:
261 if (posts > 0) {
262 /*
263 * response buffer posted, but did not replace all unexpected
264 * pdu recv bufs. Ignore error, retry occurs next send
265 */
266 outstanding_unexp_pdus -= (posts - 1);
267 err = 0;
268 }
269 atomic_add(outstanding_unexp_pdus,
270 &iser_conn->ib_conn->unexpected_pdu_count);
271
272 return err; 244 return err;
273} 245}
274 246
@@ -302,10 +274,8 @@ int iser_conn_set_full_featured_mode(struct iscsi_conn *conn)
302 struct iscsi_iser_conn *iser_conn = conn->dd_data; 274 struct iscsi_iser_conn *iser_conn = conn->dd_data;
303 275
304 int i; 276 int i;
305 /* 277 /* no need to keep it in a var, we are after login so if this should
306 * FIXME this value should be declared to the target during login with 278 * be negotiated, by now the result should be available here */
307 * the MaxOutstandingUnexpectedPDUs key when supported
308 */
309 int initial_post_recv_bufs_num = ISER_MAX_RX_MISC_PDUS; 279 int initial_post_recv_bufs_num = ISER_MAX_RX_MISC_PDUS;
310 280
311 iser_dbg("Initially post: %d\n", initial_post_recv_bufs_num); 281 iser_dbg("Initially post: %d\n", initial_post_recv_bufs_num);
@@ -507,7 +477,6 @@ int iser_send_control(struct iscsi_conn *conn,
507 int err = 0; 477 int err = 0;
508 struct iser_regd_buf *regd_buf; 478 struct iser_regd_buf *regd_buf;
509 struct iser_device *device; 479 struct iser_device *device;
510 unsigned char opcode;
511 480
512 if (!iser_conn_state_comp(iser_conn->ib_conn, ISER_CONN_UP)) { 481 if (!iser_conn_state_comp(iser_conn->ib_conn, ISER_CONN_UP)) {
513 iser_err("Failed to send, conn: 0x%p is not up\n", iser_conn->ib_conn); 482 iser_err("Failed to send, conn: 0x%p is not up\n", iser_conn->ib_conn);
@@ -542,15 +511,10 @@ int iser_send_control(struct iscsi_conn *conn,
542 data_seg_len); 511 data_seg_len);
543 } 512 }
544 513
545 opcode = task->hdr->opcode & ISCSI_OPCODE_MASK; 514 if (iser_post_receive_control(conn) != 0) {
546 515 iser_err("post_rcv_buff failed!\n");
547 /* post recv buffer for response if one is expected */ 516 err = -ENOMEM;
548 if (!(opcode == ISCSI_OP_NOOP_OUT && task->hdr->itt == RESERVED_ITT)) { 517 goto send_control_error;
549 if (iser_post_receive_control(conn) != 0) {
550 iser_err("post_rcv_buff failed!\n");
551 err = -ENOMEM;
552 goto send_control_error;
553 }
554 } 518 }
555 519
556 err = iser_post_send(mdesc); 520 err = iser_post_send(mdesc);
@@ -621,20 +585,6 @@ void iser_rcv_completion(struct iser_desc *rx_desc,
621 * parallel to the execution of iser_conn_term. So the code that waits * 585 * parallel to the execution of iser_conn_term. So the code that waits *
622 * for the posted rx bufs refcount to become zero handles everything */ 586 * for the posted rx bufs refcount to become zero handles everything */
623 atomic_dec(&conn->ib_conn->post_recv_buf_count); 587 atomic_dec(&conn->ib_conn->post_recv_buf_count);
624
625 /*
626 * if an unexpected PDU was received then the recv wr consumed must
627 * be replaced, this is done in the next send of a control-type PDU
628 */
629 if (opcode == ISCSI_OP_NOOP_IN && hdr->itt == RESERVED_ITT) {
630 /* nop-in with itt = 0xffffffff */
631 atomic_inc(&conn->ib_conn->unexpected_pdu_count);
632 }
633 else if (opcode == ISCSI_OP_ASYNC_EVENT) {
634 /* asyncronous message */
635 atomic_inc(&conn->ib_conn->unexpected_pdu_count);
636 }
637 /* a reject PDU consumes the recv buf posted for the response */
638} 588}
639 589
640void iser_snd_completion(struct iser_desc *tx_desc) 590void iser_snd_completion(struct iser_desc *tx_desc)
diff --git a/drivers/infiniband/ulp/iser/iser_verbs.c b/drivers/infiniband/ulp/iser/iser_verbs.c
index 8579f32ce38e..7092503a10e3 100644
--- a/drivers/infiniband/ulp/iser/iser_verbs.c
+++ b/drivers/infiniband/ulp/iser/iser_verbs.c
@@ -491,7 +491,6 @@ void iser_conn_init(struct iser_conn *ib_conn)
491 init_waitqueue_head(&ib_conn->wait); 491 init_waitqueue_head(&ib_conn->wait);
492 atomic_set(&ib_conn->post_recv_buf_count, 0); 492 atomic_set(&ib_conn->post_recv_buf_count, 0);
493 atomic_set(&ib_conn->post_send_buf_count, 0); 493 atomic_set(&ib_conn->post_send_buf_count, 0);
494 atomic_set(&ib_conn->unexpected_pdu_count, 0);
495 atomic_set(&ib_conn->refcount, 1); 494 atomic_set(&ib_conn->refcount, 1);
496 INIT_LIST_HEAD(&ib_conn->conn_list); 495 INIT_LIST_HEAD(&ib_conn->conn_list);
497 spin_lock_init(&ib_conn->lock); 496 spin_lock_init(&ib_conn->lock);