33 #include <linux/kernel.h>
34 #include <linux/module.h>
35 #include <linux/slab.h>
40 #define ISCSI_ISER_MAX_CONN 8
41 #define ISER_MAX_RX_CQ_LEN (ISER_QP_MAX_RECV_DTOS * ISCSI_ISER_MAX_CONN)
42 #define ISER_MAX_TX_CQ_LEN (ISER_QP_MAX_REQ_DTOS * ISCSI_ISER_MAX_CONN)
44 static void iser_cq_tasklet_fn(
unsigned long data);
60 iser_err(
"async event %d on device %s port %d\n", event->
event,
87 if (IS_ERR(device->
pd))
90 for (i = 0; i < device->
cqs_used; i++) {
96 iser_cq_event_callback,
99 if (IS_ERR(device->
rx_cq[i]))
103 NULL, iser_cq_event_callback,
107 if (IS_ERR(device->
tx_cq[i]))
115 (
unsigned long)&cq_desc[i]);
121 if (IS_ERR(device->
mr))
134 for (j = 0; j < device->
cqs_used; j++)
137 for (j = 0; j <
i; j++) {
138 if (device->
tx_cq[j])
140 if (device->
rx_cq[j])
147 iser_err(
"failed to allocate an IB resource\n");
155 static void iser_free_device_ib_res(
struct iser_device *device)
160 for (i = 0; i < device->
cqs_used; i++) {
183 static int iser_create_ib_conn_res(
struct iser_conn *ib_conn)
189 int index, min_index = 0;
214 if (req_err || resp_err) {
251 memset(&init_attr, 0,
sizeof init_attr);
255 for (index = 0; index < device->
cqs_used; index++)
261 iser_err(
"cq index %d used for ib_conn %p\n", min_index, ib_conn);
263 init_attr.event_handler = iser_qp_event_callback;
264 init_attr.qp_context = (
void *)ib_conn;
265 init_attr.send_cq = device->
tx_cq[min_index];
266 init_attr.recv_cq = device->
rx_cq[min_index];
269 init_attr.cap.max_send_sge = 2;
270 init_attr.cap.max_recv_sge = 1;
279 iser_err(
"setting conn %p cma_id %p: fmr_pool %p qp %p\n",
285 iser_err(
"unable to alloc mem or create resource, err %d\n", ret);
293 static int iser_free_ib_conn_res(
struct iser_conn *ib_conn,
int can_destroy_id)
298 iser_err(
"freeing conn %p cma_id %p fmr pool %p qp %p\n",
306 if (ib_conn->
qp !=
NULL) {
307 cq_index = ((
struct iser_cq_desc *)ib_conn->
qp->recv_cq->cq_context)->cq_index;
313 if (ib_conn->
cma_id !=
NULL && can_destroy_id)
323 ib_dma_unmap_single(ib_conn->
device->ib_device,
327 ib_dma_unmap_single(ib_conn->
device->ib_device,
359 if (iser_create_device_ib_res(device)) {
364 list_add(&device->
ig_list, &
ig.device_list);
374 static void iser_device_try_release(
struct iser_device *device)
380 iser_free_device_ib_res(device);
387 static int iser_conn_state_comp_exch(
struct iser_conn *ib_conn,
393 spin_lock_bh(&ib_conn->
lock);
394 if ((ret = (ib_conn->
state == comp)))
395 ib_conn->
state = exch;
396 spin_unlock_bh(&ib_conn->
lock);
403 static void iser_conn_release(
struct iser_conn *ib_conn,
int can_destroy_id)
413 iser_free_ib_conn_res(ib_conn, can_destroy_id);
417 iser_device_try_release(device);
429 iser_conn_release(ib_conn, can_destroy_id);
450 iser_err(
"Failed to disconnect, conn: 0x%p err %d\n",
459 static int iser_connect_error(
struct rdma_cm_id *cma_id)
469 static int iser_addr_handler(
struct rdma_cm_id *cma_id)
475 device = iser_device_find_by_ib_device(cma_id);
477 iser_err(
"device lookup/creation failed\n");
478 return iser_connect_error(cma_id);
486 iser_err(
"resolve route failed: %d\n", ret);
487 return iser_connect_error(cma_id);
493 static int iser_route_handler(
struct rdma_cm_id *cma_id)
502 memset(&conn_param, 0,
sizeof conn_param);
503 conn_param.responder_resources = 4;
504 conn_param.initiator_depth = 1;
505 conn_param.retry_count = 7;
506 conn_param.rnr_retry_count = 6;
510 iser_err(
"failure connecting: %d\n", ret);
516 return iser_connect_error(cma_id);
519 static void iser_connected_handler(
struct rdma_cm_id *cma_id)
528 static int iser_disconnected_handler(
struct rdma_cm_id *cma_id)
557 iser_err(
"event %d status %d conn %p id %p\n",
560 switch (event->
event) {
562 ret = iser_addr_handler(cma_id);
565 ret = iser_route_handler(cma_id);
568 iser_connected_handler(cma_id);
575 ret = iser_connect_error(cma_id);
580 ret = iser_disconnected_handler(cma_id);
618 iser_err(
"connecting to: %pI4, port 0x%x\n",
627 if (IS_ERR(ib_conn->
cma_id)) {
628 err = PTR_ERR(ib_conn->
cma_id);
629 iser_err(
"rdma_create_id failed: %d\n", err);
637 iser_err(
"rdma_resolve_addr failed: %d\n", err);
647 goto connect_failure;
680 page_list = page_vec->
pages;
681 io_addr = page_list[0];
689 status = (
int)PTR_ERR(mem);
690 iser_err(
"ib_fmr_pool_map_phys failed: %d\n", status);
694 mem_reg->
lkey = mem->
fmr->lkey;
695 mem_reg->
rkey = mem->
fmr->rkey;
699 mem_reg->
mem_h = (
void *)mem;
704 iser_dbg(
"PHYSICAL Mem.register, [PHYS p_array: 0x%p, sz: %d, "
705 "entry[0]: (0x%08lx,%ld)] -> "
706 "[lkey: 0x%08X mem_h: 0x%p va: 0x%08lX sz: %ld]\n",
707 page_vec, page_vec->
length,
708 (
unsigned long)page_vec->
pages[0],
710 (
unsigned int)mem_reg->
lkey, mem_reg->
mem_h,
711 (
unsigned long)mem_reg->
va, (
unsigned long)mem_reg->
len);
726 iser_err(
"ib_fmr_pool_unmap failed %d\n", ret);
747 ib_ret = ib_post_recv(ib_conn->
qp, &rx_wr, &rx_wr_failed);
749 iser_err(
"ib_post_recv failed ret=%d\n", ib_ret);
762 for (rx_wr = ib_conn->
rx_wr, i = 0; i < count; i++, rx_wr++) {
763 rx_desc = &ib_conn->
rx_descs[my_rx_head];
767 rx_wr->
next = rx_wr + 1;
775 ib_ret = ib_post_recv(ib_conn->
qp, ib_conn->
rx_wr, &rx_wr_failed);
777 iser_err(
"ib_post_recv failed ret=%d\n", ib_ret);
795 ib_dma_sync_single_for_device(ib_conn->
device->ib_device,
807 ib_ret = ib_post_send(ib_conn->
qp, &send_wr, &send_wr_failed);
809 iser_err(
"ib_post_send failed, ret:%d\n", ib_ret);
838 static int iser_drain_tx_cq(
struct iser_device *device,
int cq_index)
844 int completed_tx = 0;
846 while (ib_poll_cq(cq, 1, &
wc) == 1) {
848 ib_conn =
wc.qp->qp_context;
853 iser_err(
"expected opcode %d got %d\n",
856 iser_err(
"tx id %llx status %d vend_err %x\n",
857 wc.wr_id,
wc.status,
wc.vendor_err);
859 iser_handle_comp_error(tx_desc, ib_conn);
867 static void iser_cq_tasklet_fn(
unsigned long data)
877 int completed_tx, completed_rx;
878 completed_tx = completed_rx = 0;
880 while (ib_poll_cq(cq, 1, &
wc) == 1) {
883 ib_conn =
wc.qp->qp_context;
886 xfer_len = (
unsigned long)
wc.byte_len;
889 iser_err(
"expected opcode %d got %d\n",
893 iser_err(
"rx id %llx status %d vend_err %x\n",
894 wc.wr_id,
wc.status,
wc.vendor_err);
896 iser_handle_comp_error(
NULL, ib_conn);
899 if (!(completed_rx & 63))
900 completed_tx += iser_drain_tx_cq(device, cq_index);
906 completed_tx += iser_drain_tx_cq(device, cq_index);
907 iser_dbg(
"got %d rx %d tx completions\n", completed_rx, completed_tx);
916 tasklet_schedule(&device->
cq_tasklet[cq_index]);