diff options
Diffstat (limited to 'drivers/infiniband')
-rw-r--r-- | drivers/infiniband/ulp/iser/iscsi_iser.h | 3 | ||||
-rw-r--r-- | drivers/infiniband/ulp/iser/iser_initiator.c | 132 | ||||
-rw-r--r-- | drivers/infiniband/ulp/iser/iser_verbs.c | 1 |
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 | ||
255 | post_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); |
258 | post_rx_kmalloc_failure: | 242 | post_rx_kmalloc_failure: |
259 | kmem_cache_free(ig.desc_cache, rx_desc); | 243 | kmem_cache_free(ig.desc_cache, rx_desc); |
260 | post_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 | ||
640 | void iser_snd_completion(struct iser_desc *tx_desc) | 590 | void 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); |