Re: [PATCH 03/14] cxl/mem: Find device capabilities

From: Ben Widawsky
Date: Tue Feb 02 2021 - 13:28:39 EST


On 21-02-02 18:10:16, Christoph Hellwig wrote:
> On Fri, Jan 29, 2021 at 04:24:27PM -0800, Ben Widawsky wrote:
> > #ifndef __CXL_H__
> > #define __CXL_H__
> >
> > +#include <linux/bitfield.h>
> > +#include <linux/bitops.h>
> > +#include <linux/io.h>
> > +
> > +#define CXL_SET_FIELD(value, field) \
> > + ({ \
> > + WARN_ON(!FIELD_FIT(field##_MASK, value)); \
> > + FIELD_PREP(field##_MASK, value); \
> > + })
> > +
> > +#define CXL_GET_FIELD(word, field) FIELD_GET(field##_MASK, word)
>
> This looks like some massive obsfucation. What is the intent
> here?
>

I will drop these. I don't recall why I did this to be honest.

> > + /* Cap 0001h - CXL_CAP_CAP_ID_DEVICE_STATUS */
> > + struct {
> > + void __iomem *regs;
> > + } status;
> > +
> > + /* Cap 0002h - CXL_CAP_CAP_ID_PRIMARY_MAILBOX */
> > + struct {
> > + void __iomem *regs;
> > + size_t payload_size;
> > + } mbox;
> > +
> > + /* Cap 4000h - CXL_CAP_CAP_ID_MEMDEV */
> > + struct {
> > + void __iomem *regs;
> > + } mem;
>
> This style looks massively obsfucated. For one the comments look like
> absolute gibberish, but also what is the point of all these anonymous
> structures?

They're not anonymous, and their names are for the below register functions. The
comments are connected spec reference 'Cap XXXXh' to definitions in cxl.h. I can
articulate that if it helps.

>
> > +#define cxl_reg(type) \
> > + static inline void cxl_write_##type##_reg32(struct cxl_mem *cxlm, \
> > + u32 reg, u32 value) \
> > + { \
> > + void __iomem *reg_addr = cxlm->type.regs; \
> > + writel(value, reg_addr + reg); \
> > + } \
> > + static inline void cxl_write_##type##_reg64(struct cxl_mem *cxlm, \
> > + u32 reg, u64 value) \
> > + { \
> > + void __iomem *reg_addr = cxlm->type.regs; \
> > + writeq(value, reg_addr + reg); \
> > + } \
>
> What is the value add of all this obsfucation over the trivial
> calls to the write*/read* functions, possible with a locally
> declarate "void __iomem *" variable in the callers like in all
> normall drivers? Except for making the life of the poor soul trying
> to debug this code some time in the future really hard, of course.
>

The register space for CXL devices is a bit weird since it's all subdivided
under 1 BAR for now. To clearly distinguish over the different subregions, these
helpers exist. It's really easy to mess this up as the developer and I actually
would disagree that it makes debugging quite a bit easier. It also gets more
convoluted when you add the other 2 BARs which also each have their own
subregions.

For example. if my mailbox function does:
cxl_read_status_reg32(cxlm, CXLDEV_MB_CAPS_OFFSET);

instead of:
cxl_read_mbox_reg32(cxlm, CXLDEV_MB_CAPS_OFFSET);

It's easier to spot than:
readl(cxlm->regs + cxlm->status_offset + CXLDEV_MB_CAPS_OFFSET)


> > + /* 8.2.8.4.3 */
>
> ????
>

I had been trying to be consistent with 'CXL2.0 - ' in front of all spec
reference. I obviously missed this one.