aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/ulp/iser/iser_verbs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/infiniband/ulp/iser/iser_verbs.c')
-rw-r--r--drivers/infiniband/ulp/iser/iser_verbs.c134
1 files changed, 85 insertions, 49 deletions
diff --git a/drivers/infiniband/ulp/iser/iser_verbs.c b/drivers/infiniband/ulp/iser/iser_verbs.c
index 7092503a10e3..89b956044060 100644
--- a/drivers/infiniband/ulp/iser/iser_verbs.c
+++ b/drivers/infiniband/ulp/iser/iser_verbs.c
@@ -129,13 +129,23 @@ static int iser_create_ib_conn_res(struct iser_conn *ib_conn)
129{ 129{
130 struct iser_device *device; 130 struct iser_device *device;
131 struct ib_qp_init_attr init_attr; 131 struct ib_qp_init_attr init_attr;
132 int ret; 132 int ret = -ENOMEM;
133 struct ib_fmr_pool_param params; 133 struct ib_fmr_pool_param params;
134 134
135 BUG_ON(ib_conn->device == NULL); 135 BUG_ON(ib_conn->device == NULL);
136 136
137 device = ib_conn->device; 137 device = ib_conn->device;
138 138
139 ib_conn->login_buf = kmalloc(ISER_RX_LOGIN_SIZE, GFP_KERNEL);
140 if (!ib_conn->login_buf) {
141 goto alloc_err;
142 ret = -ENOMEM;
143 }
144
145 ib_conn->login_dma = ib_dma_map_single(ib_conn->device->ib_device,
146 (void *)ib_conn->login_buf, ISER_RX_LOGIN_SIZE,
147 DMA_FROM_DEVICE);
148
139 ib_conn->page_vec = kmalloc(sizeof(struct iser_page_vec) + 149 ib_conn->page_vec = kmalloc(sizeof(struct iser_page_vec) +
140 (sizeof(u64) * (ISCSI_ISER_SG_TABLESIZE +1)), 150 (sizeof(u64) * (ISCSI_ISER_SG_TABLESIZE +1)),
141 GFP_KERNEL); 151 GFP_KERNEL);
@@ -174,7 +184,7 @@ static int iser_create_ib_conn_res(struct iser_conn *ib_conn)
174 init_attr.cap.max_send_wr = ISER_QP_MAX_REQ_DTOS; 184 init_attr.cap.max_send_wr = ISER_QP_MAX_REQ_DTOS;
175 init_attr.cap.max_recv_wr = ISER_QP_MAX_RECV_DTOS; 185 init_attr.cap.max_recv_wr = ISER_QP_MAX_RECV_DTOS;
176 init_attr.cap.max_send_sge = MAX_REGD_BUF_VECTOR_LEN; 186 init_attr.cap.max_send_sge = MAX_REGD_BUF_VECTOR_LEN;
177 init_attr.cap.max_recv_sge = 2; 187 init_attr.cap.max_recv_sge = 1;
178 init_attr.sq_sig_type = IB_SIGNAL_REQ_WR; 188 init_attr.sq_sig_type = IB_SIGNAL_REQ_WR;
179 init_attr.qp_type = IB_QPT_RC; 189 init_attr.qp_type = IB_QPT_RC;
180 190
@@ -192,6 +202,7 @@ qp_err:
192 (void)ib_destroy_fmr_pool(ib_conn->fmr_pool); 202 (void)ib_destroy_fmr_pool(ib_conn->fmr_pool);
193fmr_pool_err: 203fmr_pool_err:
194 kfree(ib_conn->page_vec); 204 kfree(ib_conn->page_vec);
205 kfree(ib_conn->login_buf);
195alloc_err: 206alloc_err:
196 iser_err("unable to alloc mem or create resource, err %d\n", ret); 207 iser_err("unable to alloc mem or create resource, err %d\n", ret);
197 return ret; 208 return ret;
@@ -314,7 +325,7 @@ static void iser_conn_release(struct iser_conn *ib_conn)
314 mutex_lock(&ig.connlist_mutex); 325 mutex_lock(&ig.connlist_mutex);
315 list_del(&ib_conn->conn_list); 326 list_del(&ib_conn->conn_list);
316 mutex_unlock(&ig.connlist_mutex); 327 mutex_unlock(&ig.connlist_mutex);
317 328 iser_free_rx_descriptors(ib_conn);
318 iser_free_ib_conn_res(ib_conn); 329 iser_free_ib_conn_res(ib_conn);
319 ib_conn->device = NULL; 330 ib_conn->device = NULL;
320 /* on EVENT_ADDR_ERROR there's no device yet for this conn */ 331 /* on EVENT_ADDR_ERROR there's no device yet for this conn */
@@ -625,6 +636,60 @@ void iser_unreg_mem(struct iser_mem_reg *reg)
625 reg->mem_h = NULL; 636 reg->mem_h = NULL;
626} 637}
627 638
639int iser_post_recvl(struct iser_conn *ib_conn)
640{
641 struct ib_recv_wr rx_wr, *rx_wr_failed;
642 struct ib_sge sge;
643 int ib_ret;
644
645 sge.addr = ib_conn->login_dma;
646 sge.length = ISER_RX_LOGIN_SIZE;
647 sge.lkey = ib_conn->device->mr->lkey;
648
649 rx_wr.wr_id = (unsigned long)ib_conn->login_buf;
650 rx_wr.sg_list = &sge;
651 rx_wr.num_sge = 1;
652 rx_wr.next = NULL;
653
654 atomic_inc(&ib_conn->post_recv_buf_count);
655 ib_ret = ib_post_recv(ib_conn->qp, &rx_wr, &rx_wr_failed);
656 if (ib_ret) {
657 iser_err("ib_post_recv failed ret=%d\n", ib_ret);
658 atomic_dec(&ib_conn->post_recv_buf_count);
659 }
660 return ib_ret;
661}
662
663int iser_post_recvm(struct iser_conn *ib_conn, int count)
664{
665 struct ib_recv_wr *rx_wr, *rx_wr_failed;
666 int i, ib_ret;
667 unsigned int my_rx_head = ib_conn->rx_desc_head;
668 struct iser_rx_desc *rx_desc;
669
670 for (rx_wr = ib_conn->rx_wr, i = 0; i < count; i++, rx_wr++) {
671 rx_desc = &ib_conn->rx_descs[my_rx_head];
672 rx_wr->wr_id = (unsigned long)rx_desc;
673 rx_wr->sg_list = &rx_desc->rx_sg;
674 rx_wr->num_sge = 1;
675 rx_wr->next = rx_wr + 1;
676 my_rx_head = (my_rx_head + 1) & (ISER_QP_MAX_RECV_DTOS - 1);
677 }
678
679 rx_wr--;
680 rx_wr->next = NULL; /* mark end of work requests list */
681
682 atomic_add(count, &ib_conn->post_recv_buf_count);
683 ib_ret = ib_post_recv(ib_conn->qp, ib_conn->rx_wr, &rx_wr_failed);
684 if (ib_ret) {
685 iser_err("ib_post_recv failed ret=%d\n", ib_ret);
686 atomic_sub(count, &ib_conn->post_recv_buf_count);
687 } else
688 ib_conn->rx_desc_head = my_rx_head;
689 return ib_ret;
690}
691
692
628/** 693/**
629 * iser_dto_to_iov - builds IOV from a dto descriptor 694 * iser_dto_to_iov - builds IOV from a dto descriptor
630 */ 695 */
@@ -665,39 +730,6 @@ static void iser_dto_to_iov(struct iser_dto *dto, struct ib_sge *iov, int iov_le
665 } 730 }
666} 731}
667 732
668/**
669 * iser_post_recv - Posts a receive buffer.
670 *
671 * returns 0 on success, -1 on failure
672 */
673int iser_post_recv(struct iser_desc *rx_desc)
674{
675 int ib_ret, ret_val = 0;
676 struct ib_recv_wr recv_wr, *recv_wr_failed;
677 struct ib_sge iov[2];
678 struct iser_conn *ib_conn;
679 struct iser_dto *recv_dto = &rx_desc->dto;
680
681 /* Retrieve conn */
682 ib_conn = recv_dto->ib_conn;
683
684 iser_dto_to_iov(recv_dto, iov, 2);
685
686 recv_wr.next = NULL;
687 recv_wr.sg_list = iov;
688 recv_wr.num_sge = recv_dto->regd_vector_len;
689 recv_wr.wr_id = (unsigned long)rx_desc;
690
691 atomic_inc(&ib_conn->post_recv_buf_count);
692 ib_ret = ib_post_recv(ib_conn->qp, &recv_wr, &recv_wr_failed);
693 if (ib_ret) {
694 iser_err("ib_post_recv failed ret=%d\n", ib_ret);
695 atomic_dec(&ib_conn->post_recv_buf_count);
696 ret_val = -1;
697 }
698
699 return ret_val;
700}
701 733
702/** 734/**
703 * iser_start_send - Initiate a Send DTO operation 735 * iser_start_send - Initiate a Send DTO operation
@@ -737,18 +769,17 @@ int iser_post_send(struct iser_desc *tx_desc)
737 return ret_val; 769 return ret_val;
738} 770}
739 771
740static void iser_handle_comp_error(struct iser_desc *desc) 772static void iser_handle_comp_error(struct iser_desc *desc,
773 struct iser_conn *ib_conn)
741{ 774{
742 struct iser_dto *dto = &desc->dto; 775 struct iser_rx_desc *rx = (struct iser_rx_desc *)desc;
743 struct iser_conn *ib_conn = dto->ib_conn; 776 struct iser_rx_desc *rx_first = ib_conn->rx_descs;
744 777 struct iser_rx_desc *rx_last = rx_first + (ISER_QP_MAX_RECV_DTOS - 1);
745 iser_dto_buffs_release(dto);
746 778
747 if (desc->type == ISCSI_RX) { 779 if ((char *)desc == ib_conn->login_buf ||
748 kfree(desc->data); 780 (rx_first <= rx && rx <= rx_last))
749 kmem_cache_free(ig.desc_cache, desc);
750 atomic_dec(&ib_conn->post_recv_buf_count); 781 atomic_dec(&ib_conn->post_recv_buf_count);
751 } else { /* type is TX control/command/dataout */ 782 else { /* type is TX control/command/dataout */
752 if (desc->type == ISCSI_TX_DATAOUT) 783 if (desc->type == ISCSI_TX_DATAOUT)
753 kmem_cache_free(ig.desc_cache, desc); 784 kmem_cache_free(ig.desc_cache, desc);
754 atomic_dec(&ib_conn->post_send_buf_count); 785 atomic_dec(&ib_conn->post_send_buf_count);
@@ -780,20 +811,25 @@ static void iser_cq_tasklet_fn(unsigned long data)
780 struct ib_wc wc; 811 struct ib_wc wc;
781 struct iser_desc *desc; 812 struct iser_desc *desc;
782 unsigned long xfer_len; 813 unsigned long xfer_len;
814 struct iser_conn *ib_conn;
783 815
784 while (ib_poll_cq(cq, 1, &wc) == 1) { 816 while (ib_poll_cq(cq, 1, &wc) == 1) {
785 desc = (struct iser_desc *) (unsigned long) wc.wr_id; 817 desc = (struct iser_desc *) (unsigned long) wc.wr_id;
786 BUG_ON(desc == NULL); 818 BUG_ON(desc == NULL);
819 ib_conn = wc.qp->qp_context;
787 820
788 if (wc.status == IB_WC_SUCCESS) { 821 if (wc.status == IB_WC_SUCCESS) {
789 if (desc->type == ISCSI_RX) { 822 if (wc.opcode == IB_WC_RECV) {
790 xfer_len = (unsigned long)wc.byte_len; 823 xfer_len = (unsigned long)wc.byte_len;
791 iser_rcv_completion(desc, xfer_len); 824 iser_rcv_completion((struct iser_rx_desc *)desc,
825 xfer_len, ib_conn);
792 } else /* type == ISCSI_TX_CONTROL/SCSI_CMD/DOUT */ 826 } else /* type == ISCSI_TX_CONTROL/SCSI_CMD/DOUT */
793 iser_snd_completion(desc); 827 iser_snd_completion(desc);
794 } else { 828 } else {
795 iser_err("comp w. error op %d status %d\n",desc->type,wc.status); 829 if (wc.status != IB_WC_WR_FLUSH_ERR)
796 iser_handle_comp_error(desc); 830 iser_err("id %llx status %d vend_err %x\n",
831 wc.wr_id, wc.status, wc.vendor_err);
832 iser_handle_comp_error(desc, ib_conn);
797 } 833 }
798 } 834 }
799 /* #warning "it is assumed here that arming CQ only once its empty" * 835 /* #warning "it is assumed here that arming CQ only once its empty" *