aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/ulp/iser
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
commit8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch)
treea8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /drivers/infiniband/ulp/iser
parent406089d01562f1e2bf9f089fd7637009ebaad589 (diff)
Patched in Tegra support.
Diffstat (limited to 'drivers/infiniband/ulp/iser')
-rw-r--r--drivers/infiniband/ulp/iser/iscsi_iser.c115
-rw-r--r--drivers/infiniband/ulp/iser/iscsi_iser.h22
-rw-r--r--drivers/infiniband/ulp/iser/iser_initiator.c57
-rw-r--r--drivers/infiniband/ulp/iser/iser_memory.c8
-rw-r--r--drivers/infiniband/ulp/iser/iser_verbs.c178
5 files changed, 128 insertions, 252 deletions
diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c
index 0ab8c9cc3a7..9c61b9c2c59 100644
--- a/drivers/infiniband/ulp/iser/iscsi_iser.c
+++ b/drivers/infiniband/ulp/iser/iscsi_iser.c
@@ -57,7 +57,6 @@
57#include <linux/scatterlist.h> 57#include <linux/scatterlist.h>
58#include <linux/delay.h> 58#include <linux/delay.h>
59#include <linux/slab.h> 59#include <linux/slab.h>
60#include <linux/module.h>
61 60
62#include <net/sock.h> 61#include <net/sock.h>
63 62
@@ -152,6 +151,7 @@ int iser_initialize_task_headers(struct iscsi_task *task,
152 tx_desc->tx_sg[0].length = ISER_HEADERS_LEN; 151 tx_desc->tx_sg[0].length = ISER_HEADERS_LEN;
153 tx_desc->tx_sg[0].lkey = device->mr->lkey; 152 tx_desc->tx_sg[0].lkey = device->mr->lkey;
154 153
154 iser_task->headers_initialized = 1;
155 iser_task->iser_conn = iser_conn; 155 iser_task->iser_conn = iser_conn;
156 return 0; 156 return 0;
157} 157}
@@ -166,7 +166,8 @@ iscsi_iser_task_init(struct iscsi_task *task)
166{ 166{
167 struct iscsi_iser_task *iser_task = task->dd_data; 167 struct iscsi_iser_task *iser_task = task->dd_data;
168 168
169 if (iser_initialize_task_headers(task, &iser_task->desc)) 169 if (!iser_task->headers_initialized)
170 if (iser_initialize_task_headers(task, &iser_task->desc))
170 return -ENOMEM; 171 return -ENOMEM;
171 172
172 /* mgmt task */ 173 /* mgmt task */
@@ -277,13 +278,6 @@ iscsi_iser_task_xmit(struct iscsi_task *task)
277static void iscsi_iser_cleanup_task(struct iscsi_task *task) 278static void iscsi_iser_cleanup_task(struct iscsi_task *task)
278{ 279{
279 struct iscsi_iser_task *iser_task = task->dd_data; 280 struct iscsi_iser_task *iser_task = task->dd_data;
280 struct iser_tx_desc *tx_desc = &iser_task->desc;
281
282 struct iscsi_iser_conn *iser_conn = task->conn->dd_data;
283 struct iser_device *device = iser_conn->ib_conn->device;
284
285 ib_dma_unmap_single(device->ib_device,
286 tx_desc->dma_addr, ISER_HEADERS_LEN, DMA_TO_DEVICE);
287 281
288 /* mgmt tasks do not need special cleanup */ 282 /* mgmt tasks do not need special cleanup */
289 if (!task->sc) 283 if (!task->sc)
@@ -364,9 +358,6 @@ iscsi_iser_conn_bind(struct iscsi_cls_session *cls_session,
364 } 358 }
365 ib_conn = ep->dd_data; 359 ib_conn = ep->dd_data;
366 360
367 if (iser_alloc_rx_descriptors(ib_conn))
368 return -ENOMEM;
369
370 /* binds the iSER connection retrieved from the previously 361 /* binds the iSER connection retrieved from the previously
371 * connected ep_handle to the iSCSI layer connection. exchanges 362 * connected ep_handle to the iSCSI layer connection. exchanges
372 * connection pointers */ 363 * connection pointers */
@@ -401,6 +392,19 @@ iscsi_iser_conn_stop(struct iscsi_cls_conn *cls_conn, int flag)
401 iser_conn->ib_conn = NULL; 392 iser_conn->ib_conn = NULL;
402} 393}
403 394
395static int
396iscsi_iser_conn_start(struct iscsi_cls_conn *cls_conn)
397{
398 struct iscsi_conn *conn = cls_conn->dd_data;
399 int err;
400
401 err = iser_conn_set_full_featured_mode(conn);
402 if (err)
403 return err;
404
405 return iscsi_conn_start(cls_conn);
406}
407
404static void iscsi_iser_session_destroy(struct iscsi_cls_session *cls_session) 408static void iscsi_iser_session_destroy(struct iscsi_cls_session *cls_session)
405{ 409{
406 struct Scsi_Host *shost = iscsi_session_to_shost(cls_session); 410 struct Scsi_Host *shost = iscsi_session_to_shost(cls_session);
@@ -573,9 +577,10 @@ iscsi_iser_ep_connect(struct Scsi_Host *shost, struct sockaddr *dst_addr,
573 577
574 err = iser_connect(ib_conn, NULL, (struct sockaddr_in *)dst_addr, 578 err = iser_connect(ib_conn, NULL, (struct sockaddr_in *)dst_addr,
575 non_blocking); 579 non_blocking);
576 if (err) 580 if (err) {
581 iscsi_destroy_endpoint(ep);
577 return ERR_PTR(err); 582 return ERR_PTR(err);
578 583 }
579 return ep; 584 return ep;
580} 585}
581 586
@@ -627,59 +632,6 @@ iscsi_iser_ep_disconnect(struct iscsi_endpoint *ep)
627 iser_conn_terminate(ib_conn); 632 iser_conn_terminate(ib_conn);
628} 633}
629 634
630static umode_t iser_attr_is_visible(int param_type, int param)
631{
632 switch (param_type) {
633 case ISCSI_HOST_PARAM:
634 switch (param) {
635 case ISCSI_HOST_PARAM_NETDEV_NAME:
636 case ISCSI_HOST_PARAM_HWADDRESS:
637 case ISCSI_HOST_PARAM_INITIATOR_NAME:
638 return S_IRUGO;
639 default:
640 return 0;
641 }
642 case ISCSI_PARAM:
643 switch (param) {
644 case ISCSI_PARAM_MAX_RECV_DLENGTH:
645 case ISCSI_PARAM_MAX_XMIT_DLENGTH:
646 case ISCSI_PARAM_HDRDGST_EN:
647 case ISCSI_PARAM_DATADGST_EN:
648 case ISCSI_PARAM_CONN_ADDRESS:
649 case ISCSI_PARAM_CONN_PORT:
650 case ISCSI_PARAM_EXP_STATSN:
651 case ISCSI_PARAM_PERSISTENT_ADDRESS:
652 case ISCSI_PARAM_PERSISTENT_PORT:
653 case ISCSI_PARAM_PING_TMO:
654 case ISCSI_PARAM_RECV_TMO:
655 case ISCSI_PARAM_INITIAL_R2T_EN:
656 case ISCSI_PARAM_MAX_R2T:
657 case ISCSI_PARAM_IMM_DATA_EN:
658 case ISCSI_PARAM_FIRST_BURST:
659 case ISCSI_PARAM_MAX_BURST:
660 case ISCSI_PARAM_PDU_INORDER_EN:
661 case ISCSI_PARAM_DATASEQ_INORDER_EN:
662 case ISCSI_PARAM_TARGET_NAME:
663 case ISCSI_PARAM_TPGT:
664 case ISCSI_PARAM_USERNAME:
665 case ISCSI_PARAM_PASSWORD:
666 case ISCSI_PARAM_USERNAME_IN:
667 case ISCSI_PARAM_PASSWORD_IN:
668 case ISCSI_PARAM_FAST_ABORT:
669 case ISCSI_PARAM_ABORT_TMO:
670 case ISCSI_PARAM_LU_RESET_TMO:
671 case ISCSI_PARAM_TGT_RESET_TMO:
672 case ISCSI_PARAM_IFACE_NAME:
673 case ISCSI_PARAM_INITIATOR_NAME:
674 return S_IRUGO;
675 default:
676 return 0;
677 }
678 }
679
680 return 0;
681}
682
683static struct scsi_host_template iscsi_iser_sht = { 635static struct scsi_host_template iscsi_iser_sht = {
684 .module = THIS_MODULE, 636 .module = THIS_MODULE,
685 .name = "iSCSI Initiator over iSER, v." DRV_VER, 637 .name = "iSCSI Initiator over iSER, v." DRV_VER,
@@ -701,6 +653,32 @@ static struct iscsi_transport iscsi_iser_transport = {
701 .owner = THIS_MODULE, 653 .owner = THIS_MODULE,
702 .name = "iser", 654 .name = "iser",
703 .caps = CAP_RECOVERY_L0 | CAP_MULTI_R2T, 655 .caps = CAP_RECOVERY_L0 | CAP_MULTI_R2T,
656 .param_mask = ISCSI_MAX_RECV_DLENGTH |
657 ISCSI_MAX_XMIT_DLENGTH |
658 ISCSI_HDRDGST_EN |
659 ISCSI_DATADGST_EN |
660 ISCSI_INITIAL_R2T_EN |
661 ISCSI_MAX_R2T |
662 ISCSI_IMM_DATA_EN |
663 ISCSI_FIRST_BURST |
664 ISCSI_MAX_BURST |
665 ISCSI_PDU_INORDER_EN |
666 ISCSI_DATASEQ_INORDER_EN |
667 ISCSI_CONN_PORT |
668 ISCSI_CONN_ADDRESS |
669 ISCSI_EXP_STATSN |
670 ISCSI_PERSISTENT_PORT |
671 ISCSI_PERSISTENT_ADDRESS |
672 ISCSI_TARGET_NAME | ISCSI_TPGT |
673 ISCSI_USERNAME | ISCSI_PASSWORD |
674 ISCSI_USERNAME_IN | ISCSI_PASSWORD_IN |
675 ISCSI_FAST_ABORT | ISCSI_ABORT_TMO |
676 ISCSI_LU_RESET_TMO | ISCSI_TGT_RESET_TMO |
677 ISCSI_PING_TMO | ISCSI_RECV_TMO |
678 ISCSI_IFACE_NAME | ISCSI_INITIATOR_NAME,
679 .host_param_mask = ISCSI_HOST_HWADDRESS |
680 ISCSI_HOST_NETDEV_NAME |
681 ISCSI_HOST_INITIATOR_NAME,
704 /* session management */ 682 /* session management */
705 .create_session = iscsi_iser_session_create, 683 .create_session = iscsi_iser_session_create,
706 .destroy_session = iscsi_iser_session_destroy, 684 .destroy_session = iscsi_iser_session_destroy,
@@ -708,12 +686,11 @@ static struct iscsi_transport iscsi_iser_transport = {
708 .create_conn = iscsi_iser_conn_create, 686 .create_conn = iscsi_iser_conn_create,
709 .bind_conn = iscsi_iser_conn_bind, 687 .bind_conn = iscsi_iser_conn_bind,
710 .destroy_conn = iscsi_iser_conn_destroy, 688 .destroy_conn = iscsi_iser_conn_destroy,
711 .attr_is_visible = iser_attr_is_visible,
712 .set_param = iscsi_iser_set_param, 689 .set_param = iscsi_iser_set_param,
713 .get_conn_param = iscsi_conn_get_param, 690 .get_conn_param = iscsi_conn_get_param,
714 .get_ep_param = iscsi_iser_get_ep_param, 691 .get_ep_param = iscsi_iser_get_ep_param,
715 .get_session_param = iscsi_session_get_param, 692 .get_session_param = iscsi_session_get_param,
716 .start_conn = iscsi_conn_start, 693 .start_conn = iscsi_iser_conn_start,
717 .stop_conn = iscsi_iser_conn_stop, 694 .stop_conn = iscsi_iser_conn_stop,
718 /* iscsi host params */ 695 /* iscsi host params */
719 .get_host_param = iscsi_host_get_param, 696 .get_host_param = iscsi_host_get_param,
diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.h b/drivers/infiniband/ulp/iser/iscsi_iser.h
index ef7d3be46c3..db6f3ce9f3b 100644
--- a/drivers/infiniband/ulp/iser/iscsi_iser.h
+++ b/drivers/infiniband/ulp/iser/iscsi_iser.h
@@ -177,7 +177,6 @@ struct iser_data_buf {
177 177
178/* fwd declarations */ 178/* fwd declarations */
179struct iser_device; 179struct iser_device;
180struct iser_cq_desc;
181struct iscsi_iser_conn; 180struct iscsi_iser_conn;
182struct iscsi_iser_task; 181struct iscsi_iser_task;
183struct iscsi_endpoint; 182struct iscsi_endpoint;
@@ -227,21 +226,16 @@ struct iser_rx_desc {
227 char pad[ISER_RX_PAD_SIZE]; 226 char pad[ISER_RX_PAD_SIZE];
228} __attribute__((packed)); 227} __attribute__((packed));
229 228
230#define ISER_MAX_CQ 4
231
232struct iser_device { 229struct iser_device {
233 struct ib_device *ib_device; 230 struct ib_device *ib_device;
234 struct ib_pd *pd; 231 struct ib_pd *pd;
235 struct ib_cq *rx_cq[ISER_MAX_CQ]; 232 struct ib_cq *rx_cq;
236 struct ib_cq *tx_cq[ISER_MAX_CQ]; 233 struct ib_cq *tx_cq;
237 struct ib_mr *mr; 234 struct ib_mr *mr;
238 struct tasklet_struct cq_tasklet[ISER_MAX_CQ]; 235 struct tasklet_struct cq_tasklet;
239 struct ib_event_handler event_handler; 236 struct ib_event_handler event_handler;
240 struct list_head ig_list; /* entry in ig devices list */ 237 struct list_head ig_list; /* entry in ig devices list */
241 int refcount; 238 int refcount;
242 int cq_active_qps[ISER_MAX_CQ];
243 int cqs_used;
244 struct iser_cq_desc *cq_desc;
245}; 239};
246 240
247struct iser_conn { 241struct iser_conn {
@@ -263,8 +257,7 @@ struct iser_conn {
263 struct list_head conn_list; /* entry in ig conn list */ 257 struct list_head conn_list; /* entry in ig conn list */
264 258
265 char *login_buf; 259 char *login_buf;
266 char *login_req_buf, *login_resp_buf; 260 u64 login_dma;
267 u64 login_req_dma, login_resp_dma;
268 unsigned int rx_desc_head; 261 unsigned int rx_desc_head;
269 struct iser_rx_desc *rx_descs; 262 struct iser_rx_desc *rx_descs;
270 struct ib_recv_wr rx_wr[ISER_MIN_POSTED_RX]; 263 struct ib_recv_wr rx_wr[ISER_MIN_POSTED_RX];
@@ -284,6 +277,7 @@ struct iscsi_iser_task {
284 struct iser_regd_buf rdma_regd[ISER_DIRS_NUM];/* regd rdma buf */ 277 struct iser_regd_buf rdma_regd[ISER_DIRS_NUM];/* regd rdma buf */
285 struct iser_data_buf data[ISER_DIRS_NUM]; /* orig. data des*/ 278 struct iser_data_buf data[ISER_DIRS_NUM]; /* orig. data des*/
286 struct iser_data_buf data_copy[ISER_DIRS_NUM];/* contig. copy */ 279 struct iser_data_buf data_copy[ISER_DIRS_NUM];/* contig. copy */
280 int headers_initialized;
287}; 281};
288 282
289struct iser_page_vec { 283struct iser_page_vec {
@@ -293,11 +287,6 @@ struct iser_page_vec {
293 int data_size; 287 int data_size;
294}; 288};
295 289
296struct iser_cq_desc {
297 struct iser_device *device;
298 int cq_index;
299};
300
301struct iser_global { 290struct iser_global {
302 struct mutex device_list_mutex;/* */ 291 struct mutex device_list_mutex;/* */
303 struct list_head device_list; /* all iSER devices */ 292 struct list_head device_list; /* all iSER devices */
@@ -377,5 +366,4 @@ int iser_dma_map_task_data(struct iscsi_iser_task *iser_task,
377void iser_dma_unmap_task_data(struct iscsi_iser_task *iser_task); 366void iser_dma_unmap_task_data(struct iscsi_iser_task *iser_task);
378int iser_initialize_task_headers(struct iscsi_task *task, 367int iser_initialize_task_headers(struct iscsi_task *task,
379 struct iser_tx_desc *tx_desc); 368 struct iser_tx_desc *tx_desc);
380int iser_alloc_rx_descriptors(struct iser_conn *ib_conn);
381#endif 369#endif
diff --git a/drivers/infiniband/ulp/iser/iser_initiator.c b/drivers/infiniband/ulp/iser/iser_initiator.c
index a00ccd1ca33..f299de6b419 100644
--- a/drivers/infiniband/ulp/iser/iser_initiator.c
+++ b/drivers/infiniband/ulp/iser/iser_initiator.c
@@ -170,7 +170,7 @@ static void iser_create_send_desc(struct iser_conn *ib_conn,
170} 170}
171 171
172 172
173int iser_alloc_rx_descriptors(struct iser_conn *ib_conn) 173static int iser_alloc_rx_descriptors(struct iser_conn *ib_conn)
174{ 174{
175 int i, j; 175 int i, j;
176 u64 dma_addr; 176 u64 dma_addr;
@@ -220,6 +220,12 @@ void iser_free_rx_descriptors(struct iser_conn *ib_conn)
220 struct iser_rx_desc *rx_desc; 220 struct iser_rx_desc *rx_desc;
221 struct iser_device *device = ib_conn->device; 221 struct iser_device *device = ib_conn->device;
222 222
223 if (ib_conn->login_buf) {
224 ib_dma_unmap_single(device->ib_device, ib_conn->login_dma,
225 ISER_RX_LOGIN_SIZE, DMA_FROM_DEVICE);
226 kfree(ib_conn->login_buf);
227 }
228
223 if (!ib_conn->rx_descs) 229 if (!ib_conn->rx_descs)
224 return; 230 return;
225 231
@@ -230,24 +236,23 @@ void iser_free_rx_descriptors(struct iser_conn *ib_conn)
230 kfree(ib_conn->rx_descs); 236 kfree(ib_conn->rx_descs);
231} 237}
232 238
233static int iser_post_rx_bufs(struct iscsi_conn *conn, struct iscsi_hdr *req) 239/**
240 * iser_conn_set_full_featured_mode - (iSER API)
241 */
242int iser_conn_set_full_featured_mode(struct iscsi_conn *conn)
234{ 243{
235 struct iscsi_iser_conn *iser_conn = conn->dd_data; 244 struct iscsi_iser_conn *iser_conn = conn->dd_data;
236 245
237 iser_dbg("req op %x flags %x\n", req->opcode, req->flags); 246 iser_dbg("Initially post: %d\n", ISER_MIN_POSTED_RX);
238 /* check if this is the last login - going to full feature phase */
239 if ((req->flags & ISCSI_FULL_FEATURE_PHASE) != ISCSI_FULL_FEATURE_PHASE)
240 return 0;
241 247
242 /* 248 /* Check that there is no posted recv or send buffers left - */
243 * Check that there is one posted recv buffer (for the last login 249 /* they must be consumed during the login phase */
244 * response) and no posted send buffers left - they must have been 250 BUG_ON(iser_conn->ib_conn->post_recv_buf_count != 0);
245 * consumed during previous login phases. 251 BUG_ON(atomic_read(&iser_conn->ib_conn->post_send_buf_count) != 0);
246 */ 252
247 WARN_ON(iser_conn->ib_conn->post_recv_buf_count != 1); 253 if (iser_alloc_rx_descriptors(iser_conn->ib_conn))
248 WARN_ON(atomic_read(&iser_conn->ib_conn->post_send_buf_count) != 0); 254 return -ENOMEM;
249 255
250 iser_dbg("Initially post: %d\n", ISER_MIN_POSTED_RX);
251 /* Initial post receive buffers */ 256 /* Initial post receive buffers */
252 if (iser_post_recvm(iser_conn->ib_conn, ISER_MIN_POSTED_RX)) 257 if (iser_post_recvm(iser_conn->ib_conn, ISER_MIN_POSTED_RX))
253 return -ENOMEM; 258 return -ENOMEM;
@@ -389,7 +394,6 @@ int iser_send_control(struct iscsi_conn *conn,
389 unsigned long data_seg_len; 394 unsigned long data_seg_len;
390 int err = 0; 395 int err = 0;
391 struct iser_device *device; 396 struct iser_device *device;
392 struct iser_conn *ib_conn = iser_conn->ib_conn;
393 397
394 /* build the tx desc regd header and add it to the tx desc dto */ 398 /* build the tx desc regd header and add it to the tx desc dto */
395 mdesc->type = ISCSI_TX_CONTROL; 399 mdesc->type = ISCSI_TX_CONTROL;
@@ -405,19 +409,9 @@ int iser_send_control(struct iscsi_conn *conn,
405 iser_err("data present on non login task!!!\n"); 409 iser_err("data present on non login task!!!\n");
406 goto send_control_error; 410 goto send_control_error;
407 } 411 }
408 412 memcpy(iser_conn->ib_conn->login_buf, task->data,
409 ib_dma_sync_single_for_cpu(device->ib_device,
410 ib_conn->login_req_dma, task->data_count,
411 DMA_TO_DEVICE);
412
413 memcpy(iser_conn->ib_conn->login_req_buf, task->data,
414 task->data_count); 413 task->data_count);
415 414 tx_dsg->addr = iser_conn->ib_conn->login_dma;
416 ib_dma_sync_single_for_device(device->ib_device,
417 ib_conn->login_req_dma, task->data_count,
418 DMA_TO_DEVICE);
419
420 tx_dsg->addr = iser_conn->ib_conn->login_req_dma;
421 tx_dsg->length = task->data_count; 415 tx_dsg->length = task->data_count;
422 tx_dsg->lkey = device->mr->lkey; 416 tx_dsg->lkey = device->mr->lkey;
423 mdesc->num_sge = 2; 417 mdesc->num_sge = 2;
@@ -427,9 +421,6 @@ int iser_send_control(struct iscsi_conn *conn,
427 err = iser_post_recvl(iser_conn->ib_conn); 421 err = iser_post_recvl(iser_conn->ib_conn);
428 if (err) 422 if (err)
429 goto send_control_error; 423 goto send_control_error;
430 err = iser_post_rx_bufs(conn, task->hdr);
431 if (err)
432 goto send_control_error;
433 } 424 }
434 425
435 err = iser_post_send(iser_conn->ib_conn, mdesc); 426 err = iser_post_send(iser_conn->ib_conn, mdesc);
@@ -454,8 +445,8 @@ void iser_rcv_completion(struct iser_rx_desc *rx_desc,
454 int rx_buflen, outstanding, count, err; 445 int rx_buflen, outstanding, count, err;
455 446
456 /* differentiate between login to all other PDUs */ 447 /* differentiate between login to all other PDUs */
457 if ((char *)rx_desc == ib_conn->login_resp_buf) { 448 if ((char *)rx_desc == ib_conn->login_buf) {
458 rx_dma = ib_conn->login_resp_dma; 449 rx_dma = ib_conn->login_dma;
459 rx_buflen = ISER_RX_LOGIN_SIZE; 450 rx_buflen = ISER_RX_LOGIN_SIZE;
460 } else { 451 } else {
461 rx_dma = rx_desc->dma_addr; 452 rx_dma = rx_desc->dma_addr;
@@ -482,7 +473,7 @@ void iser_rcv_completion(struct iser_rx_desc *rx_desc,
482 * for the posted rx bufs refcount to become zero handles everything */ 473 * for the posted rx bufs refcount to become zero handles everything */
483 conn->ib_conn->post_recv_buf_count--; 474 conn->ib_conn->post_recv_buf_count--;
484 475
485 if (rx_dma == ib_conn->login_resp_dma) 476 if (rx_dma == ib_conn->login_dma)
486 return; 477 return;
487 478
488 outstanding = ib_conn->post_recv_buf_count; 479 outstanding = ib_conn->post_recv_buf_count;
diff --git a/drivers/infiniband/ulp/iser/iser_memory.c b/drivers/infiniband/ulp/iser/iser_memory.c
index 2033a928d34..fb88d6896b6 100644
--- a/drivers/infiniband/ulp/iser/iser_memory.c
+++ b/drivers/infiniband/ulp/iser/iser_memory.c
@@ -73,11 +73,11 @@ static int iser_start_rdma_unaligned_sg(struct iscsi_iser_task *iser_task,
73 73
74 p = mem; 74 p = mem;
75 for_each_sg(sgl, sg, data->size, i) { 75 for_each_sg(sgl, sg, data->size, i) {
76 from = kmap_atomic(sg_page(sg)); 76 from = kmap_atomic(sg_page(sg), KM_USER0);
77 memcpy(p, 77 memcpy(p,
78 from + sg->offset, 78 from + sg->offset,
79 sg->length); 79 sg->length);
80 kunmap_atomic(from); 80 kunmap_atomic(from, KM_USER0);
81 p += sg->length; 81 p += sg->length;
82 } 82 }
83 } 83 }
@@ -133,11 +133,11 @@ void iser_finalize_rdma_unaligned_sg(struct iscsi_iser_task *iser_task,
133 133
134 p = mem; 134 p = mem;
135 for_each_sg(sgl, sg, sg_size, i) { 135 for_each_sg(sgl, sg, sg_size, i) {
136 to = kmap_atomic(sg_page(sg)); 136 to = kmap_atomic(sg_page(sg), KM_SOFTIRQ0);
137 memcpy(to + sg->offset, 137 memcpy(to + sg->offset,
138 p, 138 p,
139 sg->length); 139 sg->length);
140 kunmap_atomic(to); 140 kunmap_atomic(to, KM_SOFTIRQ0);
141 p += sg->length; 141 p += sg->length;
142 } 142 }
143 } 143 }
diff --git a/drivers/infiniband/ulp/iser/iser_verbs.c b/drivers/infiniband/ulp/iser/iser_verbs.c
index 95a49affee4..ede1475bee0 100644
--- a/drivers/infiniband/ulp/iser/iser_verbs.c
+++ b/drivers/infiniband/ulp/iser/iser_verbs.c
@@ -70,50 +70,32 @@ static void iser_event_handler(struct ib_event_handler *handler,
70 */ 70 */
71static int iser_create_device_ib_res(struct iser_device *device) 71static int iser_create_device_ib_res(struct iser_device *device)
72{ 72{
73 int i, j;
74 struct iser_cq_desc *cq_desc;
75
76 device->cqs_used = min(ISER_MAX_CQ, device->ib_device->num_comp_vectors);
77 iser_err("using %d CQs, device %s supports %d vectors\n", device->cqs_used,
78 device->ib_device->name, device->ib_device->num_comp_vectors);
79
80 device->cq_desc = kmalloc(sizeof(struct iser_cq_desc) * device->cqs_used,
81 GFP_KERNEL);
82 if (device->cq_desc == NULL)
83 goto cq_desc_err;
84 cq_desc = device->cq_desc;
85
86 device->pd = ib_alloc_pd(device->ib_device); 73 device->pd = ib_alloc_pd(device->ib_device);
87 if (IS_ERR(device->pd)) 74 if (IS_ERR(device->pd))
88 goto pd_err; 75 goto pd_err;
89 76
90 for (i = 0; i < device->cqs_used; i++) { 77 device->rx_cq = ib_create_cq(device->ib_device,
91 cq_desc[i].device = device; 78 iser_cq_callback,
92 cq_desc[i].cq_index = i; 79 iser_cq_event_callback,
80 (void *)device,
81 ISER_MAX_RX_CQ_LEN, 0);
82 if (IS_ERR(device->rx_cq))
83 goto rx_cq_err;
93 84
94 device->rx_cq[i] = ib_create_cq(device->ib_device, 85 device->tx_cq = ib_create_cq(device->ib_device,
95 iser_cq_callback, 86 NULL, iser_cq_event_callback,
96 iser_cq_event_callback, 87 (void *)device,
97 (void *)&cq_desc[i], 88 ISER_MAX_TX_CQ_LEN, 0);
98 ISER_MAX_RX_CQ_LEN, i);
99 if (IS_ERR(device->rx_cq[i]))
100 goto cq_err;
101 89
102 device->tx_cq[i] = ib_create_cq(device->ib_device, 90 if (IS_ERR(device->tx_cq))
103 NULL, iser_cq_event_callback, 91 goto tx_cq_err;
104 (void *)&cq_desc[i],
105 ISER_MAX_TX_CQ_LEN, i);
106 92
107 if (IS_ERR(device->tx_cq[i])) 93 if (ib_req_notify_cq(device->rx_cq, IB_CQ_NEXT_COMP))
108 goto cq_err; 94 goto cq_arm_err;
109 95
110 if (ib_req_notify_cq(device->rx_cq[i], IB_CQ_NEXT_COMP)) 96 tasklet_init(&device->cq_tasklet,
111 goto cq_err; 97 iser_cq_tasklet_fn,
112 98 (unsigned long)device);
113 tasklet_init(&device->cq_tasklet[i],
114 iser_cq_tasklet_fn,
115 (unsigned long)&cq_desc[i]);
116 }
117 99
118 device->mr = ib_get_dma_mr(device->pd, IB_ACCESS_LOCAL_WRITE | 100 device->mr = ib_get_dma_mr(device->pd, IB_ACCESS_LOCAL_WRITE |
119 IB_ACCESS_REMOTE_WRITE | 101 IB_ACCESS_REMOTE_WRITE |
@@ -131,19 +113,14 @@ static int iser_create_device_ib_res(struct iser_device *device)
131handler_err: 113handler_err:
132 ib_dereg_mr(device->mr); 114 ib_dereg_mr(device->mr);
133dma_mr_err: 115dma_mr_err:
134 for (j = 0; j < device->cqs_used; j++) 116 tasklet_kill(&device->cq_tasklet);
135 tasklet_kill(&device->cq_tasklet[j]); 117cq_arm_err:
136cq_err: 118 ib_destroy_cq(device->tx_cq);
137 for (j = 0; j < i; j++) { 119tx_cq_err:
138 if (device->tx_cq[j]) 120 ib_destroy_cq(device->rx_cq);
139 ib_destroy_cq(device->tx_cq[j]); 121rx_cq_err:
140 if (device->rx_cq[j])
141 ib_destroy_cq(device->rx_cq[j]);
142 }
143 ib_dealloc_pd(device->pd); 122 ib_dealloc_pd(device->pd);
144pd_err: 123pd_err:
145 kfree(device->cq_desc);
146cq_desc_err:
147 iser_err("failed to allocate an IB resource\n"); 124 iser_err("failed to allocate an IB resource\n");
148 return -1; 125 return -1;
149} 126}
@@ -154,24 +131,18 @@ cq_desc_err:
154 */ 131 */
155static void iser_free_device_ib_res(struct iser_device *device) 132static void iser_free_device_ib_res(struct iser_device *device)
156{ 133{
157 int i;
158 BUG_ON(device->mr == NULL); 134 BUG_ON(device->mr == NULL);
159 135
160 for (i = 0; i < device->cqs_used; i++) { 136 tasklet_kill(&device->cq_tasklet);
161 tasklet_kill(&device->cq_tasklet[i]);
162 (void)ib_destroy_cq(device->tx_cq[i]);
163 (void)ib_destroy_cq(device->rx_cq[i]);
164 device->tx_cq[i] = NULL;
165 device->rx_cq[i] = NULL;
166 }
167
168 (void)ib_unregister_event_handler(&device->event_handler); 137 (void)ib_unregister_event_handler(&device->event_handler);
169 (void)ib_dereg_mr(device->mr); 138 (void)ib_dereg_mr(device->mr);
139 (void)ib_destroy_cq(device->tx_cq);
140 (void)ib_destroy_cq(device->rx_cq);
170 (void)ib_dealloc_pd(device->pd); 141 (void)ib_dealloc_pd(device->pd);
171 142
172 kfree(device->cq_desc);
173
174 device->mr = NULL; 143 device->mr = NULL;
144 device->tx_cq = NULL;
145 device->rx_cq = NULL;
175 device->pd = NULL; 146 device->pd = NULL;
176} 147}
177 148
@@ -184,40 +155,20 @@ static int iser_create_ib_conn_res(struct iser_conn *ib_conn)
184{ 155{
185 struct iser_device *device; 156 struct iser_device *device;
186 struct ib_qp_init_attr init_attr; 157 struct ib_qp_init_attr init_attr;
187 int req_err, resp_err, ret = -ENOMEM; 158 int ret = -ENOMEM;
188 struct ib_fmr_pool_param params; 159 struct ib_fmr_pool_param params;
189 int index, min_index = 0;
190 160
191 BUG_ON(ib_conn->device == NULL); 161 BUG_ON(ib_conn->device == NULL);
192 162
193 device = ib_conn->device; 163 device = ib_conn->device;
194 164
195 ib_conn->login_buf = kmalloc(ISCSI_DEF_MAX_RECV_SEG_LEN + 165 ib_conn->login_buf = kmalloc(ISER_RX_LOGIN_SIZE, GFP_KERNEL);
196 ISER_RX_LOGIN_SIZE, GFP_KERNEL);
197 if (!ib_conn->login_buf) 166 if (!ib_conn->login_buf)
198 goto out_err; 167 goto out_err;
199 168
200 ib_conn->login_req_buf = ib_conn->login_buf; 169 ib_conn->login_dma = ib_dma_map_single(ib_conn->device->ib_device,
201 ib_conn->login_resp_buf = ib_conn->login_buf + ISCSI_DEF_MAX_RECV_SEG_LEN; 170 (void *)ib_conn->login_buf, ISER_RX_LOGIN_SIZE,
202 171 DMA_FROM_DEVICE);
203 ib_conn->login_req_dma = ib_dma_map_single(ib_conn->device->ib_device,
204 (void *)ib_conn->login_req_buf,
205 ISCSI_DEF_MAX_RECV_SEG_LEN, DMA_TO_DEVICE);
206
207 ib_conn->login_resp_dma = ib_dma_map_single(ib_conn->device->ib_device,
208 (void *)ib_conn->login_resp_buf,
209 ISER_RX_LOGIN_SIZE, DMA_FROM_DEVICE);
210
211 req_err = ib_dma_mapping_error(device->ib_device, ib_conn->login_req_dma);
212 resp_err = ib_dma_mapping_error(device->ib_device, ib_conn->login_resp_dma);
213
214 if (req_err || resp_err) {
215 if (req_err)
216 ib_conn->login_req_dma = 0;
217 if (resp_err)
218 ib_conn->login_resp_dma = 0;
219 goto out_err;
220 }
221 172
222 ib_conn->page_vec = kmalloc(sizeof(struct iser_page_vec) + 173 ib_conn->page_vec = kmalloc(sizeof(struct iser_page_vec) +
223 (sizeof(u64) * (ISCSI_ISER_SG_TABLESIZE +1)), 174 (sizeof(u64) * (ISCSI_ISER_SG_TABLESIZE +1)),
@@ -250,20 +201,10 @@ static int iser_create_ib_conn_res(struct iser_conn *ib_conn)
250 201
251 memset(&init_attr, 0, sizeof init_attr); 202 memset(&init_attr, 0, sizeof init_attr);
252 203
253 mutex_lock(&ig.connlist_mutex);
254 /* select the CQ with the minimal number of usages */
255 for (index = 0; index < device->cqs_used; index++)
256 if (device->cq_active_qps[index] <
257 device->cq_active_qps[min_index])
258 min_index = index;
259 device->cq_active_qps[min_index]++;
260 mutex_unlock(&ig.connlist_mutex);
261 iser_err("cq index %d used for ib_conn %p\n", min_index, ib_conn);
262
263 init_attr.event_handler = iser_qp_event_callback; 204 init_attr.event_handler = iser_qp_event_callback;
264 init_attr.qp_context = (void *)ib_conn; 205 init_attr.qp_context = (void *)ib_conn;
265 init_attr.send_cq = device->tx_cq[min_index]; 206 init_attr.send_cq = device->tx_cq;
266 init_attr.recv_cq = device->rx_cq[min_index]; 207 init_attr.recv_cq = device->rx_cq;
267 init_attr.cap.max_send_wr = ISER_QP_MAX_REQ_DTOS; 208 init_attr.cap.max_send_wr = ISER_QP_MAX_REQ_DTOS;
268 init_attr.cap.max_recv_wr = ISER_QP_MAX_RECV_DTOS; 209 init_attr.cap.max_recv_wr = ISER_QP_MAX_RECV_DTOS;
269 init_attr.cap.max_send_sge = 2; 210 init_attr.cap.max_send_sge = 2;
@@ -292,7 +233,6 @@ out_err:
292 */ 233 */
293static int iser_free_ib_conn_res(struct iser_conn *ib_conn, int can_destroy_id) 234static int iser_free_ib_conn_res(struct iser_conn *ib_conn, int can_destroy_id)
294{ 235{
295 int cq_index;
296 BUG_ON(ib_conn == NULL); 236 BUG_ON(ib_conn == NULL);
297 237
298 iser_err("freeing conn %p cma_id %p fmr pool %p qp %p\n", 238 iser_err("freeing conn %p cma_id %p fmr pool %p qp %p\n",
@@ -303,12 +243,9 @@ static int iser_free_ib_conn_res(struct iser_conn *ib_conn, int can_destroy_id)
303 if (ib_conn->fmr_pool != NULL) 243 if (ib_conn->fmr_pool != NULL)
304 ib_destroy_fmr_pool(ib_conn->fmr_pool); 244 ib_destroy_fmr_pool(ib_conn->fmr_pool);
305 245
306 if (ib_conn->qp != NULL) { 246 if (ib_conn->qp != NULL)
307 cq_index = ((struct iser_cq_desc *)ib_conn->qp->recv_cq->cq_context)->cq_index;
308 ib_conn->device->cq_active_qps[cq_index]--;
309
310 rdma_destroy_qp(ib_conn->cma_id); 247 rdma_destroy_qp(ib_conn->cma_id);
311 } 248
312 /* if cma handler context, the caller acts s.t the cma destroy the id */ 249 /* if cma handler context, the caller acts s.t the cma destroy the id */
313 if (ib_conn->cma_id != NULL && can_destroy_id) 250 if (ib_conn->cma_id != NULL && can_destroy_id)
314 rdma_destroy_id(ib_conn->cma_id); 251 rdma_destroy_id(ib_conn->cma_id);
@@ -318,18 +255,6 @@ static int iser_free_ib_conn_res(struct iser_conn *ib_conn, int can_destroy_id)
318 ib_conn->cma_id = NULL; 255 ib_conn->cma_id = NULL;
319 kfree(ib_conn->page_vec); 256 kfree(ib_conn->page_vec);
320 257
321 if (ib_conn->login_buf) {
322 if (ib_conn->login_req_dma)
323 ib_dma_unmap_single(ib_conn->device->ib_device,
324 ib_conn->login_req_dma,
325 ISCSI_DEF_MAX_RECV_SEG_LEN, DMA_TO_DEVICE);
326 if (ib_conn->login_resp_dma)
327 ib_dma_unmap_single(ib_conn->device->ib_device,
328 ib_conn->login_resp_dma,
329 ISER_RX_LOGIN_SIZE, DMA_FROM_DEVICE);
330 kfree(ib_conn->login_buf);
331 }
332
333 return 0; 258 return 0;
334} 259}
335 260
@@ -657,9 +582,8 @@ id_failure:
657 ib_conn->cma_id = NULL; 582 ib_conn->cma_id = NULL;
658addr_failure: 583addr_failure:
659 ib_conn->state = ISER_CONN_DOWN; 584 ib_conn->state = ISER_CONN_DOWN;
660 iser_conn_put(ib_conn, 1); /* deref ib conn's cma id */
661connect_failure: 585connect_failure:
662 iser_conn_put(ib_conn, 1); /* deref ib conn deallocate */ 586 iser_conn_release(ib_conn, 1);
663 return err; 587 return err;
664} 588}
665 589
@@ -734,11 +658,11 @@ int iser_post_recvl(struct iser_conn *ib_conn)
734 struct ib_sge sge; 658 struct ib_sge sge;
735 int ib_ret; 659 int ib_ret;
736 660
737 sge.addr = ib_conn->login_resp_dma; 661 sge.addr = ib_conn->login_dma;
738 sge.length = ISER_RX_LOGIN_SIZE; 662 sge.length = ISER_RX_LOGIN_SIZE;
739 sge.lkey = ib_conn->device->mr->lkey; 663 sge.lkey = ib_conn->device->mr->lkey;
740 664
741 rx_wr.wr_id = (unsigned long)ib_conn->login_resp_buf; 665 rx_wr.wr_id = (unsigned long)ib_conn->login_buf;
742 rx_wr.sg_list = &sge; 666 rx_wr.sg_list = &sge;
743 rx_wr.num_sge = 1; 667 rx_wr.num_sge = 1;
744 rx_wr.next = NULL; 668 rx_wr.next = NULL;
@@ -835,9 +759,9 @@ static void iser_handle_comp_error(struct iser_tx_desc *desc,
835 } 759 }
836} 760}
837 761
838static int iser_drain_tx_cq(struct iser_device *device, int cq_index) 762static int iser_drain_tx_cq(struct iser_device *device)
839{ 763{
840 struct ib_cq *cq = device->tx_cq[cq_index]; 764 struct ib_cq *cq = device->tx_cq;
841 struct ib_wc wc; 765 struct ib_wc wc;
842 struct iser_tx_desc *tx_desc; 766 struct iser_tx_desc *tx_desc;
843 struct iser_conn *ib_conn; 767 struct iser_conn *ib_conn;
@@ -866,10 +790,8 @@ static int iser_drain_tx_cq(struct iser_device *device, int cq_index)
866 790
867static void iser_cq_tasklet_fn(unsigned long data) 791static void iser_cq_tasklet_fn(unsigned long data)
868{ 792{
869 struct iser_cq_desc *cq_desc = (struct iser_cq_desc *)data; 793 struct iser_device *device = (struct iser_device *)data;
870 struct iser_device *device = cq_desc->device; 794 struct ib_cq *cq = device->rx_cq;
871 int cq_index = cq_desc->cq_index;
872 struct ib_cq *cq = device->rx_cq[cq_index];
873 struct ib_wc wc; 795 struct ib_wc wc;
874 struct iser_rx_desc *desc; 796 struct iser_rx_desc *desc;
875 unsigned long xfer_len; 797 unsigned long xfer_len;
@@ -897,21 +819,19 @@ static void iser_cq_tasklet_fn(unsigned long data)
897 } 819 }
898 completed_rx++; 820 completed_rx++;
899 if (!(completed_rx & 63)) 821 if (!(completed_rx & 63))
900 completed_tx += iser_drain_tx_cq(device, cq_index); 822 completed_tx += iser_drain_tx_cq(device);
901 } 823 }
902 /* #warning "it is assumed here that arming CQ only once its empty" * 824 /* #warning "it is assumed here that arming CQ only once its empty" *
903 * " would not cause interrupts to be missed" */ 825 * " would not cause interrupts to be missed" */
904 ib_req_notify_cq(cq, IB_CQ_NEXT_COMP); 826 ib_req_notify_cq(cq, IB_CQ_NEXT_COMP);
905 827
906 completed_tx += iser_drain_tx_cq(device, cq_index); 828 completed_tx += iser_drain_tx_cq(device);
907 iser_dbg("got %d rx %d tx completions\n", completed_rx, completed_tx); 829 iser_dbg("got %d rx %d tx completions\n", completed_rx, completed_tx);
908} 830}
909 831
910static void iser_cq_callback(struct ib_cq *cq, void *cq_context) 832static void iser_cq_callback(struct ib_cq *cq, void *cq_context)
911{ 833{
912 struct iser_cq_desc *cq_desc = (struct iser_cq_desc *)cq_context; 834 struct iser_device *device = (struct iser_device *)cq_context;
913 struct iser_device *device = cq_desc->device;
914 int cq_index = cq_desc->cq_index;
915 835
916 tasklet_schedule(&device->cq_tasklet[cq_index]); 836 tasklet_schedule(&device->cq_tasklet);
917} 837}