aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband
diff options
context:
space:
mode:
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);