Received: by 2002:ac0:a582:0:0:0:0:0 with SMTP id m2-v6csp3728349imm; Mon, 8 Oct 2018 08:35:59 -0700 (PDT) X-Google-Smtp-Source: ACcGV62YQsm8kGg7gWzFdqdWiHKjHvKdcEKmXI0gHTG4rSC57hTvJrFKGYX8m3GiDivKnc0aG4AG X-Received: by 2002:a17:902:ba95:: with SMTP id k21-v6mr24586455pls.38.1539012959801; Mon, 08 Oct 2018 08:35:59 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1539012959; cv=none; d=google.com; s=arc-20160816; b=jabctjwSVr2ZedJjs/Pc+bfzoGrr/6Vvo1pNFOZdOgz8Q3oOjc+txEyGq9pmg5ypY2 W6QPGbc8ou5yg06GR7+4Tkb/7fp6CCdXAJcENdbp0tc8d9KJBQKxH4rDfUFaNm9+ndfC hkeX/4906Ld1xabem4mKY0jULwr8BEr8GcYbWOLwMtXiR3FE9Ee4URLI/sbwS20FXyAI BsrafCWuHKKR0RlJjwVa3HtPXISRkm+1zUvkO5h3ubux29OQfcX4qXoejsytisXTxEXO KQ2SEGrwlfM13HX5swofpbOhC2Z3XFIxoVxBBzNEzG60vkgY7qVCeEFrvxyLlMtMm87k Q4EA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature; bh=CutNT+9UvFdQfZ0SH5/Yeir8s1pEeAOPmIhWdBiNPiU=; b=et8OtKtUFoFJ1sw2iVkD5FlezIJSZhAzCmUQ4nzDCXQtdHu5HgTl4fS/1YA9WA2zHu 4GhMZTEWkxNMZUskXan/pX34peuHd7BbwDdstBT9488SYEHrcacpi9DC7ZY+M6s9z1WL qcGdxDZ4CWTtyvEJ0HGpEgH6gzWciWEWftGYQGWaB88H8N85YlkJ8mNpFlT3BmV7C2wf djnqIYMRBIkERynrFhDBaiD4Icl90oQLhxoHkIQiZMQLB7pHuZEC3nykQrUp3LyT7lcS ezHmJKgttM/qIS+7wYeDkPUYNzgP1tZ7KPUGL1y8OpfUqq+eJsCFufX8ad+19jAiBXOd SS4A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=BtTp9rk1; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id y62-v6si19329592pfy.139.2018.10.08.08.35.44; Mon, 08 Oct 2018 08:35:59 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=BtTp9rk1; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727841AbeJHWiX (ORCPT + 99 others); Mon, 8 Oct 2018 18:38:23 -0400 Received: from mail.kernel.org ([198.145.29.99]:56816 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727723AbeJHWiW (ORCPT ); Mon, 8 Oct 2018 18:38:22 -0400 Received: from sasha-vm.mshome.net (c-73-47-72-35.hsd1.nh.comcast.net [73.47.72.35]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 52ED321479; Mon, 8 Oct 2018 15:26:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1539012366; bh=dhi4mQeVPz01spRzxLrxlT+I0KMXfnEvTjmSI/Uixk8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=BtTp9rk1MhciweE+hSm3UZ05tZfPhmuXer4SUZN+aqjN2SbuqExaAyAraFFsIkPOI Gj8SfI9Zeg33frhGKbt0p4AaOqzLF4TGV/MQUkXjspFPLWe8BK5TRem3M+bbs7RGkG Y3IkdxDGfHQGO6Lu6lJfAs6As0Tju2B6fvcjCmsQ= From: Sasha Levin To: stable@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Wen Xiong , "Martin K . Petersen" , Sasha Levin Subject: [PATCH AUTOSEL 4.18 42/58] scsi: ipr: System hung while dlpar adding primary ipr adapter back Date: Mon, 8 Oct 2018 11:25:07 -0400 Message-Id: <20181008152523.70705-42-sashal@kernel.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181008152523.70705-1-sashal@kernel.org> References: <20181008152523.70705-1-sashal@kernel.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Wen Xiong [ Upstream commit 318ddb34b2052f838aa243d07173e2badf3e630e ] While dlpar adding primary ipr adapter back, driver goes through adapter initialization then schedule ipr_worker_thread to start te disk scan by dropping the host lock, calling scsi_add_device. Then get the adapter reset request again, so driver does scsi_block_requests, this will cause the scsi_add_device get hung until we unblock. But we can't run ipr_worker_thread to do the unblock because its stuck in scsi_add_device. This patch fixes the issue. [mkp: typo and whitespace fixes] Signed-off-by: Wen Xiong Acked-by: Brian King Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin --- drivers/scsi/ipr.c | 106 ++++++++++++++++++++++++++------------------- drivers/scsi/ipr.h | 1 + 2 files changed, 62 insertions(+), 45 deletions(-) diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index 02d65dce74e5..2e8a91341254 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -3310,6 +3310,65 @@ static void ipr_release_dump(struct kref *kref) LEAVE; } +static void ipr_add_remove_thread(struct work_struct *work) +{ + unsigned long lock_flags; + struct ipr_resource_entry *res; + struct scsi_device *sdev; + struct ipr_ioa_cfg *ioa_cfg = + container_of(work, struct ipr_ioa_cfg, scsi_add_work_q); + u8 bus, target, lun; + int did_work; + + ENTER; + spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); + +restart: + do { + did_work = 0; + if (!ioa_cfg->hrrq[IPR_INIT_HRRQ].allow_cmds) { + spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + return; + } + + list_for_each_entry(res, &ioa_cfg->used_res_q, queue) { + if (res->del_from_ml && res->sdev) { + did_work = 1; + sdev = res->sdev; + if (!scsi_device_get(sdev)) { + if (!res->add_to_ml) + list_move_tail(&res->queue, &ioa_cfg->free_res_q); + else + res->del_from_ml = 0; + spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + scsi_remove_device(sdev); + scsi_device_put(sdev); + spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); + } + break; + } + } + } while (did_work); + + list_for_each_entry(res, &ioa_cfg->used_res_q, queue) { + if (res->add_to_ml) { + bus = res->bus; + target = res->target; + lun = res->lun; + res->add_to_ml = 0; + spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + scsi_add_device(ioa_cfg->host, bus, target, lun); + spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); + goto restart; + } + } + + ioa_cfg->scan_done = 1; + spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + kobject_uevent(&ioa_cfg->host->shost_dev.kobj, KOBJ_CHANGE); + LEAVE; +} + /** * ipr_worker_thread - Worker thread * @work: ioa config struct @@ -3324,13 +3383,9 @@ static void ipr_release_dump(struct kref *kref) static void ipr_worker_thread(struct work_struct *work) { unsigned long lock_flags; - struct ipr_resource_entry *res; - struct scsi_device *sdev; struct ipr_dump *dump; struct ipr_ioa_cfg *ioa_cfg = container_of(work, struct ipr_ioa_cfg, work_q); - u8 bus, target, lun; - int did_work; ENTER; spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); @@ -3368,49 +3423,9 @@ static void ipr_worker_thread(struct work_struct *work) return; } -restart: - do { - did_work = 0; - if (!ioa_cfg->hrrq[IPR_INIT_HRRQ].allow_cmds) { - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); - return; - } + schedule_work(&ioa_cfg->scsi_add_work_q); - list_for_each_entry(res, &ioa_cfg->used_res_q, queue) { - if (res->del_from_ml && res->sdev) { - did_work = 1; - sdev = res->sdev; - if (!scsi_device_get(sdev)) { - if (!res->add_to_ml) - list_move_tail(&res->queue, &ioa_cfg->free_res_q); - else - res->del_from_ml = 0; - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); - scsi_remove_device(sdev); - scsi_device_put(sdev); - spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); - } - break; - } - } - } while (did_work); - - list_for_each_entry(res, &ioa_cfg->used_res_q, queue) { - if (res->add_to_ml) { - bus = res->bus; - target = res->target; - lun = res->lun; - res->add_to_ml = 0; - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); - scsi_add_device(ioa_cfg->host, bus, target, lun); - spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); - goto restart; - } - } - - ioa_cfg->scan_done = 1; spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); - kobject_uevent(&ioa_cfg->host->shost_dev.kobj, KOBJ_CHANGE); LEAVE; } @@ -9908,6 +9923,7 @@ static void ipr_init_ioa_cfg(struct ipr_ioa_cfg *ioa_cfg, INIT_LIST_HEAD(&ioa_cfg->free_res_q); INIT_LIST_HEAD(&ioa_cfg->used_res_q); INIT_WORK(&ioa_cfg->work_q, ipr_worker_thread); + INIT_WORK(&ioa_cfg->scsi_add_work_q, ipr_add_remove_thread); init_waitqueue_head(&ioa_cfg->reset_wait_q); init_waitqueue_head(&ioa_cfg->msi_wait_q); init_waitqueue_head(&ioa_cfg->eeh_wait_q); diff --git a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h index 93570734cbfb..a98cfd24035a 100644 --- a/drivers/scsi/ipr.h +++ b/drivers/scsi/ipr.h @@ -1568,6 +1568,7 @@ struct ipr_ioa_cfg { u8 saved_mode_page_len; struct work_struct work_q; + struct work_struct scsi_add_work_q; struct workqueue_struct *reset_work_q; wait_queue_head_t reset_wait_q; -- 2.17.1