From patchwork Wed Aug 4 18:45:59 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Roland Dreier X-Patchwork-Id: 117114 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.4/8.14.3) with ESMTP id o74Ik7kg006027 for ; Wed, 4 Aug 2010 18:46:07 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753900Ab0HDSqG (ORCPT ); Wed, 4 Aug 2010 14:46:06 -0400 Received: from sj-iport-4.cisco.com ([171.68.10.86]:49487 "EHLO sj-iport-4.cisco.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752491Ab0HDSqF (ORCPT ); Wed, 4 Aug 2010 14:46:05 -0400 Authentication-Results: sj-iport-4.cisco.com; dkim=neutral (message not signed) header.i=none X-IronPort-AV: E=Sophos;i="4.55,316,1278288000"; d="scan'208";a="167512307" Received: from sj-core-1.cisco.com ([171.71.177.237]) by sj-iport-4.cisco.com with ESMTP; 04 Aug 2010 18:46:03 +0000 Received: from roland-alpha.cisco.com (roland-alpha.cisco.com [10.33.42.9]) by sj-core-1.cisco.com (8.13.8/8.14.3) with ESMTP id o74Ik32o017629; Wed, 4 Aug 2010 18:46:03 GMT Received: by roland-alpha.cisco.com (Postfix, from userid 33217) id B479620394; Wed, 4 Aug 2010 11:45:59 -0700 (PDT) From: Roland Dreier To: Bart Van Assche Cc: linux-rdma@vger.kernel.org, Roland Dreier , David Dillow Subject: Re: [PATCH] IB/srp receive buffer handling robustness improvement References: <201007301259.05796.bvanassche@acm.org> X-Message-Flag: Warning: May contain useful information Date: Wed, 04 Aug 2010 11:45:59 -0700 In-Reply-To: <201007301259.05796.bvanassche@acm.org> (Bart Van Assche's message of "Fri, 30 Jul 2010 12:59:05 +0200") Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.1 (gnu/linux) MIME-Version: 1.0 Sender: linux-rdma-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-rdma@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Wed, 04 Aug 2010 18:46:08 +0000 (UTC) diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c index 4675def..ffdd2d1 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c @@ -811,6 +811,38 @@ static int srp_map_data(struct scsi_cmnd *scmnd, struct srp_target_port *target, return len; } +static int srp_post_recv(struct srp_target_port *target) +{ + unsigned long flags; + struct srp_iu *iu; + struct ib_sge list; + struct ib_recv_wr wr, *bad_wr; + unsigned int next; + int ret; + + spin_lock_irqsave(target->scsi_host->host_lock, flags); + + next = target->rx_head & (SRP_RQ_SIZE - 1); + wr.wr_id = next; + iu = target->rx_ring[next]; + + list.addr = iu->dma; + list.length = iu->size; + list.lkey = target->srp_host->srp_dev->mr->lkey; + + wr.next = NULL; + wr.sg_list = &list; + wr.num_sge = 1; + + ret = ib_post_recv(target->qp, &wr, &bad_wr); + if (!ret) + ++target->rx_head; + + spin_unlock_irqrestore(target->scsi_host->host_lock, flags); + + return ret; +} + static void srp_process_rsp(struct srp_target_port *target, struct srp_rsp *rsp) { struct srp_request *req; @@ -868,6 +900,7 @@ static void srp_handle_recv(struct srp_target_port *target, struct ib_wc *wc) { struct ib_device *dev; struct srp_iu *iu; + int res; u8 opcode; iu = target->rx_ring[wc->wr_id]; @@ -904,6 +937,11 @@ static void srp_handle_recv(struct srp_target_port *target, struct ib_wc *wc) ib_dma_sync_single_for_device(dev, iu->dma, target->max_ti_iu_len, DMA_FROM_DEVICE); + + res = srp_post_recv(target); + if (res != 0) + shost_printk(KERN_ERR, target->scsi_host, + PFX "Recv failed with error code %d\n", res); } static void srp_recv_completion(struct ib_cq *cq, void *target_ptr) @@ -943,45 +981,6 @@ static void srp_send_completion(struct ib_cq *cq, void *target_ptr) } } -static int __srp_post_recv(struct srp_target_port *target) -{ - struct srp_iu *iu; - struct ib_sge list; - struct ib_recv_wr wr, *bad_wr; - unsigned int next; - int ret; - - next = target->rx_head & (SRP_RQ_SIZE - 1); - wr.wr_id = next; - iu = target->rx_ring[next]; - - list.addr = iu->dma; - list.length = iu->size; - list.lkey = target->srp_host->srp_dev->mr->lkey; - - wr.next = NULL; - wr.sg_list = &list; - wr.num_sge = 1; - - ret = ib_post_recv(target->qp, &wr, &bad_wr); - if (!ret) - ++target->rx_head; - - return ret; -} - -static int srp_post_recv(struct srp_target_port *target) -{ - unsigned long flags; - int ret; - - spin_lock_irqsave(target->scsi_host->host_lock, flags); - ret = __srp_post_recv(target); - spin_unlock_irqrestore(target->scsi_host->host_lock, flags); - - return ret; -} - /* * Must be called with target->scsi_host->host_lock held to protect * req_lim and tx_head. Lock cannot be dropped between call here and @@ -1091,11 +1090,6 @@ static int srp_queuecommand(struct scsi_cmnd *scmnd, goto err; } - if (__srp_post_recv(target)) { - shost_printk(KERN_ERR, target->scsi_host, PFX "Recv failed\n"); - goto err_unmap; - } - ib_dma_sync_single_for_device(dev, iu->dma, srp_max_iu_len, DMA_TO_DEVICE); @@ -1238,6 +1232,7 @@ static int srp_cm_handler(struct ib_cm_id *cm_id, struct ib_cm_event *event) int attr_mask = 0; int comp = 0; int opcode = 0; + int i; switch (event->event) { case IB_CM_REQ_ERROR: @@ -1287,7 +1282,11 @@ static int srp_cm_handler(struct ib_cm_id *cm_id, struct ib_cm_event *event) if (target->status) break; - target->status = srp_post_recv(target); + for (i = 0; i < SRP_RQ_SIZE; i++) { + target->status = srp_post_recv(target); + if (target->status) + break; + } if (target->status) break;