From patchwork Fri Apr 13 23:37:27 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dan Williams X-Patchwork-Id: 152444 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id C9A82B7012 for ; Sat, 14 Apr 2012 09:21:49 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932454Ab2DMXVs (ORCPT ); Fri, 13 Apr 2012 19:21:48 -0400 Received: from mga11.intel.com ([192.55.52.93]:24697 "EHLO mga11.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932433Ab2DMXVr (ORCPT ); Fri, 13 Apr 2012 19:21:47 -0400 Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga102.fm.intel.com with ESMTP; 13 Apr 2012 16:21:46 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.71,315,1320652800"; d="scan'208";a="153440613" Received: from dwillia2-linux.jf.intel.com ([10.23.45.110]) by fmsmga002.fm.intel.com with ESMTP; 13 Apr 2012 16:21:46 -0700 Received: from dwillia2-linux.jf.intel.com (localhost.localdomain [IPv6:::1]) by dwillia2-linux.jf.intel.com (Postfix) with ESMTP id 54CB180005; Fri, 13 Apr 2012 16:37:27 -0700 (PDT) Subject: [PATCH 07/12] libsas: fix ata_eh clobbering ex_phys via smp_ata_check_ready To: JBottomley@parallels.com From: Dan Williams Cc: Maciej Patelczyk , linux-scsi@vger.kernel.org, Jacek Danecki , Jack Wang , linux-ide@vger.kernel.org, Bartek Nowakowski Date: Fri, 13 Apr 2012 16:37:27 -0700 Message-ID: <20120413233727.8025.82428.stgit@dwillia2-linux.jf.intel.com> In-Reply-To: <20120413233343.8025.18101.stgit@dwillia2-linux.jf.intel.com> References: <20120413233343.8025.18101.stgit@dwillia2-linux.jf.intel.com> User-Agent: StGit/0.16-1-g7004 MIME-Version: 1.0 Sender: linux-ide-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-ide@vger.kernel.org The check_ready implementation in the expander-attached ata device case polls on sas_ex_phy_discover(). The effect is that the ex_phy fields (critically ->attached_sas_addr) can change. When ata_eh ends and libsas comes along to revalidate the domain sas_unregister_devs_sas_addr() can fail to lookup devices to remove, or fail to re-add an ata device that ata_eh marked as disabled. So change the code to skip the sas_address and change count updates when ata_eh is active. Cc: Jack Wang Tested-by: Maciej Patelczyk Tested-by: Bartek Nowakowski Tested-by: Jacek Danecki Signed-off-by: Dan Williams --- drivers/scsi/libsas/sas_expander.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) -- To unsubscribe from this list: send the line "unsubscribe linux-ide" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c index 37c3c3f..c1f91b1 100644 --- a/drivers/scsi/libsas/sas_expander.c +++ b/drivers/scsi/libsas/sas_expander.c @@ -202,6 +202,7 @@ static void sas_set_ex_phy(struct domain_device *dev, int phy_id, void *rsp) u8 sas_addr[SAS_ADDR_SIZE]; struct smp_resp *resp = rsp; struct discover_resp *dr = &resp->disc; + struct sas_ha_struct *ha = dev->port->ha; struct expander_device *ex = &dev->ex_dev; struct ex_phy *phy = &ex->ex_phy[phy_id]; struct sas_rphy *rphy = dev->rphy; @@ -209,6 +210,8 @@ static void sas_set_ex_phy(struct domain_device *dev, int phy_id, void *rsp) char *type; if (new_phy) { + if (WARN_ON_ONCE(test_bit(SAS_HA_ATA_EH_ACTIVE, &ha->state))) + return; phy->phy = sas_phy_alloc(&rphy->dev, phy_id); /* FIXME: error_handling */ @@ -233,6 +236,8 @@ static void sas_set_ex_phy(struct domain_device *dev, int phy_id, void *rsp) memcpy(sas_addr, phy->attached_sas_addr, SAS_ADDR_SIZE); phy->attached_dev_type = to_dev_type(dr); + if (test_bit(SAS_HA_ATA_EH_ACTIVE, &ha->state)) + goto out; phy->phy_id = phy_id; phy->linkrate = dr->linkrate; phy->attached_sata_host = dr->attached_sata_host; @@ -266,6 +271,7 @@ static void sas_set_ex_phy(struct domain_device *dev, int phy_id, void *rsp) return; } + out: switch (phy->attached_dev_type) { case SATA_PENDING: type = "stp pending"; @@ -304,7 +310,15 @@ static void sas_set_ex_phy(struct domain_device *dev, int phy_id, void *rsp) else return; - SAS_DPRINTK("ex %016llx phy%02d:%c:%X attached: %016llx (%s)\n", + /* if the attached device type changed and ata_eh is active, + * make sure we run revalidation when eh completes (see: + * sas_enable_revalidation) + */ + if (test_bit(SAS_HA_ATA_EH_ACTIVE, &ha->state)) + set_bit(DISCE_REVALIDATE_DOMAIN, &dev->port->disc.pending); + + SAS_DPRINTK("%sex %016llx phy%02d:%c:%X attached: %016llx (%s)\n", + test_bit(SAS_HA_ATA_EH_ACTIVE, &ha->state) ? "ata: " : "", SAS_ADDR(dev->sas_addr), phy->phy_id, sas_route_char(dev, phy), phy->linkrate, SAS_ADDR(phy->attached_sas_addr), type);