[PATCH treewide v2 1/3] bitfield: Add non-constant field_{prep,get}() helpers
Yury Norov
yury.norov at gmail.com
Tue Feb 4 03:48:00 AEDT 2025
On Tue, Feb 04, 2025 at 12:41:55AM +0900, Vincent Mailhol wrote:
> On 03/02/2025 at 22:59, Geert Uytterhoeven wrote:
> > Hi Vincent,
> >
> > On Mon, 3 Feb 2025 at 14:37, Vincent Mailhol <mailhol.vincent at wanadoo.fr> wrote:
> >> On 03/02/2025 at 16:44, Johannes Berg wrote:
> >>> On Sun, 2025-02-02 at 12:53 -0500, Yury Norov wrote:
> >>>>> Instead of creating another variant for
> >>>>> non-constant bitfields, wouldn't it be better to make the existing macro
> >>>>> accept both?
> >>>>
> >>>> Yes, it would definitely be better IMO.
> >>>
> >>> On the flip side, there have been discussions in the past (though I
> >>> think not all, if any, on the list(s)) about the argument order. Since
> >>> the value is typically not a constant, requiring the mask to be a
> >>> constant has ensured that the argument order isn't as easily mixed up as
> >>> otherwise.
> >>
> >> If this is a concern, then it can be checked with:
> >>
> >> BUILD_BUG_ON_MSG(!__builtin_constant_p(_mask) &&
> >> __builtin_constant_p(_val),
> >> _pfx "mask is not constant");
> >>
> >> It means that we forbid FIELD_PREP(non_const_mask, const_val) but allow
> >> any other combination.
> >
> > Even that case looks valid to me. Actually there is already such a user
> > in drivers/iio/temperature/mlx90614.c:
> >
> > ret |= field_prep(chip_info->fir_config_mask, MLX90614_CONST_FIR);
> >
> > So if you want enhanced safety, having both the safer/const upper-case
> > variants and the less-safe/non-const lower-case variants makes sense.
I agree with that. I just don't want the same shift-and operation to be
opencoded again and again.
What I actually meant is that I'm OK with whatever number of field_prep()
macro flavors, if we make sure that they don't duplicate each other. So
for me, something like this would be the best solution:
#define field_prep(mask, val) \
(((typeof(_mask))(_val) << __bf_shf(_mask)) & (_mask))
#define FIELD_PREP(mask, val) \
( \
FIELD_PREP_INPUT_CHECK(_mask, _val,); \
field_prep(mask, val); \
)
#define FIELD_PREP_CONST(_mask, _val) \
( \
FIELD_PREP_CONST_INPUT_CHECK(mask, val);
FIELD_PREP(mask, val); // or field_prep()
)
We have a similar macro GENMASK() in linux/bits.h. It is implemented
like this:
#define GENMASK_INPUT_CHECK(h, l) BUILD_BUG_ON_ZERO(const_true((l) > (h)))
#define GENMASK(h, l) \
(GENMASK_INPUT_CHECK(h, l) + __GENMASK(h, l))
And it works just well. Can we end up with a similar approach here?
> So, we are scared of people calling FIELD_PREP() with the arguments in
> the wrong order:
>
> FIELD_PREP(val, mask)
>
> thus adding the check that mask must be a compile time constant.
Don't be scared. Kernel coding implies that people get used to read
function declarations and comments on top of them before using
something.
Thansk,
Yury
More information about the Linux-aspeed
mailing list