From: Jonathan Cameron <Jonathan.Cameron@Huawei.com>
To: Vishal Verma <vishal.l.verma@intel.com>
Cc: <linux-cxl@vger.kernel.org>,
Dan Williams <dan.j.williams@intel.com>,
"Ira Weiny" <ira.weiny@intel.com>,
Alison Schofield <alison.schofield@intel.com>
Subject: Re: [PATCH v2] cxl/region: refactor decoder allocation for region refs
Date: Thu, 3 Nov 2022 16:41:18 +0000 [thread overview]
Message-ID: <20221103164118.000031bf@Huawei.com> (raw)
In-Reply-To: <20221101074100.1732003-1-vishal.l.verma@intel.com>
On Tue, 1 Nov 2022 01:41:00 -0600
Vishal Verma <vishal.l.verma@intel.com> wrote:
> When an intermediate port's decoders have been exhausted by existing
> regions, and creating a new region with the port in question in it's
> hierarchical path is attempted, cxl_port_attach_region() fails to find a
> port decoder (as would be expected), and drops into the failure / cleanup
> path.
>
> However, during cleanup of the region reference, a sanity check attempts
> to dereference the decoder, which in the above case didn't exist. This
> causes a NULL pointer dereference BUG.
>
> To fix this, refactor the decoder allocation and de-allocation into
> helper routines, and in this 'free' routine, check that the decoder,
> @cxld, is valid before attempting any operations on it.
>
> Cc: Dan Williams <dan.j.williams@intel.com>
> Suggested-by: Dan Williams <dan.j.williams@intel.com>
> Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>
FWIW.
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
> ---
> drivers/cxl/core/region.c | 67 ++++++++++++++++++++++++---------------
> 1 file changed, 41 insertions(+), 26 deletions(-)
>
> Changes since v1[1]:
> - Limit the new decoder alloc helper to only the decoder allocation for
> new cxl_region_ref objects, not retrieval for existing refs (Dan).
>
> [1]: https://lore.kernel.org/linux-cxl/89acba4011d03582a1f81feb376915b826020cee.camel@intel.com
>
>
> diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
> index 401148016978..986855e93e71 100644
> --- a/drivers/cxl/core/region.c
> +++ b/drivers/cxl/core/region.c
> @@ -686,18 +686,27 @@ static struct cxl_region_ref *alloc_region_ref(struct cxl_port *port,
> return cxl_rr;
> }
>
> -static void free_region_ref(struct cxl_region_ref *cxl_rr)
> +static void cxl_rr_free_decoder(struct cxl_region_ref *cxl_rr)
> {
> - struct cxl_port *port = cxl_rr->port;
> struct cxl_region *cxlr = cxl_rr->region;
> struct cxl_decoder *cxld = cxl_rr->decoder;
>
> + if (!cxld)
> + return;
> +
> dev_WARN_ONCE(&cxlr->dev, cxld->region != cxlr, "region mismatch\n");
> if (cxld->region == cxlr) {
> cxld->region = NULL;
> put_device(&cxlr->dev);
> }
> +}
>
> +static void free_region_ref(struct cxl_region_ref *cxl_rr)
> +{
> + struct cxl_port *port = cxl_rr->port;
> + struct cxl_region *cxlr = cxl_rr->region;
> +
> + cxl_rr_free_decoder(cxl_rr);
> xa_erase(&port->regions, (unsigned long)cxlr);
> xa_destroy(&cxl_rr->endpoints);
> kfree(cxl_rr);
> @@ -728,6 +737,33 @@ static int cxl_rr_ep_add(struct cxl_region_ref *cxl_rr,
> return 0;
> }
>
> +static int cxl_rr_alloc_decoder(struct cxl_port *port, struct cxl_region *cxlr,
> + struct cxl_endpoint_decoder *cxled,
> + struct cxl_region_ref *cxl_rr)
> +{
> + struct cxl_decoder *cxld;
> +
> + if (port == cxled_to_port(cxled))
> + cxld = &cxled->cxld;
> + else
> + cxld = cxl_region_find_decoder(port, cxlr);
> + if (!cxld) {
> + dev_dbg(&cxlr->dev, "%s: no decoder available\n",
> + dev_name(&port->dev));
> + return -EBUSY;
> + }
> +
> + if (cxld->region) {
> + dev_dbg(&cxlr->dev, "%s: %s already attached to %s\n",
> + dev_name(&port->dev), dev_name(&cxld->dev),
> + dev_name(&cxld->region->dev));
> + return -EBUSY;
> + }
> +
> + cxl_rr->decoder = cxld;
> + return 0;
> +}
> +
> /**
> * cxl_port_attach_region() - track a region's interest in a port by endpoint
> * @port: port to add a new region reference 'struct cxl_region_ref'
> @@ -794,12 +830,6 @@ static int cxl_port_attach_region(struct cxl_port *port,
> cxl_rr->nr_targets++;
> nr_targets_inc = true;
> }
> -
> - /*
> - * The decoder for @cxlr was allocated when the region was first
> - * attached to @port.
> - */
> - cxld = cxl_rr->decoder;
> } else {
> cxl_rr = alloc_region_ref(port, cxlr);
> if (IS_ERR(cxl_rr)) {
> @@ -810,26 +840,11 @@ static int cxl_port_attach_region(struct cxl_port *port,
> }
> nr_targets_inc = true;
>
> - if (port == cxled_to_port(cxled))
> - cxld = &cxled->cxld;
> - else
> - cxld = cxl_region_find_decoder(port, cxlr);
> - if (!cxld) {
> - dev_dbg(&cxlr->dev, "%s: no decoder available\n",
> - dev_name(&port->dev));
> + rc = cxl_rr_alloc_decoder(port, cxlr, cxled, cxl_rr);
> + if (rc)
> goto out_erase;
> - }
> -
> - if (cxld->region) {
> - dev_dbg(&cxlr->dev, "%s: %s already attached to %s\n",
> - dev_name(&port->dev), dev_name(&cxld->dev),
> - dev_name(&cxld->region->dev));
> - rc = -EBUSY;
> - goto out_erase;
> - }
> -
> - cxl_rr->decoder = cxld;
> }
> + cxld = cxl_rr->decoder;
>
> rc = cxl_rr_ep_add(cxl_rr, cxled);
> if (rc) {
prev parent reply other threads:[~2022-11-03 16:45 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-11-01 7:41 [PATCH v2] cxl/region: refactor decoder allocation for region refs Vishal Verma
2022-11-01 18:16 ` Dave Jiang
2022-11-03 16:41 ` Jonathan Cameron [this message]
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=20221103164118.000031bf@Huawei.com \
--to=jonathan.cameron@huawei.com \
--cc=alison.schofield@intel.com \
--cc=dan.j.williams@intel.com \
--cc=ira.weiny@intel.com \
--cc=linux-cxl@vger.kernel.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.