From patchwork Mon Nov 9 21:33:43 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vu Pham X-Patchwork-Id: 58841 X-Patchwork-Delegate: dave@thedillows.org Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id nA9LXAAw026492 for ; Mon, 9 Nov 2009 21:33:46 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754806AbZKIVdk (ORCPT ); Mon, 9 Nov 2009 16:33:40 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1754820AbZKIVdk (ORCPT ); Mon, 9 Nov 2009 16:33:40 -0500 Received: from p02c11o145.mxlogic.net ([208.65.144.78]:52995 "EHLO p02c11o145.mxlogic.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754806AbZKIVdj (ORCPT ); Mon, 9 Nov 2009 16:33:39 -0500 Received: from unknown [63.251.237.3] (EHLO mtiexch01.mti.com) by p02c11o145.mxlogic.net(mxl_mta-6.4.0-2) with ESMTP id 7ba88fa4.0.37737.00-009.102741.p02c11o145.mxlogic.net (envelope-from ); Mon, 09 Nov 2009 14:33:45 -0700 (MST) X-MXL-Hash: 4af88ab92b1bff76-50d6ab8bca1a98257128c1d445eb8307ea3fe4a7 Received: from [10.2.1.145] ([10.2.1.145]) by mtiexch01.mti.com with Microsoft SMTPSVC(6.0.3790.3959); Mon, 9 Nov 2009 13:36:52 -0800 Message-ID: <4AF88AB7.30108@mellanox.com> Date: Mon, 09 Nov 2009 13:33:43 -0800 From: Vu Pham User-Agent: Thunderbird 2.0.0.23 (Windows/20090812) MIME-Version: 1.0 To: Linux RDMA list CC: Roland Dreier Subject: [linux-rdma][PATCH 4/6] SRP setup timer to propagate errors and clean up connection resources X-OriginalArrivalTime: 09 Nov 2009 21:36:52.0484 (UTC) FILETIME=[C0640C40:01CA6184] X-Spam: [F=0.2000000000; CM=0.500; S=0.200(2009110601)] X-MAIL-FROM: X-SOURCE-IP: [63.251.237.3] X-AnalysisOut: [v=1.0 c=1 a=_M7D_BTLUsgA:10 a=xupnbh4h0YLOHZnncC45HQ==:17 ] X-AnalysisOut: [a=CbDCq_QkAAAA:8 a=eK9ljTSZh1-STlL6an4A:9 a=UjqF_6fgXv9G92] X-AnalysisOut: [rvlZJ_PozMqBoA:4 a=E3yz0KKPV6YA:10 a=zNIGlxmyDZvp5ggeUNoA:] X-AnalysisOut: [9 a=9Jc4Ij15KPNrmNDcYmoA:7 a=i38aXDm9eYWjXe4ja__lJ-V2mOIA:] X-AnalysisOut: [4] Sender: linux-rdma-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-rdma@vger.kernel.org diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c index 047d488..3475a8b 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c @@ -435,6 +435,8 @@ static void srp_remove_work(struct work_struct *work) target->state = SRP_TARGET_REMOVED; spin_unlock_irq(target->scsi_host->host_lock); + del_timer_sync(&target->qp_err_timer); + spin_lock(&target->srp_host->target_lock); list_del(&target->list); spin_unlock(&target->srp_host->target_lock); @@ -896,6 +898,50 @@ static void srp_handle_recv(struct srp_target_port *target, struct ib_wc *wc) DMA_FROM_DEVICE); } +static void srp_reconnect_work(struct work_struct *work) +{ + struct srp_target_port *target = + container_of(work, struct srp_target_port, work); + + srp_reconnect_target(target); + spin_lock_irq(target->scsi_host->host_lock); + target->work_in_progress = 0; + spin_unlock_irq(target->scsi_host->host_lock); +} + +static void srp_qp_in_err_timer(unsigned long data) +{ + struct srp_target_port *target = (struct srp_target_port *)data; + struct srp_request *req, *tmp; + + if (target->state != SRP_TARGET_LIVE) + return; + + spin_lock_irq(target->scsi_host->host_lock); + list_for_each_entry_safe(req, tmp, &target->req_queue, list) + srp_reset_req(target, req); + spin_unlock_irq(target->scsi_host->host_lock); + + spin_lock_irq(target->scsi_host->host_lock); + if (!target->work_in_progress) { + target->work_in_progress = 1; + INIT_WORK(&target->work, srp_reconnect_work); + schedule_work(&target->work); + } + spin_unlock_irq(target->scsi_host->host_lock); +} + +static void srp_qp_err_add_timer(struct srp_target_port *target, int time) +{ + if (!timer_pending(&target->qp_err_timer)) { + setup_timer(&target->qp_err_timer, + srp_qp_in_err_timer, + (unsigned long)target); + target->qp_err_timer.expires = round_jiffies(time*HZ + jiffies); + add_timer(&target->qp_err_timer); + } +} + static void srp_completion(struct ib_cq *cq, void *target_ptr) { struct srp_target_port *target = target_ptr; @@ -1440,9 +1486,22 @@ static int srp_reset_device(struct scsi_cmnd *scmnd) static int srp_reset_host(struct scsi_cmnd *scmnd) { struct srp_target_port *target = host_to_target(scmnd->device->host); + struct srp_request *req, *tmp; int ret = FAILED; - shost_printk(KERN_ERR, target->scsi_host, PFX "SRP reset_host called\n"); + shost_printk(KERN_ERR, target->scsi_host, + PFX "SRP reset_host called state %d qp_err %d\n", + target->state, target->qp_in_error); + + spin_lock_irq(target->scsi_host->host_lock); + if (timer_pending(&target->qp_err_timer) || target->qp_in_error || + target->state != SRP_TARGET_LIVE) { + list_for_each_entry_safe(req, tmp, &target->req_queue, list) + srp_reset_req(target, req); + spin_unlock_irq(target->scsi_host->host_lock); + return SUCCESS; + } + spin_unlock_irq(target->scsi_host->host_lock); if (!srp_reconnect_target(target)) ret = SUCCESS; diff --git a/drivers/infiniband/ulp/srp/ib_srp.h b/drivers/infiniband/ulp/srp/ib_srp.h index 92db025..daa4bf7 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.h +++ b/drivers/infiniband/ulp/srp/ib_srp.h @@ -153,12 +153,14 @@ struct srp_target_port { struct srp_request req_ring[SRP_SQ_SIZE]; struct work_struct work; + int work_in_progress; struct list_head list; struct completion done; int status; enum srp_target_state state; int qp_in_error; + struct timer_list qp_err_timer; int device_loss_timeout; };