From nobody Mon Apr 6 10:43:20 2026 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8690F3093AE for ; Thu, 19 Mar 2026 14:12:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773929540; cv=none; b=uselZkfCmB5aIGZXdSclld8ykxm9OorPKvS5SmNfjnK27yq4bLZz9Zf/2cKiV8DWp8dR948xtvstY0eJPA4cHutwiUuJ1Or+K6Z50FXubYdNbUnNhE8BaBssjnCCDY7owckA3zc9EZvQ1ON+Y3uYnrrDeoDi8xL7+VYbqp/tr5s= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773929540; c=relaxed/simple; bh=voqLIQV9QeuwZ5uTWkNIFl3G2KPd+oc1BJzkugN4JvU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=dGdXvMACnhpgM7rIsUTZ4U4xGH126So8VWMV4eDbuQ6xQXDlGcpI8W4kWIWU3Qd3vYtFguN82w/FjQtu6jUIu9UMvdQeCgDoq8ETo4lxJ2C1IwBgi0Pvk8Qa6ya5fiOY0ELXjHkOXJ4Jvh2WeuE9sPTwaqEUZTLxFWNL5AzCYMU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=MMjYDdrO; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="MMjYDdrO" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1773929536; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=PLOIg+t5Qh2zTANNzcOlodqXLFFqshsYIl+fB71vt6Q=; b=MMjYDdrOr9E3MuEOXFkGIlWCBd6cN/jmrxWIa93viKS2a14LYloaTDfqWaApBKaeIbbwyD N2lI44HCKKcP1D2Fm7wx93nMQAjUFNehNRTbVVGFlxN1AjMWNg/g7NRFwq3tKORa74L936 DEKdxjyW2GLoFbWCJMGvqVxP5+ixgtg= Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-356-NvJ5g7KRNRKfWe_5_Dyczw-1; Thu, 19 Mar 2026 10:12:12 -0400 X-MC-Unique: NvJ5g7KRNRKfWe_5_Dyczw-1 X-Mimecast-MFC-AGG-ID: NvJ5g7KRNRKfWe_5_Dyczw_1773929526 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 98E5118005BF; Thu, 19 Mar 2026 14:12:06 +0000 (UTC) Received: from fedora-work.redhat.com (unknown [10.22.66.24]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 42542180035F; Thu, 19 Mar 2026 14:12:02 +0000 (UTC) From: David Jeffery To: linux-kernel@vger.kernel.org, driver-core@lists.linux.dev, linux-pci@vger.kernel.org, linux-scsi@vger.kernel.org, Greg Kroah-Hartman , "Rafael J. Wysocki" , Danilo Krummrich Cc: Tarun Sahu , Pasha Tatashin , =?UTF-8?q?Micha=C5=82=20C=C5=82api=C5=84ski?= , Jordan Richards , Ewan Milne , John Meneghini , "Lombardi, Maurizio" , Stuart Hayes , Laurence Oberman , Bart Van Assche , Bjorn Helgaas , David Jeffery Subject: [PATCH 1/5] driver core: separate function to shutdown one device Date: Thu, 19 Mar 2026 10:11:38 -0400 Message-ID: <20260319141142.5781-2-djeffery@redhat.com> In-Reply-To: <20260319141142.5781-1-djeffery@redhat.com> References: <20260319141142.5781-1-djeffery@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 Content-Type: text/plain; charset="utf-8" Make a separate function for the part of device_shutdown() that does the shutown for a single device. This is in preparation for making device shutdown asynchronous. Signed-off-by: Stuart Hayes Signed-off-by: David Jeffery Tested-by: Laurence Oberman --- drivers/base/core.c | 71 +++++++++++++++++++++++++-------------------- 1 file changed, 39 insertions(+), 32 deletions(-) diff --git a/drivers/base/core.c b/drivers/base/core.c index 791f9e444df8..10586298e18b 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -4782,12 +4782,48 @@ int device_change_owner(struct device *dev, kuid_t = kuid, kgid_t kgid) return error; } =20 +static void shutdown_one_device(struct device *dev) +{ + struct device *parent =3D dev->parent; + + /* hold lock to avoid race with probe/release */ + if (parent) + device_lock(parent); + device_lock(dev); + + /* Don't allow any more runtime suspends */ + pm_runtime_get_noresume(dev); + pm_runtime_barrier(dev); + + if (dev->class && dev->class->shutdown_pre) { + if (initcall_debug) + dev_info(dev, "shutdown_pre\n"); + dev->class->shutdown_pre(dev); + } + if (dev->bus && dev->bus->shutdown) { + if (initcall_debug) + dev_info(dev, "shutdown\n"); + dev->bus->shutdown(dev); + } else if (dev->driver && dev->driver->shutdown) { + if (initcall_debug) + dev_info(dev, "shutdown\n"); + dev->driver->shutdown(dev); + } + + device_unlock(dev); + if (parent) + device_unlock(parent); + + put_device(parent); + put_device(dev); +} + /** * device_shutdown - call ->shutdown() on each device to shutdown. */ void device_shutdown(void) { - struct device *dev, *parent; + struct device *dev; =20 wait_for_device_probe(); device_block_probing(); @@ -4809,7 +4845,7 @@ void device_shutdown(void) * prevent it from being freed because parent's * lock is to be held */ - parent =3D get_device(dev->parent); + get_device(dev->parent); get_device(dev); /* * Make sure the device is off the kset list, in the @@ -4818,36 +4854,7 @@ void device_shutdown(void) list_del_init(&dev->kobj.entry); spin_unlock(&devices_kset->list_lock); =20 - /* hold lock to avoid race with probe/release */ - if (parent) - device_lock(parent); - device_lock(dev); - - /* Don't allow any more runtime suspends */ - pm_runtime_get_noresume(dev); - pm_runtime_barrier(dev); - - if (dev->class && dev->class->shutdown_pre) { - if (initcall_debug) - dev_info(dev, "shutdown_pre\n"); - dev->class->shutdown_pre(dev); - } - if (dev->bus && dev->bus->shutdown) { - if (initcall_debug) - dev_info(dev, "shutdown\n"); - dev->bus->shutdown(dev); - } else if (dev->driver && dev->driver->shutdown) { - if (initcall_debug) - dev_info(dev, "shutdown\n"); - dev->driver->shutdown(dev); - } - - device_unlock(dev); - if (parent) - device_unlock(parent); - - put_device(dev); - put_device(parent); + shutdown_one_device(dev); =20 spin_lock(&devices_kset->list_lock); } --=20 2.53.0 From nobody Mon Apr 6 10:43:20 2026 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3AF19305064 for ; Thu, 19 Mar 2026 14:12:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773929541; cv=none; b=SVTx3TBEdy+aQ6zPef8vXqjQG2sDBxHuSL1aZUV9wsLPiC8X0wGU2sL36Opjhva8sARsd/6XzI0Up9E1ip3g5qDMdF5YEvr0H2KcKVOPliKkL/Q4PkowLeTMyf5hbrly4b6V4kR6v0AWNGdqrVb9Rx5L5j6KNJL0sWjuNUvVLgI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773929541; c=relaxed/simple; bh=IfyjG0oQAceFxDXb4D6xoWuus9aQ/LmlQ+KniKVfTBk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=HacuqdKjSU+JqLadH/wCf3OAaKntUXxnsGsJPC18ZU5iFV5WPee9lARctzta34sIMx+dXWhhsyGzjHozUuXUgidJMOYrelNl2jZySFa69aofBOwwcSilEtrj1ODat7pl9YJO8KwAY9qTFcY79NoJUxkNHTufcnkLkFy/ysvTxTY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=Ycv+Me3+; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="Ycv+Me3+" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1773929538; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=f9patlQbuB55/bJm1JsV9uGRmDphoePFBzZFkCXjCLA=; b=Ycv+Me3+abpJnhNysk5we44Ok+z41MzJtJO0o0LF1ObnHMlAB+xQnl8ESOtArXoFVXAkql Ry6pUy97/HuxDtfIqicF2XW2+m8FXU6yNBCKEKELovMOwCqa4OnDsiqbyWe2QLxczPbBtm xcI1jy384ExnZ82LZ1vmKNbiSvds7fg= Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-203-rWK4Yi85M2a3SwDFL_sLtg-1; Thu, 19 Mar 2026 10:12:14 -0400 X-MC-Unique: rWK4Yi85M2a3SwDFL_sLtg-1 X-Mimecast-MFC-AGG-ID: rWK4Yi85M2a3SwDFL_sLtg_1773929531 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 787B71800625; Thu, 19 Mar 2026 14:12:11 +0000 (UTC) Received: from fedora-work.redhat.com (unknown [10.22.66.24]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 07C2F180035F; Thu, 19 Mar 2026 14:12:06 +0000 (UTC) From: David Jeffery To: linux-kernel@vger.kernel.org, driver-core@lists.linux.dev, linux-pci@vger.kernel.org, linux-scsi@vger.kernel.org, Greg Kroah-Hartman , "Rafael J. Wysocki" , Danilo Krummrich Cc: Tarun Sahu , Pasha Tatashin , =?UTF-8?q?Micha=C5=82=20C=C5=82api=C5=84ski?= , Jordan Richards , Ewan Milne , John Meneghini , "Lombardi, Maurizio" , Stuart Hayes , Laurence Oberman , Bart Van Assche , Bjorn Helgaas , David Jeffery Subject: [PATCH 2/5] driver core: do not always lock parent in shutdown Date: Thu, 19 Mar 2026 10:11:39 -0400 Message-ID: <20260319141142.5781-3-djeffery@redhat.com> In-Reply-To: <20260319141142.5781-1-djeffery@redhat.com> References: <20260319141142.5781-1-djeffery@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 Content-Type: text/plain; charset="utf-8" Don't lock a parent device unless it is needed in device_shutdown. This is in preparation for making device shutdown asynchronous, when it will be needed to allow children of a common parent to shut down simultaneously. Signed-off-by: Stuart Hayes Signed-off-by: David Jeffery Tested-by: Laurence Oberman --- drivers/base/core.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/drivers/base/core.c b/drivers/base/core.c index 10586298e18b..2e9094f5c5aa 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -4782,13 +4782,8 @@ int device_change_owner(struct device *dev, kuid_t k= uid, kgid_t kgid) return error; } =20 -static void shutdown_one_device(struct device *dev) +static void __shutdown_one_device(struct device *dev) { - struct device *parent =3D dev->parent; - - /* hold lock to avoid race with probe/release */ - if (parent) - device_lock(parent); device_lock(dev); =20 /* Don't allow any more runtime suspends */ @@ -4811,10 +4806,20 @@ static void shutdown_one_device(struct device *dev) } =20 device_unlock(dev); - if (parent) - device_unlock(parent); +} =20 - put_device(parent); +static void shutdown_one_device(struct device *dev) +{ + /* hold lock to avoid race with probe/release */ + if (dev->parent && dev->bus && dev->bus->need_parent_lock) { + device_lock(dev->parent); + __shutdown_one_device(dev); + device_unlock(dev->parent); + } else { + __shutdown_one_device(dev); + } + + put_device(dev->parent); put_device(dev); } =20 --=20 2.53.0 From nobody Mon Apr 6 10:43:20 2026 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A7DD8317171 for ; Thu, 19 Mar 2026 14:12:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773929564; cv=none; b=aCycakxJarmv8KI9JE010MBgAwGY4BD5NqMBp/Sd/FBWfPuxgxXxLJFS7xKtjBkOfHMlN6JprfBc5c63oNGXq78nt3USKwCXcc68JJaUjl+kFQz6jcBGn9awTG84z5bu3tUYveXPiWi5VFaivKpeHwVFU31UIw2GDj9hu51ebvM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773929564; c=relaxed/simple; bh=6mSehbpF+RItZ1Q8Et60jCpZ0rREFfenJveoiK1gS60=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=LYFPhc1YgZmTh0Fl3WINshWWbfmPv9BTS+8TocVn4cRTgQx1jlP9HtmJ0ivzdqvmp4IucZbVdzTeX5iKMRWYgKpCfcE/01WBE81GOpefahsZJHn6zcc7td25HcaPB6ajQsjeq6wvDaucQw0V+OadHZAu7/9nQ/VeILlbrGQEww0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=RikB2As1; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="RikB2As1" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1773929558; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=OQ5/Jf7lfLb4nnTLYmHQMRrsCz1ABsjpH0OOeVo4OKY=; b=RikB2As18LG++aZ5CV5PrzffqTMEAZ3NKbe4R9aixfcKXMv9TKB6jI2dpol0B2Gea6QRik ZNcHpyX/qunr+NcsWxpBjV6kxUd2JJ7bsv0gNZiNskGq7c/xo1RdZSlIzqIg1A9Tskiz4g 9x6zYeuHVfb1iOgcKflG6Xc/EzHqloY= Received: from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-593-pzCk9WJuMxOC6OKCAGtQGg-1; Thu, 19 Mar 2026 10:12:35 -0400 X-MC-Unique: pzCk9WJuMxOC6OKCAGtQGg-1 X-Mimecast-MFC-AGG-ID: pzCk9WJuMxOC6OKCAGtQGg_1773929536 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id ECAF019560A7; Thu, 19 Mar 2026 14:12:15 +0000 (UTC) Received: from fedora-work.redhat.com (unknown [10.22.66.24]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id BFC771800576; Thu, 19 Mar 2026 14:12:11 +0000 (UTC) From: David Jeffery To: linux-kernel@vger.kernel.org, driver-core@lists.linux.dev, linux-pci@vger.kernel.org, linux-scsi@vger.kernel.org, Greg Kroah-Hartman , "Rafael J. Wysocki" , Danilo Krummrich Cc: Tarun Sahu , Pasha Tatashin , =?UTF-8?q?Micha=C5=82=20C=C5=82api=C5=84ski?= , Jordan Richards , Ewan Milne , John Meneghini , "Lombardi, Maurizio" , Stuart Hayes , Laurence Oberman , Bart Van Assche , Bjorn Helgaas , David Jeffery Subject: [PATCH 3/5] driver core: async device shutdown infrastructure Date: Thu, 19 Mar 2026 10:11:40 -0400 Message-ID: <20260319141142.5781-4-djeffery@redhat.com> In-Reply-To: <20260319141142.5781-1-djeffery@redhat.com> References: <20260319141142.5781-1-djeffery@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 Content-Type: text/plain; charset="utf-8" Patterned after async suspend, allow devices to mark themselves as wanting to perform async shutdown. Devices using async shutdown wait only for their dependencies to shutdown before executing their shutdown routine. Sync shutdown devices are shut down one at a time and will only wait for an async shutdown device if the async device is a dependency. Signed-off-by: David Jeffery Signed-off-by: Stuart Hayes Tested-by: Laurence Oberman --- drivers/base/base.h | 2 + drivers/base/core.c | 104 ++++++++++++++++++++++++++++++++++++++++- include/linux/device.h | 13 ++++++ 3 files changed, 118 insertions(+), 1 deletion(-) diff --git a/drivers/base/base.h b/drivers/base/base.h index 79d031d2d845..ea2a039e7907 100644 --- a/drivers/base/base.h +++ b/drivers/base/base.h @@ -113,6 +113,7 @@ struct driver_type { * @device - pointer back to the struct device that this structure is * associated with. * @driver_type - The type of the bound Rust driver. + * @complete - completion for device shutdown ordering * @dead - This device is currently either in the process of or has been * removed from the system. Any asynchronous events scheduled for this * device should exit without taking any action. @@ -132,6 +133,7 @@ struct device_private { #ifdef CONFIG_RUST struct driver_type driver_type; #endif + struct completion complete; u8 dead:1; }; #define to_device_private_parent(obj) \ diff --git a/drivers/base/core.c b/drivers/base/core.c index 2e9094f5c5aa..53568b820a13 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -9,6 +9,7 @@ */ =20 #include +#include #include #include #include @@ -37,6 +38,10 @@ #include "physical_location.h" #include "power/power.h" =20 +static bool async_shutdown =3D true; +module_param(async_shutdown, bool, 0644); +MODULE_PARM_DESC(async_shutdown, "Enable asynchronous device shutdown supp= ort"); + /* Device links support. */ static LIST_HEAD(deferred_sync); static unsigned int defer_sync_state_count =3D 1; @@ -3538,6 +3543,7 @@ static int device_private_init(struct device *dev) klist_init(&dev->p->klist_children, klist_children_get, klist_children_put); INIT_LIST_HEAD(&dev->p->deferred_probe); + init_completion(&dev->p->complete); return 0; } =20 @@ -4782,6 +4788,37 @@ int device_change_owner(struct device *dev, kuid_t k= uid, kgid_t kgid) return error; } =20 +static bool wants_async_shutdown(struct device *dev) +{ + return async_shutdown && dev->async_shutdown; +} + +static int wait_for_device_shutdown(struct device *dev, void *data) +{ + bool async =3D *(bool *)data; + + if (async || wants_async_shutdown(dev)) + wait_for_completion(&dev->p->complete); + + return 0; +} + +static void wait_for_shutdown_dependencies(struct device *dev, bool async) +{ + struct device_link *link; + int idx; + + device_for_each_child(dev, &async, wait_for_device_shutdown); + + idx =3D device_links_read_lock(); + + dev_for_each_link_to_consumer(link, dev) + if (!device_link_flag_is_sync_state_only(link->flags)) + wait_for_device_shutdown(link->consumer, &async); + + device_links_read_unlock(idx); +} + static void __shutdown_one_device(struct device *dev) { device_lock(dev); @@ -4805,6 +4842,8 @@ static void __shutdown_one_device(struct device *dev) dev->driver->shutdown(dev); } =20 + complete_all(&dev->p->complete); + device_unlock(dev); } =20 @@ -4823,6 +4862,58 @@ static void shutdown_one_device(struct device *dev) put_device(dev); } =20 +static void async_shutdown_handler(void *data, async_cookie_t cookie) +{ + struct device *dev =3D data; + + wait_for_shutdown_dependencies(dev, true); + shutdown_one_device(dev); +} + +static bool shutdown_device_async(struct device *dev) +{ + if (async_schedule_dev_nocall(async_shutdown_handler, dev)) + return true; + return false; +} + + +static void early_async_shutdown_devices(void) +{ + struct device *dev, *next, *needs_put =3D NULL; + + if (!async_shutdown) + return; + + spin_lock(&devices_kset->list_lock); + + list_for_each_entry_safe_reverse(dev, next, &devices_kset->list, + kobj.entry) { + if (wants_async_shutdown(dev)) { + get_device(dev->parent); + get_device(dev); + + if (shutdown_device_async(dev)) { + list_del_init(&dev->kobj.entry); + } else { + /* + * async failed, clean up extra references + * and run from the standard shutdown loop + */ + needs_put =3D dev; + break; + } + } + } + + spin_unlock(&devices_kset->list_lock); + + if (needs_put) { + put_device(needs_put->parent); + put_device(needs_put); + } +} + /** * device_shutdown - call ->shutdown() on each device to shutdown. */ @@ -4835,6 +4926,12 @@ void device_shutdown(void) =20 cpufreq_suspend(); =20 + /* + * Start async device threads where possible to maximize potential + * parallelism and minimize false dependency on unrelated sync devices + */ + early_async_shutdown_devices(); + spin_lock(&devices_kset->list_lock); /* * Walk the devices list backward, shutting down each in turn. @@ -4859,11 +4956,16 @@ void device_shutdown(void) list_del_init(&dev->kobj.entry); spin_unlock(&devices_kset->list_lock); =20 - shutdown_one_device(dev); + if (!wants_async_shutdown(dev) || !shutdown_device_async(dev)) { + wait_for_shutdown_dependencies(dev, false); + shutdown_one_device(dev); + } =20 spin_lock(&devices_kset->list_lock); } spin_unlock(&devices_kset->list_lock); + + async_synchronize_full(); } =20 /* diff --git a/include/linux/device.h b/include/linux/device.h index 0be95294b6e6..da1db7d235c9 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -551,6 +551,8 @@ struct device_physical_location { * @dma_skip_sync: DMA sync operations can be skipped for coherent buffers. * @dma_iommu: Device is using default IOMMU implementation for DMA and * doesn't rely on dma_ops structure. + * @async_shutdown: Device shutdown may be run asynchronously and in paral= lel + * to the shutdown of unrelated devices * * At the lowest level, every device in a Linux system is represented by an * instance of struct device. The device structure contains the information @@ -669,6 +671,7 @@ struct device { #ifdef CONFIG_IOMMU_DMA bool dma_iommu:1; #endif + bool async_shutdown:1; }; =20 /** @@ -824,6 +827,16 @@ static inline bool device_async_suspend_enabled(struct= device *dev) return !!dev->power.async_suspend; } =20 +static inline bool device_enable_async_shutdown(struct device *dev) +{ + return dev->async_shutdown =3D true; +} + +static inline bool device_async_shutdown_enabled(struct device *dev) +{ + return !!dev->async_shutdown; +} + static inline bool device_pm_not_required(struct device *dev) { return dev->power.no_pm; --=20 2.53.0 From nobody Mon Apr 6 10:43:20 2026 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A0AB9303CAB for ; Thu, 19 Mar 2026 14:12:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773929554; cv=none; b=TT6NKayUYq9bqs9sf4zy4YtKKdF8O8c1StXnODLH6YvZlOn4lVAoIc+qkwIuA52etSL1hG5IS4RPYIUAgPB/5XuKZ0TGEHPHj63T7PgFjPOBtNKzIy2ADt45VScqbgClkxVza4zOD4gT90j2X1jQNIEVrgasF8lueSFR8Qq7zWw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773929554; c=relaxed/simple; bh=4vvr+xDrAWxMxjnNh4nkvtXpBMA19u1S8MdxP1fEm4s=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Nlu7ZtMMTnkR+zjHJi5tZNZENsN+EGVqT6XdIMiMXKxSjGWK0cjuXeCGhC8DvabTGvs49I536+Qx+8WBJB7nU0glWoP/JIlr+0O9MLXmuJEgS4Z8Ftq8oI3LSxR4FuzxaxIFlrayFaZzhWycwLKF3qNEdTQIK+UMNHCDFmF/HzQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=g73bbAln; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="g73bbAln" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1773929552; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=jQvaSb3MuBGeMbb7vK8Mg571zM++WUT9vxPRh2XvaDA=; b=g73bbAlntF9o0D32173A5UzD8PbA82TRzdkHgRHTOG010trfvzYNa40H086NQO7nTKkfWM cq7VodJ6pQLSbVnXXUjl7jHUPPhWjMMPyvdZ8vnmfQ4MDL76aV6tilYDDiQ2X0NNhZNr25 4BnDGMdtkLWNaQQUS81sjL9r+8J3oKI= Received: from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-554-ih4dCwmYM1mBXk6becXcqQ-1; Thu, 19 Mar 2026 10:12:29 -0400 X-MC-Unique: ih4dCwmYM1mBXk6becXcqQ-1 X-Mimecast-MFC-AGG-ID: ih4dCwmYM1mBXk6becXcqQ_1773929540 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 7C5AF1954B17; Thu, 19 Mar 2026 14:12:20 +0000 (UTC) Received: from fedora-work.redhat.com (unknown [10.22.66.24]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 54A8E1800576; Thu, 19 Mar 2026 14:12:16 +0000 (UTC) From: David Jeffery To: linux-kernel@vger.kernel.org, driver-core@lists.linux.dev, linux-pci@vger.kernel.org, linux-scsi@vger.kernel.org, Greg Kroah-Hartman , "Rafael J. Wysocki" , Danilo Krummrich Cc: Tarun Sahu , Pasha Tatashin , =?UTF-8?q?Micha=C5=82=20C=C5=82api=C5=84ski?= , Jordan Richards , Ewan Milne , John Meneghini , "Lombardi, Maurizio" , Stuart Hayes , Laurence Oberman , Bart Van Assche , Bjorn Helgaas , David Jeffery Subject: [PATCH 4/5] PCI: enable async shutdown support Date: Thu, 19 Mar 2026 10:11:41 -0400 Message-ID: <20260319141142.5781-5-djeffery@redhat.com> In-Reply-To: <20260319141142.5781-1-djeffery@redhat.com> References: <20260319141142.5781-1-djeffery@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 Content-Type: text/plain; charset="utf-8" Like its async suspend support, allow PCI device shutdown to be performed asynchronously to reduce shutdown time. Signed-off-by: David Jeffery Signed-off-by: Stuart Hayes Tested-by: Laurence Oberman --- drivers/pci/probe.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index bccc7a4bdd79..4d98bab2163d 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -1040,6 +1040,7 @@ static int pci_register_host_bridge(struct pci_host_b= ridge *bridge) =20 bus->bridge =3D get_device(&bridge->dev); device_enable_async_suspend(bus->bridge); + device_enable_async_shutdown(bus->bridge); pci_set_bus_of_node(bus); pci_set_bus_msi_domain(bus); if (bridge->msi_domain && !dev_get_msi_domain(&bus->dev) && @@ -2749,6 +2750,7 @@ void pci_device_add(struct pci_dev *dev, struct pci_b= us *bus) pci_reassigndev_resource_alignment(dev); =20 pci_init_capabilities(dev); + device_enable_async_shutdown(&dev->dev); =20 /* * Add the device to our list of discovered devices --=20 2.53.0 From nobody Mon Apr 6 10:43:20 2026 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C13D1305047 for ; Thu, 19 Mar 2026 14:12:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773929557; cv=none; b=S7d7ItSXw5a+DVcegqN8X5XpFlFvZICkWgzIpkbbdEhhxSNFmS8GVLpTzV3vmPm3pp3hoDy8NiNp5BYdfmw4QyTrmkT247gUXMOnc84PcOV2qvWkP9cHh58cOilGUzhBjfV++EB11kZjI6c67dfkX8tTA1b0nGazh3sWFbbRAZ4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773929557; c=relaxed/simple; bh=ZS9R2CooQDezB+WIJnc8X5IeXYWMu8ZBSkFXu1xP+24=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=XJo3wKsE3q0qfEuyy1Y5/Ilq3OTPJngRQ1Qt43vv2RZIIZkG7A42CsmJm/N91pVnEX7w/xDJ1CNM3S5lgOeKi6iV2yj9sQUpe4gzSWHwTRymd4eXDBCxnR5ZmuScCPj944ikz5ON36Qq7MaaxkPZ0RUdPSLHdb/7PuiRim5hndY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=Lungrv8N; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="Lungrv8N" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1773929554; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=SdgaP8ORLsWTjy97D1Ac7KNDjoWNyGxBr7xWgrx8peE=; b=Lungrv8NFlPgNj8e3HMZeugAHL/Cx1c4XiTYTUUJpr0G7gg3KmwKdYl34nmJGvA0IZ2s+K INn2mVbr3PZeyYJVEyBM6LTVkUWkapNnmCGCDA60iVG46zZ1ttvEx6MyEe5bhOjTjLM/+x 9MSyUiGODNIFIale+n2yJYxTsgQI36E= Received: from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-640-FJ55uTLQNseO0C85eSUjLw-1; Thu, 19 Mar 2026 10:12:30 -0400 X-MC-Unique: FJ55uTLQNseO0C85eSUjLw-1 X-Mimecast-MFC-AGG-ID: FJ55uTLQNseO0C85eSUjLw_1773929545 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 1F29E195608E; Thu, 19 Mar 2026 14:12:25 +0000 (UTC) Received: from fedora-work.redhat.com (unknown [10.22.66.24]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id CE8A41800351; Thu, 19 Mar 2026 14:12:20 +0000 (UTC) From: David Jeffery To: linux-kernel@vger.kernel.org, driver-core@lists.linux.dev, linux-pci@vger.kernel.org, linux-scsi@vger.kernel.org, Greg Kroah-Hartman , "Rafael J. Wysocki" , Danilo Krummrich Cc: Tarun Sahu , Pasha Tatashin , =?UTF-8?q?Micha=C5=82=20C=C5=82api=C5=84ski?= , Jordan Richards , Ewan Milne , John Meneghini , "Lombardi, Maurizio" , Stuart Hayes , Laurence Oberman , Bart Van Assche , Bjorn Helgaas , David Jeffery Subject: [PATCH 5/5] scsi: enable async shutdown support Date: Thu, 19 Mar 2026 10:11:42 -0400 Message-ID: <20260319141142.5781-6-djeffery@redhat.com> In-Reply-To: <20260319141142.5781-1-djeffery@redhat.com> References: <20260319141142.5781-1-djeffery@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 Content-Type: text/plain; charset="utf-8" Like scsi's async suspend support, allow scsi devices to be shut down asynchronously to reduce system shutdown time. Signed-off-by: David Jeffery Signed-off-by: Stuart Hayes Tested-by: Laurence Oberman Reviewed-by: Martin K. Petersen --- drivers/scsi/hosts.c | 3 +++ drivers/scsi/scsi_scan.c | 1 + drivers/scsi/scsi_sysfs.c | 4 ++++ 3 files changed, 8 insertions(+) diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index e047747d4ecf..dfb38a82c0bf 100644 --- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c @@ -273,6 +273,7 @@ int scsi_add_host_with_dma(struct Scsi_Host *shost, str= uct device *dev, pm_runtime_set_active(&shost->shost_gendev); pm_runtime_enable(&shost->shost_gendev); device_enable_async_suspend(&shost->shost_gendev); + device_enable_async_shutdown(&shost->shost_gendev); =20 error =3D device_add(&shost->shost_gendev); if (error) @@ -282,6 +283,7 @@ int scsi_add_host_with_dma(struct Scsi_Host *shost, str= uct device *dev, get_device(shost->shost_gendev.parent); =20 device_enable_async_suspend(&shost->shost_dev); + device_enable_async_shutdown(&shost->shost_dev); =20 get_device(&shost->shost_gendev); error =3D device_add(&shost->shost_dev); @@ -519,6 +521,7 @@ struct Scsi_Host *scsi_host_alloc(const struct scsi_hos= t_template *sht, int priv shost->shost_gendev.bus =3D &scsi_bus_type; shost->shost_gendev.type =3D &scsi_host_type; scsi_enable_async_suspend(&shost->shost_gendev); + device_enable_async_shutdown(&shost->shost_gendev); =20 device_initialize(&shost->shost_dev); shost->shost_dev.parent =3D &shost->shost_gendev; diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 60c06fa4ec32..c42b33e8ea8a 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -518,6 +518,7 @@ static struct scsi_target *scsi_alloc_target(struct dev= ice *parent, dev->bus =3D &scsi_bus_type; dev->type =3D &scsi_target_type; scsi_enable_async_suspend(dev); + device_enable_async_shutdown(dev); starget->id =3D id; starget->channel =3D channel; starget->can_queue =3D 0; diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index 6b8c5c05f294..c76ba17b206f 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c @@ -1370,6 +1370,7 @@ static int scsi_target_add(struct scsi_target *starge= t) pm_runtime_set_active(&starget->dev); pm_runtime_enable(&starget->dev); device_enable_async_suspend(&starget->dev); + device_enable_async_shutdown(&starget->dev); =20 return 0; } @@ -1396,6 +1397,7 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev) transport_configure_device(&starget->dev); =20 device_enable_async_suspend(&sdev->sdev_gendev); + device_enable_async_shutdown(&sdev->sdev_gendev); scsi_autopm_get_target(starget); pm_runtime_set_active(&sdev->sdev_gendev); if (!sdev->rpm_autosuspend) @@ -1415,6 +1417,7 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev) } =20 device_enable_async_suspend(&sdev->sdev_dev); + device_enable_async_shutdown(&sdev->sdev_dev); error =3D device_add(&sdev->sdev_dev); if (error) { sdev_printk(KERN_INFO, sdev, @@ -1670,6 +1673,7 @@ void scsi_sysfs_device_initialize(struct scsi_device = *sdev) sdev->sdev_gendev.bus =3D &scsi_bus_type; sdev->sdev_gendev.type =3D &scsi_dev_type; scsi_enable_async_suspend(&sdev->sdev_gendev); + device_enable_async_shutdown(&sdev->sdev_gendev); dev_set_name(&sdev->sdev_gendev, "%d:%d:%d:%llu", sdev->host->host_no, sdev->channel, sdev->id, sdev->lun); sdev->sdev_gendev.groups =3D hostt->sdev_groups; --=20 2.53.0