Linux CXL
 help / color / mirror / Atom feed
From: Gregory Price <gregory.price@memverge.com>
To: linux-cxl@vger.kernel.org
Cc: Dan Williams <dan.j.williams@intel.com>,
	linux-cxl@vger.kernel.org, Dave Jiang <dave.jiang@intel.com>
Subject: [BUG] Root port fails to match with port driver on non-RCH topology
Date: Thu, 15 Jun 2023 12:16:05 -0400	[thread overview]
Message-ID: <ZIs5Ra+9SGGbUZoZ@memverge.com> (raw)

On boot in an AMD Genoa production system with EFI_MEMORY_SP set, the
root port fails to enable port topology.  Notably, this is not an RCH
system, so i'm not sure this code path has been tested previously.


Nebulous message in dmesg:

[   15.589072] cxl_mem mem0: CXL port topology root0 not enabled

A bit non-obvious what is occuring here, this occurs during endpoint
allocation, at this point is cxl_mem_probe:

drivers/cxl/mem.c
static int cxl_mem_probe(struct device *dev)
{
...
    if (dport->rch)
        endpoint_parent = parent_port->uport;
    else
        endpoint_parent = &parent_port->dev;

    device_lock(endpoint_parent);
    if (!endpoint_parent->driver) {
        dev_err(dev, "CXL port topology %s not enabled\n",
            dev_name(endpoint_parent));
        rc = -ENXIO;
        goto unlock;
    }
...
}


endpoint_parent->driver is NULL.  In this case, endpoint driver traces
back to root0 not having it's driver set.  This occurs only when the
type matching fails:

drivers/cxl/core/port.c
static int cxl_bus_match(struct device *dev, struct device_driver *drv)
{
    return cxl_device_id(dev) == to_cxl_drv(drv)->id;
}


As it turns out, this can never return true for the root port.

drivers/cxl/core/port.c
static int cxl_device_id(const struct device *dev)
{
...
    if (is_cxl_port(dev)) {
        if (is_cxl_root(to_cxl_port(dev)))
            return CXL_DEVICE_ROOT;
        return CXL_DEVICE_PORT;
    }
...
}

drivers/cxl/port.c
static struct cxl_driver cxl_port_driver = {
    .name = "cxl_port",
    .probe = cxl_port_probe,
    .id = CXL_DEVICE_PORT,
    .drv = {
        .dev_groups = cxl_port_attribute_groups,
    },
};


the root will always be identified as CXL_DEVICE_ROOT and can never
match the port driver.  As a result, the >driver field can never be
set by the device drive base:


static int __device_attach_driver(struct device_driver *drv, void *_data)
{
...
        ret = driver_match_device(drv, dev);
...
        driver_probe_device(drv, dev)
}

static int driver_probe_device(struct device_driver *drv, struct device *dev)
{
...
        ret = __driver_probe_device(drv, dev);
...
}

static int __driver_probe_device(struct device_driver *drv, struct device *dev)
{
...
                ret = really_probe(dev, drv);
...
}

static int really_probe(struct device *dev, struct device_driver *drv)
{
...
re_probe:
        dev->driver = drv;
...
}




Unfortunately, I added this as a hack, but it did not resolve the issue.

I'm a bit lost in the device-driver core trying to track down the exact
path that is being taken, it's possible another subsequent error is
occuring that subsequently fails as well.


~Gregory


diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c
index 4d1f9c5b5029..7f99e4f790d8 100644
--- a/drivers/cxl/core/port.c
+++ b/drivers/cxl/core/port.c
@@ -1853,7 +1853,9 @@ static int cxl_bus_uevent(const struct device *dev, struct kobj_uevent_env *env)

 static int cxl_bus_match(struct device *dev, struct device_driver *drv)
 {
-       return cxl_device_id(dev) == to_cxl_drv(drv)->id;
+       int devid = cxl_device_id(dev);
+       int drvid = to_cxl_drv(drv)->id
+       return (devid == drvid) || (devid == CXL_DEVICE_ROOT && drvid == CXL_DEVICE_PORT);
 }

             reply	other threads:[~2023-06-15 16:16 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-06-15 16:16 Gregory Price [this message]
2023-06-15 18:46 ` [BUG] Root port fails to match with port driver on non-RCH topology Gregory Price
2023-06-15 18:51   ` Gregory Price
2023-06-15 22:43     ` Gregory Price
2023-06-22  9:48       ` Jonathan Cameron
2023-06-22 14:47         ` Gregory Price

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=ZIs5Ra+9SGGbUZoZ@memverge.com \
    --to=gregory.price@memverge.com \
    --cc=dan.j.williams@intel.com \
    --cc=dave.jiang@intel.com \
    --cc=linux-cxl@vger.kernel.org \
    /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