[PATCH v2 12/14] drm/i915: Define multicast registers as a new type

Matt Roper matthew.d.roper at intel.com
Wed Oct 5 01:01:15 UTC 2022


On Tue, Oct 04, 2022 at 04:00:57PM +0300, Jani Nikula wrote:
> On Tue, 04 Oct 2022, Jani Nikula <jani.nikula at linux.intel.com> wrote:
> > On Fri, 30 Sep 2022, Matt Roper <matthew.d.roper at intel.com> wrote:
> >> diff --git a/drivers/gpu/drm/i915/i915_reg_defs.h b/drivers/gpu/drm/i915/i915_reg_defs.h
> >> index 8f486f77609f..e823869b9afd 100644
> >> --- a/drivers/gpu/drm/i915/i915_reg_defs.h
> >> +++ b/drivers/gpu/drm/i915/i915_reg_defs.h
> >> @@ -104,22 +104,16 @@ typedef struct {
> >>  
> >>  #define _MMIO(r) ((const i915_reg_t){ .reg = (r) })
> >>  
> >> -#define INVALID_MMIO_REG _MMIO(0)
> >> -
> >> -static __always_inline u32 i915_mmio_reg_offset(i915_reg_t reg)
> >> -{
> >> -	return reg.reg;
> >> -}
> >> +typedef struct {
> >> +	u32 reg;
> >> +} i915_mcr_reg_t;
> >>  
> >> -static inline bool i915_mmio_reg_equal(i915_reg_t a, i915_reg_t b)
> >> -{
> >> -	return i915_mmio_reg_offset(a) == i915_mmio_reg_offset(b);
> >> -}
> >> +#define INVALID_MMIO_REG _MMIO(0)
> >>  
> >> -static inline bool i915_mmio_reg_valid(i915_reg_t reg)
> >> -{
> >> -	return !i915_mmio_reg_equal(reg, INVALID_MMIO_REG);
> >> -}
> >> +/* These macros can be used on either i915_reg_t or i915_mcr_reg_t */
> >> +#define i915_mmio_reg_offset(r) (r.reg)
> >> +#define i915_mmio_reg_equal(a, b) (i915_mmio_reg_offset(a) == i915_mmio_reg_offset(b))
> >> +#define i915_mmio_reg_valid(r) (!i915_mmio_reg_equal(r, INVALID_MMIO_REG))
> >>  
> >
> > I don't really like losing the type safety here. The whole and only
> > purpose of typedeffing i915_reg_t as a struct instead of just u32 was
> > the strict type safety.
> 
> PS. Changes like this should really be highlighted better, in the commit
> subject and title. Now it feels like it's hidden within a big commit
> within a big series, without even mentioning it in the commit message.

This patch adds the type safety we've been missing until now.  The only
thing that's slightly less safe is the i915_mmio_reg_offset() macro
itself since it allows either of the two split register types to be
passed to the same macro for simplicity.  In theory if you had some
other structure that also had a 'reg' member it could sneak through
here, but most type mistakes (e.g., passing an integer) would still
cause a build failure.

If we want to make this specific macro more bullet-proof, while still
minimizing thrash elsewhere, we could re-write this as

    #define i915_mmio_reg_offset(r) \
         _Generic((r), i915_reg_t: (r).reg, i915_mcr_reg_t: (r).reg)

which I believe should result in a build failure if anything other than
an i915_reg_t or i915_mcr_reg_t is passed in.

We could also just split this out into separate MCR vs non-MCR offset
lookup functions as we've done with other things in this series.  But if
I recall correctly that leads to annoying thrash in stuff like
cmdparser, gvt, perf, etc. that never actually wanted registers to begin
with, but rather lists/ranges of MMIO offsets without a care for the
type of register that lives at the offset.


Matt

> 
> 
> BR,
> Jani.
> 
> 
> >
> > BR,
> > Jani.
> 
> -- 
> Jani Nikula, Intel Open Source Graphics Center

-- 
Matt Roper
Graphics Software Engineer
VTT-OSGC Platform Enablement
Intel Corporation


More information about the dri-devel mailing list