All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jonathan Cameron <Jonathan.Cameron@Huawei.com>
To: Dan Williams <dan.j.williams@intel.com>
Cc: <linux-cxl@vger.kernel.org>, <vishal.l.verma@intel.com>,
	<dave.hansen@linux.intel.com>, <linux-mm@kvack.org>,
	<linux-acpi@vger.kernel.org>
Subject: Re: [PATCH v2 01/20] cxl/memdev: Fix endpoint port removal
Date: Fri, 10 Feb 2023 17:28:50 +0000	[thread overview]
Message-ID: <20230210172850.00001d5b@Huawei.com> (raw)
In-Reply-To: <167601992789.1924368.8083994227892600608.stgit@dwillia2-xfh.jf.intel.com>

On Fri, 10 Feb 2023 01:05:27 -0800
Dan Williams <dan.j.williams@intel.com> wrote:

> Testing of ram region support [1], stimulates a long standing bug in
> cxl_detach_ep() where some cxl_ep_remove() cleanup is skipped due to
> inability to walk ports after dports have been unregistered. That
> results in a failure to re-register a memdev after the port is
> re-enabled leading to a crash like the following:
> 
>     cxl_port_setup_targets: cxl region4: cxl_host_bridge.0:port4 iw: 1 ig: 256
>     general protection fault, ...
>     [..]
>     RIP: 0010:cxl_region_setup_targets+0x897/0x9e0 [cxl_core]
>     dev_name at include/linux/device.h:700
>     (inlined by) cxl_port_setup_targets at drivers/cxl/core/region.c:1155
>     (inlined by) cxl_region_setup_targets at drivers/cxl/core/region.c:1249
>     [..]
>     Call Trace:
>      <TASK>
>      attach_target+0x39a/0x760 [cxl_core]
>      ? __mutex_unlock_slowpath+0x3a/0x290
>      cxl_add_to_region+0xb8/0x340 [cxl_core]
>      ? lockdep_hardirqs_on+0x7d/0x100
>      discover_region+0x4b/0x80 [cxl_port]
>      ? __pfx_discover_region+0x10/0x10 [cxl_port]
>      device_for_each_child+0x58/0x90
>      cxl_port_probe+0x10e/0x130 [cxl_port]
>      cxl_bus_probe+0x17/0x50 [cxl_core]
> 
> Change the port ancestry walk to be by depth rather than by dport. This
> ensures that even if a port has unregistered its dports a deferred
> memdev cleanup will still be able to cleanup the memdev's interest in
> that port.
> 
> The parent_port->dev.driver check is only needed for determining if the
> bottom up removal beat the top-down removal, but cxl_ep_remove() can
> always proceed.

Why can cxl_ep_remove() always proceed?  What stops it racing?
Is it that we are holding a reference to the port at the time of the
call so the release callback can't be called until we drop that?
Anyhow, good to have a little more detail on the 'why' in the patch
description (particularly for those reading this when half asleep like me ;)

> 
> Fixes: 2703c16c75ae ("cxl/core/port: Add switch port enumeration")
> Link: http://lore.kernel.org/r/167564534874.847146.5222419648551436750.stgit@dwillia2-xfh.jf.intel.com [1]
> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
> ---
>  drivers/cxl/core/memdev.c |    1 +
>  drivers/cxl/core/port.c   |   58 +++++++++++++++++++++++++--------------------
>  drivers/cxl/cxlmem.h      |    2 ++
>  3 files changed, 35 insertions(+), 26 deletions(-)
> 
> diff --git a/drivers/cxl/core/memdev.c b/drivers/cxl/core/memdev.c
> index a74a93310d26..3a8bc2b06047 100644
> --- a/drivers/cxl/core/memdev.c
> +++ b/drivers/cxl/core/memdev.c
> @@ -246,6 +246,7 @@ static struct cxl_memdev *cxl_memdev_alloc(struct cxl_dev_state *cxlds,
>  	if (rc < 0)
>  		goto err;
>  	cxlmd->id = rc;
> +	cxlmd->depth = -1;
>  
>  	dev = &cxlmd->dev;
>  	device_initialize(dev);
> diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c
> index 410c036c09fa..317bcf4dbd9d 100644
> --- a/drivers/cxl/core/port.c
> +++ b/drivers/cxl/core/port.c
> @@ -1207,6 +1207,7 @@ int cxl_endpoint_autoremove(struct cxl_memdev *cxlmd, struct cxl_port *endpoint)
>  
>  	get_device(&endpoint->dev);
>  	dev_set_drvdata(dev, endpoint);
> +	cxlmd->depth = endpoint->depth;
>  	return devm_add_action_or_reset(dev, delete_endpoint, cxlmd);
>  }
>  EXPORT_SYMBOL_NS_GPL(cxl_endpoint_autoremove, CXL);
> @@ -1241,50 +1242,55 @@ static void reap_dports(struct cxl_port *port)
>  	}
>  }
>  
> +struct detach_ctx {
> +	struct cxl_memdev *cxlmd;
> +	int depth;
> +};

>  static void cxl_detach_ep(void *data)
>  {
>  	struct cxl_memdev *cxlmd = data;
> -	struct device *iter;
>  
> -	for (iter = &cxlmd->dev; iter; iter = grandparent(iter)) {
> -		struct device *dport_dev = grandparent(iter);
> +	for (int i = cxlmd->depth - 1; i >= 1; i--) {
>  		struct cxl_port *port, *parent_port;
> +		struct detach_ctx ctx = {
> +			.cxlmd = cxlmd,
> +			.depth = i,
> +		};
> +		struct device *dev;
>  		struct cxl_ep *ep;
>  		bool died = false;
>  
> -		if (!dport_dev)
> -			break;
> -
> -		port = find_cxl_port(dport_dev, NULL);
> -		if (!port)
> -			continue;
> -
> -		if (is_cxl_root(port)) {
> -			put_device(&port->dev);
> +		dev = bus_find_device(&cxl_bus_type, NULL, &ctx,
> +				      port_has_memdev);
> +		if (!dev)
>  			continue;
> -		}
> +		port = to_cxl_port(dev);
>  
>  		parent_port = to_cxl_port(port->dev.parent);
>  		device_lock(&parent_port->dev);
> -		if (!parent_port->dev.driver) {
> -			/*
> -			 * The bottom-up race to delete the port lost to a
> -			 * top-down port disable, give up here, because the
> -			 * parent_port ->remove() will have cleaned up all
> -			 * descendants.
> -			 */
> -			device_unlock(&parent_port->dev);
> -			put_device(&port->dev);
> -			continue;
> -		}
> -
>  		device_lock(&port->dev);
>  		ep = cxl_ep_load(port, cxlmd);
>  		dev_dbg(&cxlmd->dev, "disconnect %s from %s\n",
>  			ep ? dev_name(ep->ep) : "", dev_name(&port->dev));
>  		cxl_ep_remove(port, ep);
>  		if (ep && !port->dead && xa_empty(&port->endpoints) &&
> -		    !is_cxl_root(parent_port)) {
> +		    !is_cxl_root(parent_port) && parent_port->dev.driver) {
>  			/*
>  			 * This was the last ep attached to a dynamically
>  			 * enumerated port. Block new cxl_add_ep() and garbage



  reply	other threads:[~2023-02-10 17:28 UTC|newest]

Thread overview: 65+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-02-10  9:05 [PATCH v2 00/20] CXL RAM and the 'Soft Reserved' => 'System RAM' default Dan Williams
2023-02-10  9:05 ` [PATCH v2 01/20] cxl/memdev: Fix endpoint port removal Dan Williams
2023-02-10 17:28   ` Jonathan Cameron [this message]
2023-02-10 21:14     ` Dan Williams
2023-02-10 23:17   ` Verma, Vishal L
2023-02-10  9:05 ` [PATCH v2 02/20] cxl/Documentation: Update references to attributes added in v6.0 Dan Williams
2023-02-10  9:05 ` [PATCH v2 03/20] cxl/region: Add a mode attribute for regions Dan Williams
2023-02-10  9:05 ` [PATCH v2 04/20] cxl/region: Support empty uuids for non-pmem regions Dan Williams
2023-02-10 17:30   ` Jonathan Cameron
2023-02-10 23:34   ` Ira Weiny
2023-02-10  9:05 ` [PATCH v2 05/20] cxl/region: Validate region mode vs decoder mode Dan Williams
2023-02-10  9:05 ` [PATCH v2 06/20] cxl/region: Add volatile region creation support Dan Williams
2023-02-10  9:06 ` [PATCH v2 07/20] cxl/region: Refactor attach_target() for autodiscovery Dan Williams
2023-02-10  9:06 ` [PATCH v2 08/20] cxl/region: Cleanup target list on attach error Dan Williams
2023-02-10 17:31   ` Jonathan Cameron
2023-02-10 23:17   ` Verma, Vishal L
2023-02-10 23:46   ` Ira Weiny
2023-02-10  9:06 ` [PATCH v2 09/20] cxl/region: Move region-position validation to a helper Dan Williams
2023-02-10 17:34   ` Jonathan Cameron
2023-02-10  9:06 ` [PATCH v2 10/20] kernel/range: Uplevel the cxl subsystem's range_contains() helper Dan Williams
2023-02-10  9:06 ` [PATCH v2 11/20] cxl/region: Enable CONFIG_CXL_REGION to be toggled Dan Williams
2023-02-10  9:06 ` [PATCH v2 12/20] cxl/port: Split endpoint and switch port probe Dan Williams
2023-02-10 17:41   ` Jonathan Cameron
2023-02-10 23:21   ` Verma, Vishal L
2023-02-10  9:06 ` [PATCH v2 13/20] cxl/region: Add region autodiscovery Dan Williams
2023-02-10 18:09   ` Jonathan Cameron
2023-02-10 21:35     ` Dan Williams
2023-02-14 13:23       ` Jonathan Cameron
2023-02-14 16:43         ` Dan Williams
2023-02-10 21:49     ` Dan Williams
2023-02-11  0:29   ` Verma, Vishal L
2023-02-11  1:03     ` Dan Williams
2023-02-13 19:27   ` Fan Ni
2023-02-28 18:53   ` Fan Ni
2023-02-10  9:06 ` [PATCH v2 14/20] tools/testing/cxl: Define a fixed volatile configuration to parse Dan Williams
2023-02-10 18:12   ` Jonathan Cameron
2023-02-10 18:36   ` Dave Jiang
2023-02-11  0:39   ` Verma, Vishal L
2023-02-10  9:06 ` [PATCH v2 15/20] dax/hmem: Move HMAT and Soft reservation probe initcall level Dan Williams
2023-02-10 21:53   ` Dave Jiang
2023-02-10 21:57     ` Dave Jiang
2023-02-11  0:40   ` Verma, Vishal L
2023-02-10  9:06 ` [PATCH v2 16/20] dax/hmem: Drop unnecessary dax_hmem_remove() Dan Williams
2023-02-10 21:59   ` Dave Jiang
2023-02-11  0:41   ` Verma, Vishal L
2023-02-10  9:07 ` [PATCH v2 17/20] dax/hmem: Convey the dax range via memregion_info() Dan Williams
2023-02-10 22:03   ` Dave Jiang
2023-02-11  4:25   ` Verma, Vishal L
2023-02-10  9:07 ` [PATCH v2 18/20] dax/hmem: Move hmem device registration to dax_hmem.ko Dan Williams
2023-02-10 18:25   ` Jonathan Cameron
2023-02-10 22:09   ` Dave Jiang
2023-02-11  4:41   ` Verma, Vishal L
2023-02-10  9:07 ` [PATCH v2 19/20] dax: Assign RAM regions to memory-hotplug by default Dan Williams
2023-02-10 22:19   ` Dave Jiang
2023-02-11  5:57   ` Verma, Vishal L
2023-02-10  9:07 ` [PATCH v2 20/20] cxl/dax: Create dax devices for CXL RAM regions Dan Williams
2023-02-10 18:38   ` Jonathan Cameron
2023-02-10 22:42   ` Dave Jiang
2023-02-10 17:53 ` [PATCH v2 00/20] CXL RAM and the 'Soft Reserved' => 'System RAM' default Dan Williams
2023-02-11 14:04   ` Gregory Price
2023-02-13 18:22 ` Gregory Price
2023-02-13 18:31   ` Gregory Price
2023-02-22 21:41     ` Fan Ni
2023-02-22 22:18       ` Dan Williams
2023-02-14 13:35   ` Jonathan Cameron

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230210172850.00001d5b@Huawei.com \
    --to=jonathan.cameron@huawei.com \
    --cc=dan.j.williams@intel.com \
    --cc=dave.hansen@linux.intel.com \
    --cc=linux-acpi@vger.kernel.org \
    --cc=linux-cxl@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=vishal.l.verma@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.