Re: [PATCH v2 1/2] cxl/acpi: Add the Host Bridge base address to CXL port objects
From: Dan Williams
Date: Wed Jun 16 2021 - 19:51:04 EST
On Wed, Jun 16, 2021 at 4:20 PM Alison Schofield
<alison.schofield@xxxxxxxxx> wrote:
>
>
> Thanks for the review Jonathan -
>
> On Wed, Jun 16, 2021 at 05:13:40PM +0100, Jonathan Cameron wrote:
> > On Tue, 15 Jun 2021 17:20:38 -0700
> > Alison Schofield <alison.schofield@xxxxxxxxx> wrote:
> >
> > > The base address for the Host Bridge port component registers is located
> > > in the CXL Host Bridge Structure (CHBS) of the ACPI CXL Early Discovery
> > > Table (CEDT). Retrieve the CHBS for each Host Bridge (ACPI0016 device)
> > > and include that base address in the port object.
> > >
> > > Co-developed-by: Vishal Verma <vishal.l.verma@xxxxxxxxx>
> > > Signed-off-by: Vishal Verma <vishal.l.verma@xxxxxxxxx>
> > > Signed-off-by: Alison Schofield <alison.schofield@xxxxxxxxx>
> >
> > Hi Alison,
> >
> > A few small suggestions from me.
> >
> > > ---
> > > drivers/cxl/acpi.c | 105 ++++++++++++++++++++++++++++++++++++++++++---
> > > 1 file changed, 99 insertions(+), 6 deletions(-)
> > >
> > > diff --git a/drivers/cxl/acpi.c b/drivers/cxl/acpi.c
> > > index be357eea552c..b6d9cd45428c 100644
> > > --- a/drivers/cxl/acpi.c
> > > +++ b/drivers/cxl/acpi.c
> > > @@ -8,6 +8,61 @@
> > > #include <linux/pci.h>
> > > #include "cxl.h"
> > >
> > > +static struct acpi_table_header *cedt_table;
> > > +
> > > +static struct acpi_cedt_chbs *cxl_acpi_match_chbs(struct device *dev, u32 uid)
> > > +{
> > > + struct acpi_cedt_chbs *chbs, *chbs_match = NULL;
> > > + acpi_size len, cur = 0;
> > > + void *cedt_base;
> > > + int rc = 0;
> > > +
> > > + len = cedt_table->length - sizeof(*cedt_table);
> > > + cedt_base = cedt_table + 1;
> > > +
> > > + while (cur < len) {
> > > + struct acpi_cedt_header *c = cedt_base + cur;
> > > +
> > > + if (c->type != ACPI_CEDT_TYPE_CHBS) {
> > > + cur += c->length;
> > > + continue;
> > > + }
> > > +
> > > + chbs = cedt_base + cur;
> > > +
> > > + if (chbs->header.length < sizeof(*chbs)) {
> > > + dev_err(dev, "Invalid CHBS header length: %u\n",
> > > + chbs->header.length);
> > > + rc = -EINVAL;
> >
> > As below, direct return would be more obvious to my eyes.
> >
>
> Well....I decided to warn & continue on this case. See the updated flow
> in v3.
>
> > > + break;
> > > + }
> > > +
> > > + if (chbs->uid == uid && !chbs_match) {
> > > + chbs_match = chbs;
> > > + cur += c->length;
> > > + continue;
> > > + }
> > > +
> > > + if (chbs->uid == uid && chbs_match) {
> > > + dev_err(dev, "Duplicate CHBS UIDs %u\n", uid);
> >
> > Do we actually care, or should we just drop out on first match?
> > I don't think think there is any obligation to catch broken tables.
> >
>
> Agree on the obligation part, but if things go wrong, this would be
> nice to know. I left it in as a dev warn once. If you think that's
> too strong - let me know.
I do think the driver should care about duplicate UID, but only if
"version, base, or length" mismatch. If the BIOS gives us ambiguous
answers about where the registers are located, the user should be
warned that the driver might be picking the "wrong" one by accident.
If they are identical, the BIOS is being repetitive, but no real harm
that the driver would care about. A dev_warn_once() sounds good as the
first duplicate should be sufficient to say something fishy is afoot,
but it's not an error. The warn_once will also re-trigger when / if
the module is reloaded.