From: Yury Norov <yury.norov@gmail.com>
To: Geert Uytterhoeven <geert+renesas@glider.be>
Cc: "Michael Turquette" <mturquette@baylibre.com>,
"Stephen Boyd" <sboyd@kernel.org>,
"Nicolas Ferre" <nicolas.ferre@microchip.com>,
"Alexandre Belloni" <alexandre.belloni@bootlin.com>,
"Claudiu Beznea" <claudiu.beznea@tuxon.dev>,
"Giovanni Cabiddu" <giovanni.cabiddu@intel.com>,
"Herbert Xu" <herbert@gondor.apana.org.au>,
"David Miller" <davem@davemloft.net>,
"Linus Walleij" <linus.walleij@linaro.org>,
"Bartosz Golaszewski" <brgl@bgdev.pl>,
"Joel Stanley" <joel@jms.id.au>,
"Andrew Jeffery" <andrew@codeconstruct.com.au>,
"Crt Mori" <cmo@melexis.com>,
"Jonathan Cameron" <jic23@kernel.org>,
"Lars-Peter Clausen" <lars@metafoo.de>,
"Jacky Huang" <ychuang3@nuvoton.com>,
"Shan-Chun Hung" <schung@nuvoton.com>,
"Rasmus Villemoes" <linux@rasmusvillemoes.dk>,
"Jaroslav Kysela" <perex@perex.cz>,
"Takashi Iwai" <tiwai@suse.com>,
"Johannes Berg" <johannes@sipsolutions.net>,
"Jakub Kicinski" <kuba@kernel.org>, "Alex Elder" <elder@ieee.org>,
"David Laight" <david.laight.linux@gmail.com>,
"Vincent Mailhol" <mailhol.vincent@wanadoo.fr>,
"Jason Baron" <jbaron@akamai.com>,
"Borislav Petkov" <bp@alien8.de>,
"Tony Luck" <tony.luck@intel.com>,
"Michael Hennerich" <Michael.Hennerich@analog.com>,
"Kim Seer Paller" <kimseer.paller@analog.com>,
"David Lechner" <dlechner@baylibre.com>,
"Nuno Sá" <nuno.sa@analog.com>,
"Andy Shevchenko" <andy@kernel.org>,
"Richard Genoud" <richard.genoud@bootlin.com>,
"Cosmin Tanislav" <demonsingur@gmail.com>,
"Biju Das" <biju.das.jz@bp.renesas.com>,
"Jianping Shen" <Jianping.Shen@de.bosch.com>,
linux-clk@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
linux-renesas-soc@vger.kernel.org, linux-crypto@vger.kernel.org,
linux-edac@vger.kernel.org, qat-linux@intel.com,
linux-gpio@vger.kernel.org, linux-aspeed@lists.ozlabs.org,
linux-iio@vger.kernel.org, linux-sound@vger.kernel.org,
linux-kernel@vger.kernel.org,
"Jonathan Cameron" <Jonathan.Cameron@huawei.com>
Subject: Re: [PATCH v4 2/4] bitfield: Add non-constant field_{prep,get}() helpers
Date: Fri, 17 Oct 2025 14:51:38 -0400 [thread overview]
Message-ID: <aPKQMdyMO-vrb30X@yury> (raw)
In-Reply-To: <67c1998f144b3a21399672c8e4d58d3884ae2b3c.1760696560.git.geert+renesas@glider.be>
On Fri, Oct 17, 2025 at 12:54:10PM +0200, Geert Uytterhoeven wrote:
> The existing FIELD_{GET,PREP}() macros are limited to compile-time
> constants. However, it is very common to prepare or extract bitfield
> elements where the bitfield mask is not a compile-time constant.
>
> To avoid this limitation, the AT91 clock driver and several other
> drivers already have their own non-const field_{prep,get}() macros.
> Make them available for general use by consolidating them in
> <linux/bitfield.h>, and improve them slightly:
> 1. Avoid evaluating macro parameters more than once,
> 2. Replace "ffs() - 1" by "__ffs()",
> 3. Support 64-bit use on 32-bit architectures.
>
> This is deliberately not merged into the existing FIELD_{GET,PREP}()
> macros, as people expressed the desire to keep stricter variants for
> increased safety, or for performance critical paths.
>
> Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
> Acked-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
> Acked-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
> Acked-by: Crt Mori <cmo@melexis.com>
> ---
> v4:
> - Add Acked-by,
> - Rebase on top of commit 7c68005a46108ffa ("crypto: qat - relocate
> power management debugfs helper APIs") in v6.17-rc1,
> - Convert more recently introduced upstream copies:
> - drivers/edac/ie31200_edac.c
> - drivers/iio/dac/ad3530r.c
Can you split out the part that actually introduces the new API?
...
> diff --git a/include/linux/bitfield.h b/include/linux/bitfield.h
> index 7ff817bdae19b468..c999fe70076f6684 100644
> --- a/include/linux/bitfield.h
> +++ b/include/linux/bitfield.h
> @@ -220,4 +220,40 @@ __MAKE_OP(64)
> #undef __MAKE_OP
> #undef ____MAKE_OP
>
> +/**
> + * field_prep() - prepare a bitfield element
> + * @mask: shifted mask defining the field's length and position
> + * @val: value to put in the field
> + *
> + * field_prep() masks and shifts up the value. The result should be
> + * combined with other fields of the bitfield using logical OR.
> + * Unlike FIELD_PREP(), @mask is not limited to a compile-time constant.
> + */
> +#define field_prep(mask, val) \
> + ({ \
> + __auto_type __mask = (mask); \
> + typeof(mask) __val = (val); \
> + unsigned int __shift = sizeof(mask) <= 4 ? \
> + __ffs(__mask) : __ffs64(__mask); \
> + (__val << __shift) & __mask; \
__ffs(0) is undef. The corresponding comment in
include/asm-generic/bitops/__ffs.h explicitly says: "code should check
against 0 first".
I think mask = 0 is a sign of error here. Can you add a code catching
it at compile time, and maybe at runtime too? Something like:
#define __field_prep(mask, val)
({
unsigned __shift = sizeof(mask) <= 4 ? __ffs(mask) : __ffs64(mask);
(val << __shift) & mask;
})
#define field_prep(mask, val)
({
unsigned int __shift;
__auto_type __mask = (mask), __ret = 0;
typeof(mask) __val = (val);
BUILD_BUG_ON_ZERO(const_true(mask == 0));
if (WARN_ON_ONCE(mask == 0))
goto out;
__ret = __field_prep(__mask, __val);
out:
ret;
})
> +
> +/**
> + * field_get() - extract a bitfield element
> + * @mask: shifted mask defining the field's length and position
> + * @reg: value of entire bitfield
> + *
> + * field_get() extracts the field specified by @mask from the
> + * bitfield passed in as @reg by masking and shifting it down.
> + * Unlike FIELD_GET(), @mask is not limited to a compile-time constant.
> + */
> +#define field_get(mask, reg) \
> + ({ \
> + __auto_type __mask = (mask); \
> + typeof(mask) __reg = (reg); \
This would trigger Wconversion warning. Consider
unsigned reg = 0xfff;
field_get(0xf, reg);
<source>:6:26: warning: conversion to 'int' from 'unsigned int' may change the sign of the result [-Wsign-conversion]
6 | typeof(mask) __reg = reg;
| ^~~
Notice, the __auto_type makes the __mask to be int, while the reg is
unsigned int. You need to do:
typeof(mask) __reg = (typeof(mask))(reg);
Please enable higher warning levels for the next round.
Also, because for numerals __auto_type is int, when char is enough - are
you sure that the macro generates the optimal code? User can workaround it
with:
field_get((u8)0xf, reg)
but it may not be trivial. Can you add an example and explanation please?
> + unsigned int __shift = sizeof(mask) <= 4 ? \
> + __ffs(__mask) : __ffs64(__mask); \
Can you use BITS_PER_TYPE() here?
> + (__reg & __mask) >> __shift; \
> + })
> +
When mask == 0, we shouldn't touch 'val' at all. Consider
field_get(0, get_user(ptr))
In this case, evaluating 'reg' is an error, similarly to memcpy().
Thanks,
Yury
> #endif
> diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c
> index 828af3095b86ee0a..6eee89cbc0867f2b 100644
> --- a/sound/usb/mixer_quirks.c
> +++ b/sound/usb/mixer_quirks.c
> @@ -3311,10 +3311,6 @@ static int snd_bbfpro_controls_create(struct usb_mixer_interface *mixer)
> #define RME_DIGIFACE_REGISTER(reg, mask) (((reg) << 16) | (mask))
> #define RME_DIGIFACE_INVERT BIT(31)
>
> -/* Nonconst helpers */
> -#define field_get(_mask, _reg) (((_reg) & (_mask)) >> (ffs(_mask) - 1))
> -#define field_prep(_mask, _val) (((_val) << (ffs(_mask) - 1)) & (_mask))
> -
> static int snd_rme_digiface_write_reg(struct snd_kcontrol *kcontrol, int item, u16 mask, u16 val)
> {
> struct usb_mixer_elem_list *list = snd_kcontrol_chip(kcontrol);
> --
> 2.43.0
next prev parent reply other threads:[~2025-10-17 23:43 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-10-17 10:54 [PATCH v4 0/4] Non-const bitfield helpers Geert Uytterhoeven
2025-10-17 10:54 ` [PATCH v4 1/4] bitfield: Drop underscores from macro parameters Geert Uytterhoeven
2025-10-17 16:37 ` Yury Norov
2025-10-20 12:13 ` Geert Uytterhoeven
2025-10-20 14:56 ` Yury Norov
2025-10-17 10:54 ` [PATCH v4 2/4] bitfield: Add non-constant field_{prep,get}() helpers Geert Uytterhoeven
2025-10-17 12:33 ` Nuno Sá
2025-10-17 12:43 ` Richard GENOUD
2025-10-17 18:51 ` Yury Norov [this message]
2025-10-20 13:00 ` Geert Uytterhoeven
2025-10-22 4:20 ` Yury Norov
2025-10-22 10:01 ` Geert Uytterhoeven
2025-10-22 15:50 ` Yury Norov
2025-10-23 11:38 ` Geert Uytterhoeven
2025-10-17 10:54 ` [PATCH v4 3/4] clk: renesas: Use bitfield helpers Geert Uytterhoeven
2025-10-17 10:54 ` [PATCH v4 4/4] soc: " Geert Uytterhoeven
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=aPKQMdyMO-vrb30X@yury \
--to=yury.norov@gmail.com \
--cc=Jianping.Shen@de.bosch.com \
--cc=Jonathan.Cameron@huawei.com \
--cc=Michael.Hennerich@analog.com \
--cc=alexandre.belloni@bootlin.com \
--cc=andrew@codeconstruct.com.au \
--cc=andy@kernel.org \
--cc=biju.das.jz@bp.renesas.com \
--cc=bp@alien8.de \
--cc=brgl@bgdev.pl \
--cc=claudiu.beznea@tuxon.dev \
--cc=cmo@melexis.com \
--cc=davem@davemloft.net \
--cc=david.laight.linux@gmail.com \
--cc=demonsingur@gmail.com \
--cc=dlechner@baylibre.com \
--cc=elder@ieee.org \
--cc=geert+renesas@glider.be \
--cc=giovanni.cabiddu@intel.com \
--cc=herbert@gondor.apana.org.au \
--cc=jbaron@akamai.com \
--cc=jic23@kernel.org \
--cc=joel@jms.id.au \
--cc=johannes@sipsolutions.net \
--cc=kimseer.paller@analog.com \
--cc=kuba@kernel.org \
--cc=lars@metafoo.de \
--cc=linus.walleij@linaro.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-aspeed@lists.ozlabs.org \
--cc=linux-clk@vger.kernel.org \
--cc=linux-crypto@vger.kernel.org \
--cc=linux-edac@vger.kernel.org \
--cc=linux-gpio@vger.kernel.org \
--cc=linux-iio@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-renesas-soc@vger.kernel.org \
--cc=linux-sound@vger.kernel.org \
--cc=linux@rasmusvillemoes.dk \
--cc=mailhol.vincent@wanadoo.fr \
--cc=mturquette@baylibre.com \
--cc=nicolas.ferre@microchip.com \
--cc=nuno.sa@analog.com \
--cc=perex@perex.cz \
--cc=qat-linux@intel.com \
--cc=richard.genoud@bootlin.com \
--cc=sboyd@kernel.org \
--cc=schung@nuvoton.com \
--cc=tiwai@suse.com \
--cc=tony.luck@intel.com \
--cc=ychuang3@nuvoton.com \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.