From: Jonathan Cameron <Jonathan.Cameron@Huawei.com>
To: Dan Williams <dan.j.williams@intel.com>
Cc: <linux-cxl@vger.kernel.org>, Fan Ni <fan.ni@samsung.com>,
<vishal.l.verma@intel.com>, <dave.hansen@linux.intel.com>,
<linux-mm@kvack.org>, <linux-acpi@vger.kernel.org>
Subject: Re: [PATCH v2 13/20] cxl/region: Add region autodiscovery
Date: Fri, 10 Feb 2023 18:09:58 +0000 [thread overview]
Message-ID: <20230210180958.00002e5a@Huawei.com> (raw)
In-Reply-To: <167601999958.1924368.9366954455835735048.stgit@dwillia2-xfh.jf.intel.com>
On Fri, 10 Feb 2023 01:06:39 -0800
Dan Williams <dan.j.williams@intel.com> wrote:
> Region autodiscovery is an asynchronous state machine advanced by
> cxl_port_probe(). After the decoders on an endpoint port are enumerated
> they are scanned for actively enabled instances. Each active decoder is
> flagged for auto-assembly CXL_DECODER_F_AUTO and attached to a region.
> If a region does not already exist for the address range setting of the
> decoder one is created. That creation process may race with other
> decoders of the same region being discovered since cxl_port_probe() is
> asynchronous. A new 'struct cxl_root_decoder' lock, @range_lock, is
> introduced to mitigate that race.
>
> Once all decoders have arrived, "p->nr_targets == p->interleave_ways",
> they are sorted by their relative decode position. The sort algorithm
> involves finding the point in the cxl_port topology where one leg of the
> decode leads to deviceA and the other deviceB. At that point in the
> topology the target order in the 'struct cxl_switch_decoder' indicates
> the relative position of those endpoint decoders in the region.
>
> >From that point the region goes through the same setup and validation
Why the >?
> steps as user-created regions, but instead of programming the decoders
> it validates that driver would have written the same values to the
> decoders as were already present.
>
> Tested-by: Fan Ni <fan.ni@samsung.com>
> Link: https://lore.kernel.org/r/167564540972.847146.17096178433176097831.stgit@dwillia2-xfh.jf.intel.com
> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
A few trivial things inline and this being complex code I'm not
as confident about it as the rest of the series but with that in mind
and the fact I didn't find anything that looked broken...
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
...
> +
> +static int cxl_region_sort_targets(struct cxl_region *cxlr)
> +{
> + struct cxl_region_params *p = &cxlr->params;
> + int i, rc = 0;
> +
> + sort(p->targets, p->nr_targets, sizeof(p->targets[0]), cmp_decode_pos,
> + NULL);
> +
> + for (i = 0; i < p->nr_targets; i++) {
> + struct cxl_endpoint_decoder *cxled = p->targets[i];
> +
> + if (cxled->pos < 0)
> + rc = -ENXIO;
If it makes sense to carry on after pos < 0 I'd like to see a comment here
on why. If not, nicer to have a separate dev_dbg() for failed case nad
direct return here.
> + cxled->pos = i;
> + }
> +
> + dev_dbg(&cxlr->dev, "region sort %s\n", rc ? "failed" : "successful");
> + return rc;
> +}
> +
> +
> +int cxl_add_to_region(struct cxl_port *root, struct cxl_endpoint_decoder *cxled)
> +{
> + struct cxl_memdev *cxlmd = cxled_to_memdev(cxled);
> + struct range *hpa = &cxled->cxld.hpa_range;
> + struct cxl_decoder *cxld = &cxled->cxld;
> + struct cxl_root_decoder *cxlrd;
> + struct cxl_region_params *p;
> + struct cxl_region *cxlr;
> + bool attach = false;
> + struct device *dev;
> + int rc;
> +
> + dev = device_find_child(&root->dev, &cxld->hpa_range,
> + match_decoder_by_range);
> + if (!dev) {
> + dev_err(cxlmd->dev.parent,
> + "%s:%s no CXL window for range %#llx:%#llx\n",
> + dev_name(&cxlmd->dev), dev_name(&cxld->dev),
> + cxld->hpa_range.start, cxld->hpa_range.end);
> + return -ENXIO;
> + }
> +
> + cxlrd = to_cxl_root_decoder(dev);
> +
> + /*
> + * Ensure that if multiple threads race to construct_region() for @hpa
> + * one does the construction and the others add to that.
> + */
> + mutex_lock(&cxlrd->range_lock);
> + dev = device_find_child(&cxlrd->cxlsd.cxld.dev, hpa,
> + match_region_by_range);
> + if (!dev)
> + cxlr = construct_region(cxlrd, cxled);
> + else
> + cxlr = to_cxl_region(dev);
> + mutex_unlock(&cxlrd->range_lock);
> +
> + if (IS_ERR(cxlr)) {
> + rc = PTR_ERR(cxlr);
> + goto out;
> + }
> +
> + attach_target(cxlr, cxled, -1, TASK_UNINTERRUPTIBLE);
> +
> + down_read(&cxl_region_rwsem);
> + p = &cxlr->params;
> + attach = p->state == CXL_CONFIG_COMMIT;
> + up_read(&cxl_region_rwsem);
> +
> + if (attach) {
> + int rc = device_attach(&cxlr->dev);
Shadowing int rc isn't great for readability. Just call it rc2 or something :)
Or given you don't make use of the value...
/*
* If device_attach() fails the range may still be active via
* the platform-firmware memory map, otherwise the driver for
* regions is local to this file, so driver matching can't fail
+ * and hence device_attach() cannot return 1.
//very much not obvious otherwise to anyone who isn't far too familiar with device_attach()
*/
if (device_attach(&cxlr->dev) < 0)
dev_err()
> +
> + /*
> + * If device_attach() fails the range may still be active via
> + * the platform-firmware memory map, otherwise the driver for
> + * regions is local to this file, so driver matching can't fail.
> + */
> + if (rc < 0)
> + dev_err(&cxlr->dev, "failed to enable, range: %pr\n",
> + p->res);
> + }
> +
> + put_device(&cxlr->dev);
> +out:
> + put_device(&cxlrd->cxlsd.cxld.dev);
Moderately horrible. Maybe just keep an extra local variable around for the first
use of struct device *dev? or maybe add a put_cxl_root_decoder() helper?
There are lots of other deep structure access like this I guess, so I don't mind
if you just leave this as yet another one.
> + return rc;
> +}
> +EXPORT_SYMBOL_NS_GPL(cxl_add_to_region, CXL);
...
> diff --git a/drivers/cxl/port.c b/drivers/cxl/port.c
> index a8d46a67b45e..d88518836c2d 100644
> --- a/drivers/cxl/port.c
> +++ b/drivers/cxl/port.c
> @@ -30,6 +30,34 @@ static void schedule_detach(void *cxlmd)
> schedule_cxl_memdev_detach(cxlmd);
> }
>
> +static int discover_region(struct device *dev, void *root)
> +{
> + struct cxl_endpoint_decoder *cxled;
> + int rc;
> +
> + if (!is_endpoint_decoder(dev))
> + return 0;
> +
> + cxled = to_cxl_endpoint_decoder(dev);
> + if ((cxled->cxld.flags & CXL_DECODER_F_ENABLE) == 0)
> + return 0;
> +
> + if (cxled->state != CXL_DECODER_STATE_AUTO)
> + return 0;
> +
> + /*
> + * Region enumeration is opportunistic, if this add-event fails,
> + * continue to the next endpoint decoder.
> + */
> + rc = cxl_add_to_region(root, cxled);
> + if (rc)
> + dev_dbg(dev, "failed to add to region: %#llx-%#llx\n",
> + cxled->cxld.hpa_range.start, cxled->cxld.hpa_range.end);
> +
> + return 0;
> +}
> +
> +
Two blank lines?
> static int cxl_switch_port_probe(struct cxl_port *port)
> {
next prev parent reply other threads:[~2023-02-10 18:10 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
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 [this message]
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=20230210180958.00002e5a@Huawei.com \
--to=jonathan.cameron@huawei.com \
--cc=dan.j.williams@intel.com \
--cc=dave.hansen@linux.intel.com \
--cc=fan.ni@samsung.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.