aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorOr Gerlitz <ogerlitz@mellanox.com>2011-11-03 18:19:46 -0400
committerRoland Dreier <roland@purestorage.com>2011-11-04 12:30:52 -0400
commit2c4ce609347f2a45792c8d9ebb5af11217766cb6 (patch)
treea78125a35d5a277d395003651b4241eafc7dd52d /drivers
parentf470f8d4e702593ee1d0852871ad80373bce707b (diff)
IB/iser: Use separate buffers for the login request/response
The driver counted on the transactional nature of iSCSI login/text flows and used the same buffer for both the request and the response. We also went further and did DMA mapping only once, with DMA_FROM_DEVICE, which violates the DMA mapping API. Fix that by using different buffers, one for requests and one for responses, and use the correct DMA mapping direction for each. Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com> Signed-off-by: Roland Dreier <roland@purestorage.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/infiniband/ulp/iser/iscsi_iser.h3
-rw-r--r--drivers/infiniband/ulp/iser/iser_initiator.c31
-rw-r--r--drivers/infiniband/ulp/iser/iser_verbs.c33
3 files changed, 52 insertions, 15 deletions
diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.h b/drivers/infiniband/ulp/iser/iscsi_iser.h
index db6f3ce9f3b..2982a14a055 100644
--- a/drivers/infiniband/ulp/iser/iscsi_iser.h
+++ b/drivers/infiniband/ulp/iser/iscsi_iser.h
@@ -257,7 +257,8 @@ struct iser_conn {
257 struct list_head conn_list; /* entry in ig conn list */ 257 struct list_head conn_list; /* entry in ig conn list */
258 258
259 char *login_buf; 259 char *login_buf;
260 u64 login_dma; 260 char *login_req_buf, *login_resp_buf;
261 u64 login_req_dma, login_resp_dma;
261 unsigned int rx_desc_head; 262 unsigned int rx_desc_head;
262 struct iser_rx_desc *rx_descs; 263 struct iser_rx_desc *rx_descs;
263 struct ib_recv_wr rx_wr[ISER_MIN_POSTED_RX]; 264 struct ib_recv_wr rx_wr[ISER_MIN_POSTED_RX];
diff --git a/drivers/infiniband/ulp/iser/iser_initiator.c b/drivers/infiniband/ulp/iser/iser_initiator.c
index f299de6b419..a607542fc79 100644
--- a/drivers/infiniband/ulp/iser/iser_initiator.c
+++ b/drivers/infiniband/ulp/iser/iser_initiator.c
@@ -221,8 +221,14 @@ void iser_free_rx_descriptors(struct iser_conn *ib_conn)
221 struct iser_device *device = ib_conn->device; 221 struct iser_device *device = ib_conn->device;
222 222
223 if (ib_conn->login_buf) { 223 if (ib_conn->login_buf) {
224 ib_dma_unmap_single(device->ib_device, ib_conn->login_dma, 224 if (ib_conn->login_req_dma)
225 ISER_RX_LOGIN_SIZE, DMA_FROM_DEVICE); 225 ib_dma_unmap_single(device->ib_device,
226 ib_conn->login_req_dma,
227 ISCSI_DEF_MAX_RECV_SEG_LEN, DMA_TO_DEVICE);
228 if (ib_conn->login_resp_dma)
229 ib_dma_unmap_single(device->ib_device,
230 ib_conn->login_resp_dma,
231 ISER_RX_LOGIN_SIZE, DMA_FROM_DEVICE);
226 kfree(ib_conn->login_buf); 232 kfree(ib_conn->login_buf);
227 } 233 }
228 234
@@ -394,6 +400,7 @@ int iser_send_control(struct iscsi_conn *conn,
394 unsigned long data_seg_len; 400 unsigned long data_seg_len;
395 int err = 0; 401 int err = 0;
396 struct iser_device *device; 402 struct iser_device *device;
403 struct iser_conn *ib_conn = iser_conn->ib_conn;
397 404
398 /* build the tx desc regd header and add it to the tx desc dto */ 405 /* build the tx desc regd header and add it to the tx desc dto */
399 mdesc->type = ISCSI_TX_CONTROL; 406 mdesc->type = ISCSI_TX_CONTROL;
@@ -409,9 +416,19 @@ int iser_send_control(struct iscsi_conn *conn,
409 iser_err("data present on non login task!!!\n"); 416 iser_err("data present on non login task!!!\n");
410 goto send_control_error; 417 goto send_control_error;
411 } 418 }
412 memcpy(iser_conn->ib_conn->login_buf, task->data, 419
420 ib_dma_sync_single_for_cpu(device->ib_device,
421 ib_conn->login_req_dma, task->data_count,
422 DMA_TO_DEVICE);
423
424 memcpy(iser_conn->ib_conn->login_req_buf, task->data,
413 task->data_count); 425 task->data_count);
414 tx_dsg->addr = iser_conn->ib_conn->login_dma; 426
427 ib_dma_sync_single_for_device(device->ib_device,
428 ib_conn->login_req_dma, task->data_count,
429 DMA_TO_DEVICE);
430
431 tx_dsg->addr = iser_conn->ib_conn->login_req_dma;
415 tx_dsg->length = task->data_count; 432 tx_dsg->length = task->data_count;
416 tx_dsg->lkey = device->mr->lkey; 433 tx_dsg->lkey = device->mr->lkey;
417 mdesc->num_sge = 2; 434 mdesc->num_sge = 2;
@@ -445,8 +462,8 @@ void iser_rcv_completion(struct iser_rx_desc *rx_desc,
445 int rx_buflen, outstanding, count, err; 462 int rx_buflen, outstanding, count, err;
446 463
447 /* differentiate between login to all other PDUs */ 464 /* differentiate between login to all other PDUs */
448 if ((char *)rx_desc == ib_conn->login_buf) { 465 if ((char *)rx_desc == ib_conn->login_resp_buf) {
449 rx_dma = ib_conn->login_dma; 466 rx_dma = ib_conn->login_resp_dma;
450 rx_buflen = ISER_RX_LOGIN_SIZE; 467 rx_buflen = ISER_RX_LOGIN_SIZE;
451 } else { 468 } else {
452 rx_dma = rx_desc->dma_addr; 469 rx_dma = rx_desc->dma_addr;
@@ -473,7 +490,7 @@ void iser_rcv_completion(struct iser_rx_desc *rx_desc,
473 * for the posted rx bufs refcount to become zero handles everything */ 490 * for the posted rx bufs refcount to become zero handles everything */
474 conn->ib_conn->post_recv_buf_count--; 491 conn->ib_conn->post_recv_buf_count--;
475 492
476 if (rx_dma == ib_conn->login_dma) 493 if (rx_dma == ib_conn->login_resp_dma)
477 return; 494 return;
478 495
479 outstanding = ib_conn->post_recv_buf_count; 496 outstanding = ib_conn->post_recv_buf_count;
diff --git a/drivers/infiniband/ulp/iser/iser_verbs.c b/drivers/infiniband/ulp/iser/iser_verbs.c
index ede1475bee0..e28877c4ce1 100644
--- a/drivers/infiniband/ulp/iser/iser_verbs.c
+++ b/drivers/infiniband/ulp/iser/iser_verbs.c
@@ -155,20 +155,39 @@ static int iser_create_ib_conn_res(struct iser_conn *ib_conn)
155{ 155{
156 struct iser_device *device; 156 struct iser_device *device;
157 struct ib_qp_init_attr init_attr; 157 struct ib_qp_init_attr init_attr;
158 int ret = -ENOMEM; 158 int req_err, resp_err, ret = -ENOMEM;
159 struct ib_fmr_pool_param params; 159 struct ib_fmr_pool_param params;
160 160
161 BUG_ON(ib_conn->device == NULL); 161 BUG_ON(ib_conn->device == NULL);
162 162
163 device = ib_conn->device; 163 device = ib_conn->device;
164 164
165 ib_conn->login_buf = kmalloc(ISER_RX_LOGIN_SIZE, GFP_KERNEL); 165 ib_conn->login_buf = kmalloc(ISCSI_DEF_MAX_RECV_SEG_LEN +
166 ISER_RX_LOGIN_SIZE, GFP_KERNEL);
166 if (!ib_conn->login_buf) 167 if (!ib_conn->login_buf)
167 goto out_err; 168 goto out_err;
168 169
169 ib_conn->login_dma = ib_dma_map_single(ib_conn->device->ib_device, 170 ib_conn->login_req_buf = ib_conn->login_buf;
170 (void *)ib_conn->login_buf, ISER_RX_LOGIN_SIZE, 171 ib_conn->login_resp_buf = ib_conn->login_buf + ISCSI_DEF_MAX_RECV_SEG_LEN;
171 DMA_FROM_DEVICE); 172
173 ib_conn->login_req_dma = ib_dma_map_single(ib_conn->device->ib_device,
174 (void *)ib_conn->login_req_buf,
175 ISCSI_DEF_MAX_RECV_SEG_LEN, DMA_TO_DEVICE);
176
177 ib_conn->login_resp_dma = ib_dma_map_single(ib_conn->device->ib_device,
178 (void *)ib_conn->login_resp_buf,
179 ISER_RX_LOGIN_SIZE, DMA_FROM_DEVICE);
180
181 req_err = ib_dma_mapping_error(device->ib_device, ib_conn->login_req_dma);
182 resp_err = ib_dma_mapping_error(device->ib_device, ib_conn->login_resp_dma);
183
184 if (req_err || resp_err) {
185 if (req_err)
186 ib_conn->login_req_dma = 0;
187 if (resp_err)
188 ib_conn->login_resp_dma = 0;
189 goto out_err;
190 }
172 191
173 ib_conn->page_vec = kmalloc(sizeof(struct iser_page_vec) + 192 ib_conn->page_vec = kmalloc(sizeof(struct iser_page_vec) +
174 (sizeof(u64) * (ISCSI_ISER_SG_TABLESIZE +1)), 193 (sizeof(u64) * (ISCSI_ISER_SG_TABLESIZE +1)),
@@ -658,11 +677,11 @@ int iser_post_recvl(struct iser_conn *ib_conn)
658 struct ib_sge sge; 677 struct ib_sge sge;
659 int ib_ret; 678 int ib_ret;
660 679
661 sge.addr = ib_conn->login_dma; 680 sge.addr = ib_conn->login_resp_dma;
662 sge.length = ISER_RX_LOGIN_SIZE; 681 sge.length = ISER_RX_LOGIN_SIZE;
663 sge.lkey = ib_conn->device->mr->lkey; 682 sge.lkey = ib_conn->device->mr->lkey;
664 683
665 rx_wr.wr_id = (unsigned long)ib_conn->login_buf; 684 rx_wr.wr_id = (unsigned long)ib_conn->login_resp_buf;
666 rx_wr.sg_list = &sge; 685 rx_wr.sg_list = &sge;
667 rx_wr.num_sge = 1; 686 rx_wr.num_sge = 1;
668 rx_wr.next = NULL; 687 rx_wr.next = NULL;