Linux CXL
 help / color / mirror / Atom feed
From: Alison Schofield <alison.schofield@intel.com>
To: Li Ming <ming.li@zohomail.com>
Cc: <linux-cxl@vger.kernel.org>, Davidlohr Bueso <dave@stgolabs.net>,
	"Jonathan Cameron" <jic23@kernel.org>,
	Dave Jiang <dave.jiang@intel.com>,
	Vishal Verma <vishal.l.verma@intel.com>,
	Ira Weiny <iweiny@kernel.org>, Dan Williams <djbw@kernel.org>
Subject: Re: [PATCH] cxl/port: Restart port enumeration when a sibling adds the dport first
Date: Mon, 13 Jul 2026 18:30:08 -0700	[thread overview]
Message-ID: <alWRIKn1y8f00OgO@aschofie-mobl2.lan> (raw)
In-Reply-To: <a0d6ec53-7186-46dd-a3c3-6bd380a23f9b@zohomail.com>

On Mon, Jul 13, 2026 at 10:45:17AM +0800, Li Ming wrote:
> On 7/12/2026 9:28 AM, Alison Schofield wrote:
> > Endpoint probes can race while enumerating a shared switch. If a
> > sibling probe adds the dport first, the losing probe treats the
> > existing dport as an error and fails to enumerate the endpoint.
> >
> > Treat this race the same as the existing port-created case by
> > restarting the port walk, allowing it to find the existing dport
> > and continue enumeration.
> >
> > This race was discovered while testing a cxl_test mixed-granularity
> > topology, where twelve endpoints behind shared switches are probed in
> > parallel during module load.
> 
> Hi Alison,
> 
> Per commit log, I think the root cause is probe_dport() called in devm_cxl_create_port() twice, and the second time failed because the dport has been added.
> 
> But devm_cxl_create_port() is protected by its parent port's device lock, probe_dport() is called only when a new port is created in devm_cxl_create_port(). If a port can be found, will return -EAGAIN directly in devm_cxl_create_port().
> 
> So If probe_dport() was called twice, is it something wrong in find_cxl_port_by_uport()? Or I miss some details?
> 

Hi Ming,

Thanks for the review and good catch! The commit log is vague and I've
reworded it for v2.

You're right about devm_cxl_create_port(): two probes both entering it
serialize on parent_port->dev and the loser then finds the port and
returns -EAGAIN without a second probe_dport(). find_cxl_port_by_uport()
is fine.

The -EBUSY comes from a different path. Two endpoints behind the same
switch race to add the shared dport and once one publishes the port the
other takes the port-found path instead of devm_cxl_create_port():

  cxl_mem probe (endpoint 0)          cxl_mem probe (endpoint 1)
  --------------------------          --------------------------
  find(uport) == NULL
  add_port_attach_ep()
   devm_cxl_create_port()
    devm_cxl_add_port()
    /* port published,     */
    /* dport not added yet  */
                                       find(uport) succeeds
                                       find_or_add_dport()
                                        probe_dport()
                                        /* adds shared dport */
                                        return -EAGAIN
    guard(device)(&port->dev)
    probe_dport()
    dport_exists() == true
    return -EBUSY

Before this patch, add_port_attach_ep() treated that -EBUSY as fatal and
dropped endpoint 0. Treating it like -EAGAIN restarts the walk, and that
finds the now present dport and continues.

Sending a v2 w commit msg update. Please take a look.

Thanks,
Alison


> 
> Ming
> 
> > Fixes: 4f06d81e7c6a ("cxl: Defer dport allocation for switch ports")
> > Signed-off-by: Alison Schofield <alison.schofield@intel.com>
> > ---
> >  drivers/cxl/core/port.c | 4 ++--
> >  1 file changed, 2 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c
> > index 1215ee4f4035..65f2d2f1eb00 100644
> > --- a/drivers/cxl/core/port.c
> > +++ b/drivers/cxl/core/port.c
> > @@ -1749,8 +1749,8 @@ static int add_port_attach_ep(struct cxl_memdev *cxlmd,
> >  					     parent_dport, uport_dev,
> >  					     dport_dev);
> >  		if (IS_ERR(dport)) {
> > -			/* Port already exists, restart iteration */
> > -			if (PTR_ERR(dport) == -EAGAIN)
> > +			/* Port or dport already exists, restart iteration */
> > +			if (PTR_ERR(dport) == -EAGAIN || PTR_ERR(dport) == -EBUSY)
> >  				return 0;
> >  			return PTR_ERR(dport);
> >  		}
> 
> 

      reply	other threads:[~2026-07-14  1:30 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-12  1:28 [PATCH] cxl/port: Restart port enumeration when a sibling adds the dport first Alison Schofield
2026-07-13  2:45 ` Li Ming
2026-07-14  1:30   ` Alison Schofield [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=alWRIKn1y8f00OgO@aschofie-mobl2.lan \
    --to=alison.schofield@intel.com \
    --cc=dave.jiang@intel.com \
    --cc=dave@stgolabs.net \
    --cc=djbw@kernel.org \
    --cc=iweiny@kernel.org \
    --cc=jic23@kernel.org \
    --cc=linux-cxl@vger.kernel.org \
    --cc=ming.li@zohomail.com \
    --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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox