* [PATCH v2 01/18] lib/parity: Add __builtin_parity() fallback implementations
2025-03-01 14:23 [PATCH v2 00/18] Introduce and use generic parity16/32/64 helper Kuan-Wei Chiu
@ 2025-03-01 14:23 ` Kuan-Wei Chiu
2025-03-02 3:10 ` Yury Norov
2025-03-01 14:23 ` [PATCH v2 02/18] bitops: Optimize parity8() using __builtin_parity() Kuan-Wei Chiu
` (16 subsequent siblings)
17 siblings, 1 reply; 32+ messages in thread
From: Kuan-Wei Chiu @ 2025-03-01 14:23 UTC (permalink / raw)
To: tglx, mingo, bp, dave.hansen, x86, jk, joel, eajames,
andrzej.hajda, neil.armstrong, rfoss, maarten.lankhorst, mripard,
tzimmermann, airlied, simona, dmitry.torokhov, mchehab, awalls,
hverkuil, miquel.raynal, richard, vigneshr, louis.peens,
andrew+netdev, davem, edumazet, pabeni, parthiban.veerasooran,
arend.vanspriel, johannes, gregkh, jirislaby, yury.norov, akpm
Cc: hpa, alistair, linux, Laurent.pinchart, jonas, jernej.skrabec,
kuba, linux-kernel, linux-fsi, dri-devel, linux-input,
linux-media, linux-mtd, oss-drivers, netdev, linux-wireless,
brcm80211, brcm80211-dev-list.pdl, linux-serial, bpf, jserv,
david.laight.linux, andrew.cooper3, Kuan-Wei Chiu, Yu-Chun Lin
Add generic C implementations of __paritysi2(), __paritydi2(), and
__parityti2() as fallback functions in lib/parity.c. These functions
compute the parity of a given integer using a bitwise approach and are
marked with __weak, allowing architecture-specific implementations to
override them.
This patch serves as preparation for using __builtin_parity() by
ensuring a fallback mechanism is available when the compiler does not
inline the __builtin_parity().
Co-developed-by: Yu-Chun Lin <eleanor15x@gmail.com>
Signed-off-by: Yu-Chun Lin <eleanor15x@gmail.com>
Signed-off-by: Kuan-Wei Chiu <visitorckw@gmail.com>
---
lib/Makefile | 2 +-
lib/parity.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 49 insertions(+), 1 deletion(-)
create mode 100644 lib/parity.c
diff --git a/lib/Makefile b/lib/Makefile
index 7bab71e59019..45affad85ee4 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -51,7 +51,7 @@ obj-y += bcd.o sort.o parser.o debug_locks.o random32.o \
bsearch.o find_bit.o llist.o lwq.o memweight.o kfifo.o \
percpu-refcount.o rhashtable.o base64.o \
once.o refcount.o rcuref.o usercopy.o errseq.o bucket_locks.o \
- generic-radix-tree.o bitmap-str.o
+ generic-radix-tree.o bitmap-str.o parity.o
obj-y += string_helpers.o
obj-y += hexdump.o
obj-$(CONFIG_TEST_HEXDUMP) += test_hexdump.o
diff --git a/lib/parity.c b/lib/parity.c
new file mode 100644
index 000000000000..a83ff8d96778
--- /dev/null
+++ b/lib/parity.c
@@ -0,0 +1,48 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * lib/parity.c
+ *
+ * Copyright (C) 2025 Kuan-Wei Chiu <visitorckw@gmail.com>
+ * Copyright (C) 2025 Yu-Chun Lin <eleanor15x@gmail.com>
+ *
+ * __parity[sdt]i2 can be overridden by linking arch-specific versions.
+ */
+
+#include <linux/export.h>
+#include <linux/kernel.h>
+
+/*
+ * One explanation of this algorithm:
+ * https://funloop.org/codex/problem/parity/README.html
+ */
+int __weak __paritysi2(u32 val);
+int __weak __paritysi2(u32 val)
+{
+ val ^= val >> 16;
+ val ^= val >> 8;
+ val ^= val >> 4;
+ return (0x6996 >> (val & 0xf)) & 1;
+}
+EXPORT_SYMBOL(__paritysi2);
+
+int __weak __paritydi2(u64 val);
+int __weak __paritydi2(u64 val)
+{
+ val ^= val >> 32;
+ val ^= val >> 16;
+ val ^= val >> 8;
+ val ^= val >> 4;
+ return (0x6996 >> (val & 0xf)) & 1;
+}
+EXPORT_SYMBOL(__paritydi2);
+
+int __weak __parityti2(u64 val);
+int __weak __parityti2(u64 val)
+{
+ val ^= val >> 32;
+ val ^= val >> 16;
+ val ^= val >> 8;
+ val ^= val >> 4;
+ return (0x6996 >> (val & 0xf)) & 1;
+}
+EXPORT_SYMBOL(__parityti2);
--
2.34.1
^ permalink raw reply related [flat|nested] 32+ messages in thread* Re: [PATCH v2 01/18] lib/parity: Add __builtin_parity() fallback implementations
2025-03-01 14:23 ` [PATCH v2 01/18] lib/parity: Add __builtin_parity() fallback implementations Kuan-Wei Chiu
@ 2025-03-02 3:10 ` Yury Norov
2025-03-02 8:20 ` Kuan-Wei Chiu
0 siblings, 1 reply; 32+ messages in thread
From: Yury Norov @ 2025-03-02 3:10 UTC (permalink / raw)
To: Kuan-Wei Chiu
Cc: tglx, mingo, bp, dave.hansen, x86, jk, joel, eajames,
andrzej.hajda, neil.armstrong, rfoss, maarten.lankhorst, mripard,
tzimmermann, airlied, simona, dmitry.torokhov, mchehab, awalls,
hverkuil, miquel.raynal, richard, vigneshr, louis.peens,
andrew+netdev, davem, edumazet, pabeni, parthiban.veerasooran,
arend.vanspriel, johannes, gregkh, jirislaby, akpm, hpa, alistair,
linux, Laurent.pinchart, jonas, jernej.skrabec, kuba,
linux-kernel, linux-fsi, dri-devel, linux-input, linux-media,
linux-mtd, oss-drivers, netdev, linux-wireless, brcm80211,
brcm80211-dev-list.pdl, linux-serial, bpf, jserv,
david.laight.linux, andrew.cooper3, Yu-Chun Lin
On Sat, Mar 01, 2025 at 10:23:52PM +0800, Kuan-Wei Chiu wrote:
> Add generic C implementations of __paritysi2(), __paritydi2(), and
> __parityti2() as fallback functions in lib/parity.c. These functions
> compute the parity of a given integer using a bitwise approach and are
> marked with __weak, allowing architecture-specific implementations to
> override them.
>
> This patch serves as preparation for using __builtin_parity() by
> ensuring a fallback mechanism is available when the compiler does not
> inline the __builtin_parity().
>
> Co-developed-by: Yu-Chun Lin <eleanor15x@gmail.com>
> Signed-off-by: Yu-Chun Lin <eleanor15x@gmail.com>
> Signed-off-by: Kuan-Wei Chiu <visitorckw@gmail.com>
> ---
> lib/Makefile | 2 +-
> lib/parity.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 49 insertions(+), 1 deletion(-)
> create mode 100644 lib/parity.c
>
> diff --git a/lib/Makefile b/lib/Makefile
> index 7bab71e59019..45affad85ee4 100644
> --- a/lib/Makefile
> +++ b/lib/Makefile
> @@ -51,7 +51,7 @@ obj-y += bcd.o sort.o parser.o debug_locks.o random32.o \
> bsearch.o find_bit.o llist.o lwq.o memweight.o kfifo.o \
> percpu-refcount.o rhashtable.o base64.o \
> once.o refcount.o rcuref.o usercopy.o errseq.o bucket_locks.o \
> - generic-radix-tree.o bitmap-str.o
> + generic-radix-tree.o bitmap-str.o parity.o
> obj-y += string_helpers.o
> obj-y += hexdump.o
> obj-$(CONFIG_TEST_HEXDUMP) += test_hexdump.o
> diff --git a/lib/parity.c b/lib/parity.c
> new file mode 100644
> index 000000000000..a83ff8d96778
> --- /dev/null
> +++ b/lib/parity.c
> @@ -0,0 +1,48 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * lib/parity.c
> + *
> + * Copyright (C) 2025 Kuan-Wei Chiu <visitorckw@gmail.com>
> + * Copyright (C) 2025 Yu-Chun Lin <eleanor15x@gmail.com>
> + *
> + * __parity[sdt]i2 can be overridden by linking arch-specific versions.
> + */
> +
> +#include <linux/export.h>
> +#include <linux/kernel.h>
> +
> +/*
> + * One explanation of this algorithm:
> + * https://funloop.org/codex/problem/parity/README.html
I already asked you not to spread this link. Is there any reason to
ignore it?
> + */
> +int __weak __paritysi2(u32 val);
> +int __weak __paritysi2(u32 val)
> +{
> + val ^= val >> 16;
> + val ^= val >> 8;
> + val ^= val >> 4;
> + return (0x6996 >> (val & 0xf)) & 1;
> +}
> +EXPORT_SYMBOL(__paritysi2);
> +
> +int __weak __paritydi2(u64 val);
> +int __weak __paritydi2(u64 val)
> +{
> + val ^= val >> 32;
> + val ^= val >> 16;
> + val ^= val >> 8;
> + val ^= val >> 4;
> + return (0x6996 >> (val & 0xf)) & 1;
> +}
> +EXPORT_SYMBOL(__paritydi2);
> +
> +int __weak __parityti2(u64 val);
> +int __weak __parityti2(u64 val)
> +{
> + val ^= val >> 32;
> + val ^= val >> 16;
> + val ^= val >> 8;
> + val ^= val >> 4;
> + return (0x6996 >> (val & 0xf)) & 1;
> +}
> +EXPORT_SYMBOL(__parityti2);
OK, it seems I wasn't clear enough on the previous round, so I'll try
to be very straightforward now.
To begin with, the difference between __parityti2 and __paritydi2
doesn't exist. I'm seriously. I put them side by side, and there's
no difference at all.
Next, this all is clearly an overengineering. You bake all those weak,
const and (ironically, missing) high-efficient arch implementations.
But you show no evidence that:
- it improves on code generation,
- the drivers care about parity()'s performance, and
- show no perf tests at all.
So you end up with +185/-155 LOCs.
Those +30 lines add no new functionality. You copy-paste the same
algorithm again and again in very core kernel files. This is a no-go
for a nice consolidation series.
In the previous round reviewers gave you quite a few nice suggestions.
H. Peter Anvin suggested to switch the function to return a boolean, I
suggested to make it a macro and even sent you a patch, Jiri and David
also spent their time trying to help you, and became ignored.
Nevertheless. NAK for the series. Whatever you end up, if it comes to
v3, please make it simple, avoid code duplication and run checkpatch.
Thanks,
Yury
^ permalink raw reply [flat|nested] 32+ messages in thread* Re: [PATCH v2 01/18] lib/parity: Add __builtin_parity() fallback implementations
2025-03-02 3:10 ` Yury Norov
@ 2025-03-02 8:20 ` Kuan-Wei Chiu
2025-03-02 16:02 ` Yury Norov
0 siblings, 1 reply; 32+ messages in thread
From: Kuan-Wei Chiu @ 2025-03-02 8:20 UTC (permalink / raw)
To: Yury Norov
Cc: tglx, mingo, bp, dave.hansen, x86, jk, joel, eajames,
andrzej.hajda, neil.armstrong, rfoss, maarten.lankhorst, mripard,
tzimmermann, airlied, simona, dmitry.torokhov, mchehab, awalls,
hverkuil, miquel.raynal, richard, vigneshr, louis.peens,
andrew+netdev, davem, edumazet, pabeni, parthiban.veerasooran,
arend.vanspriel, johannes, gregkh, jirislaby, akpm, hpa, alistair,
linux, Laurent.pinchart, jonas, jernej.skrabec, kuba,
linux-kernel, linux-fsi, dri-devel, linux-input, linux-media,
linux-mtd, oss-drivers, netdev, linux-wireless, brcm80211,
brcm80211-dev-list.pdl, linux-serial, bpf, jserv,
david.laight.linux, andrew.cooper3, Yu-Chun Lin
Hi Yury,
On Sat, Mar 01, 2025 at 10:10:20PM -0500, Yury Norov wrote:
> On Sat, Mar 01, 2025 at 10:23:52PM +0800, Kuan-Wei Chiu wrote:
> > Add generic C implementations of __paritysi2(), __paritydi2(), and
> > __parityti2() as fallback functions in lib/parity.c. These functions
> > compute the parity of a given integer using a bitwise approach and are
> > marked with __weak, allowing architecture-specific implementations to
> > override them.
> >
> > This patch serves as preparation for using __builtin_parity() by
> > ensuring a fallback mechanism is available when the compiler does not
> > inline the __builtin_parity().
> >
> > Co-developed-by: Yu-Chun Lin <eleanor15x@gmail.com>
> > Signed-off-by: Yu-Chun Lin <eleanor15x@gmail.com>
> > Signed-off-by: Kuan-Wei Chiu <visitorckw@gmail.com>
> > ---
> > lib/Makefile | 2 +-
> > lib/parity.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
> > 2 files changed, 49 insertions(+), 1 deletion(-)
> > create mode 100644 lib/parity.c
> >
> > diff --git a/lib/Makefile b/lib/Makefile
> > index 7bab71e59019..45affad85ee4 100644
> > --- a/lib/Makefile
> > +++ b/lib/Makefile
> > @@ -51,7 +51,7 @@ obj-y += bcd.o sort.o parser.o debug_locks.o random32.o \
> > bsearch.o find_bit.o llist.o lwq.o memweight.o kfifo.o \
> > percpu-refcount.o rhashtable.o base64.o \
> > once.o refcount.o rcuref.o usercopy.o errseq.o bucket_locks.o \
> > - generic-radix-tree.o bitmap-str.o
> > + generic-radix-tree.o bitmap-str.o parity.o
> > obj-y += string_helpers.o
> > obj-y += hexdump.o
> > obj-$(CONFIG_TEST_HEXDUMP) += test_hexdump.o
> > diff --git a/lib/parity.c b/lib/parity.c
> > new file mode 100644
> > index 000000000000..a83ff8d96778
> > --- /dev/null
> > +++ b/lib/parity.c
> > @@ -0,0 +1,48 @@
> > +// SPDX-License-Identifier: GPL-2.0-only
> > +/*
> > + * lib/parity.c
> > + *
> > + * Copyright (C) 2025 Kuan-Wei Chiu <visitorckw@gmail.com>
> > + * Copyright (C) 2025 Yu-Chun Lin <eleanor15x@gmail.com>
> > + *
> > + * __parity[sdt]i2 can be overridden by linking arch-specific versions.
> > + */
> > +
> > +#include <linux/export.h>
> > +#include <linux/kernel.h>
> > +
> > +/*
> > + * One explanation of this algorithm:
> > + * https://funloop.org/codex/problem/parity/README.html
>
> I already asked you not to spread this link. Is there any reason to
> ignore it?
>
In v2, this algorithm was removed from bitops.h, so I moved the link
here instead. I'm sorry if it seemed like I ignored your comment.
> > + */
> > +int __weak __paritysi2(u32 val);
> > +int __weak __paritysi2(u32 val)
> > +{
> > + val ^= val >> 16;
> > + val ^= val >> 8;
> > + val ^= val >> 4;
> > + return (0x6996 >> (val & 0xf)) & 1;
> > +}
> > +EXPORT_SYMBOL(__paritysi2);
> > +
> > +int __weak __paritydi2(u64 val);
> > +int __weak __paritydi2(u64 val)
> > +{
> > + val ^= val >> 32;
> > + val ^= val >> 16;
> > + val ^= val >> 8;
> > + val ^= val >> 4;
> > + return (0x6996 >> (val & 0xf)) & 1;
> > +}
> > +EXPORT_SYMBOL(__paritydi2);
> > +
> > +int __weak __parityti2(u64 val);
> > +int __weak __parityti2(u64 val)
> > +{
> > + val ^= val >> 32;
> > + val ^= val >> 16;
> > + val ^= val >> 8;
> > + val ^= val >> 4;
> > + return (0x6996 >> (val & 0xf)) & 1;
> > +}
> > +EXPORT_SYMBOL(__parityti2);
>
> OK, it seems I wasn't clear enough on the previous round, so I'll try
> to be very straightforward now.
>
> To begin with, the difference between __parityti2 and __paritydi2
> doesn't exist. I'm seriously. I put them side by side, and there's
> no difference at all.
>
> Next, this all is clearly an overengineering. You bake all those weak,
> const and (ironically, missing) high-efficient arch implementations.
> But you show no evidence that:
> - it improves on code generation,
> - the drivers care about parity()'s performance, and
> - show no perf tests at all.
>
> So you end up with +185/-155 LOCs.
>
> Those +30 lines add no new functionality. You copy-paste the same
> algorithm again and again in very core kernel files. This is a no-go
> for a nice consolidation series.
>
> In the previous round reviewers gave you quite a few nice suggestions.
> H. Peter Anvin suggested to switch the function to return a boolean, I
> suggested to make it a macro and even sent you a patch, Jiri and David
> also spent their time trying to help you, and became ignored.
>
> Nevertheless. NAK for the series. Whatever you end up, if it comes to
> v3, please make it simple, avoid code duplication and run checkpatch.
>
In v1, I used the same approach as parity8() because I couldn't justify
the performance impact in a specific driver or subsystem. However,
multiple people commented on using __builtin_parity or an x86 assembly
implementation. I'm not ignoring their feedback-I want to address these
comments. Before submitting, I sent an email explaining my current
approach: using David's suggested method along with __builtin_parity,
but no one responded. So, I decided to submit v2 for discussion
instead.
To avoid mistakes in v3, I want to confirm the following changes before
sending it:
(a) Change the return type from int to bool.
(b) Avoid __builtin_parity and use the same approach as parity8().
(c) Implement parity16/32/64() as single-line inline functions that
call the next smaller variant after xor.
(d) Add a parity() macro that selects the appropriate parityXX() based
on type size.
(e) Update users to use this parity() macro.
However, (d) may require a patch affecting multiple subsystems at once
since some places that already include bitops.h have functions named
parity(), causing conflicts. Unless we decide not to add this macro in
the end.
As for checkpatch.pl warnings, they are mostly pre-existing coding
style issues in this series. I've kept them as-is, but if preferred,
I'm fine with fixing them.
If anything is incorrect or if there are concerns, please let me know.
Regards,
Kuan-Wei
diff --git a/include/linux/bitops.h b/include/linux/bitops.h
index c1cb53cf2f0f..47b7eca8d3b7 100644
--- a/include/linux/bitops.h
+++ b/include/linux/bitops.h
@@ -260,6 +260,43 @@ static inline int parity8(u8 val)
return (0x6996 >> (val & 0xf)) & 1;
}
+static inline bool parity16(u16 val)
+{
+ return parity8(val ^ (val >> 8));
+}
+
+static inline bool parity32(u32 val)
+{
+ return parity16(val ^ (val >> 16));
+}
+
+static inline bool parity64(u64 val)
+{
+ return parity32(val ^ (val >> 32));
+}
+
+#define parity(val) \
+({ \
+ bool __ret; \
+ switch (BITS_PER_TYPE(val)) { \
+ case 64: \
+ __ret = parity64(val); \
+ break; \
+ case 32: \
+ __ret = parity32(val); \
+ break; \
+ case 16: \
+ __ret = parity16(val); \
+ break; \
+ case 8: \
+ __ret = parity8(val); \
+ break; \
+ default: \
+ BUILD_BUG(); \
+ } \
+ __ret; \
+})
+
/**
* __ffs64 - find first set bit in a 64 bit word
* @word: The 64 bit word
^ permalink raw reply related [flat|nested] 32+ messages in thread* Re: [PATCH v2 01/18] lib/parity: Add __builtin_parity() fallback implementations
2025-03-02 8:20 ` Kuan-Wei Chiu
@ 2025-03-02 16:02 ` Yury Norov
2025-03-02 17:29 ` Kuan-Wei Chiu
0 siblings, 1 reply; 32+ messages in thread
From: Yury Norov @ 2025-03-02 16:02 UTC (permalink / raw)
To: Kuan-Wei Chiu
Cc: tglx, mingo, bp, dave.hansen, x86, jk, joel, eajames,
andrzej.hajda, neil.armstrong, rfoss, maarten.lankhorst, mripard,
tzimmermann, airlied, simona, dmitry.torokhov, mchehab, awalls,
hverkuil, miquel.raynal, richard, vigneshr, louis.peens,
andrew+netdev, davem, edumazet, pabeni, parthiban.veerasooran,
arend.vanspriel, johannes, gregkh, jirislaby, akpm, hpa, alistair,
linux, Laurent.pinchart, jonas, jernej.skrabec, kuba,
linux-kernel, linux-fsi, dri-devel, linux-input, linux-media,
linux-mtd, oss-drivers, netdev, linux-wireless, brcm80211,
brcm80211-dev-list.pdl, linux-serial, bpf, jserv,
david.laight.linux, andrew.cooper3, Yu-Chun Lin
On Sun, Mar 02, 2025 at 04:20:02PM +0800, Kuan-Wei Chiu wrote:
> Hi Yury,
>
> On Sat, Mar 01, 2025 at 10:10:20PM -0500, Yury Norov wrote:
> > On Sat, Mar 01, 2025 at 10:23:52PM +0800, Kuan-Wei Chiu wrote:
> > > Add generic C implementations of __paritysi2(), __paritydi2(), and
> > > __parityti2() as fallback functions in lib/parity.c. These functions
> > > compute the parity of a given integer using a bitwise approach and are
> > > marked with __weak, allowing architecture-specific implementations to
> > > override them.
> > >
> > > This patch serves as preparation for using __builtin_parity() by
> > > ensuring a fallback mechanism is available when the compiler does not
> > > inline the __builtin_parity().
> > >
> > > Co-developed-by: Yu-Chun Lin <eleanor15x@gmail.com>
> > > Signed-off-by: Yu-Chun Lin <eleanor15x@gmail.com>
> > > Signed-off-by: Kuan-Wei Chiu <visitorckw@gmail.com>
> > > ---
> > > lib/Makefile | 2 +-
> > > lib/parity.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
> > > 2 files changed, 49 insertions(+), 1 deletion(-)
> > > create mode 100644 lib/parity.c
> > >
> > > diff --git a/lib/Makefile b/lib/Makefile
> > > index 7bab71e59019..45affad85ee4 100644
> > > --- a/lib/Makefile
> > > +++ b/lib/Makefile
> > > @@ -51,7 +51,7 @@ obj-y += bcd.o sort.o parser.o debug_locks.o random32.o \
> > > bsearch.o find_bit.o llist.o lwq.o memweight.o kfifo.o \
> > > percpu-refcount.o rhashtable.o base64.o \
> > > once.o refcount.o rcuref.o usercopy.o errseq.o bucket_locks.o \
> > > - generic-radix-tree.o bitmap-str.o
> > > + generic-radix-tree.o bitmap-str.o parity.o
> > > obj-y += string_helpers.o
> > > obj-y += hexdump.o
> > > obj-$(CONFIG_TEST_HEXDUMP) += test_hexdump.o
> > > diff --git a/lib/parity.c b/lib/parity.c
> > > new file mode 100644
> > > index 000000000000..a83ff8d96778
> > > --- /dev/null
> > > +++ b/lib/parity.c
> > > @@ -0,0 +1,48 @@
> > > +// SPDX-License-Identifier: GPL-2.0-only
> > > +/*
> > > + * lib/parity.c
> > > + *
> > > + * Copyright (C) 2025 Kuan-Wei Chiu <visitorckw@gmail.com>
> > > + * Copyright (C) 2025 Yu-Chun Lin <eleanor15x@gmail.com>
> > > + *
> > > + * __parity[sdt]i2 can be overridden by linking arch-specific versions.
> > > + */
> > > +
> > > +#include <linux/export.h>
> > > +#include <linux/kernel.h>
> > > +
> > > +/*
> > > + * One explanation of this algorithm:
> > > + * https://funloop.org/codex/problem/parity/README.html
> >
> > I already asked you not to spread this link. Is there any reason to
> > ignore it?
> >
> In v2, this algorithm was removed from bitops.h, so I moved the link
> here instead. I'm sorry if it seemed like I ignored your comment.
Yes, it is.
> In v1, I used the same approach as parity8() because I couldn't justify
> the performance impact in a specific driver or subsystem. However,
> multiple people commented on using __builtin_parity or an x86 assembly
> implementation. I'm not ignoring their feedback-I want to address these
Please ask those multiple people: are they ready to maintain all that
zoo of macros, weak implementations, arch implementations and stubs
for no clear benefit? Performance is always worth it, but again I see
not even a hint that the drivers care about performance. You don't
measure it, so don't care as well. Right?
> comments. Before submitting, I sent an email explaining my current
> approach: using David's suggested method along with __builtin_parity,
> but no one responded. So, I decided to submit v2 for discussion
> instead.
For discussion use tag RFC.
>
> To avoid mistakes in v3, I want to confirm the following changes before
> sending it:
>
> (a) Change the return type from int to bool.
> (b) Avoid __builtin_parity and use the same approach as parity8().
> (c) Implement parity16/32/64() as single-line inline functions that
> call the next smaller variant after xor.
> (d) Add a parity() macro that selects the appropriate parityXX() based
> on type size.
> (e) Update users to use this parity() macro.
>
> However, (d) may require a patch affecting multiple subsystems at once
> since some places that already include bitops.h have functions named
> parity(), causing conflicts. Unless we decide not to add this macro in
> the end.
>
> As for checkpatch.pl warnings, they are mostly pre-existing coding
> style issues in this series. I've kept them as-is, but if preferred,
> I'm fine with fixing them.
Checkpatch only complains on new lines. Particularly this patch should
trigger checkpatch warning because it adds a new file but doesn't touch
MAINTAINERS.
> If anything is incorrect or if there are concerns, please let me know.
>
> Regards,
> Kuan-Wei
>
> diff --git a/include/linux/bitops.h b/include/linux/bitops.h
> index c1cb53cf2f0f..47b7eca8d3b7 100644
> --- a/include/linux/bitops.h
> +++ b/include/linux/bitops.h
> @@ -260,6 +260,43 @@ static inline int parity8(u8 val)
> return (0x6996 >> (val & 0xf)) & 1;
> }
>
> +static inline bool parity16(u16 val)
> +{
> + return parity8(val ^ (val >> 8));
> +}
> +
> +static inline bool parity32(u32 val)
> +{
> + return parity16(val ^ (val >> 16));
> +}
> +
> +static inline bool parity64(u64 val)
> +{
> + return parity32(val ^ (val >> 32));
> +}
That was discussed between Jiri and me in v2. Fixed types functions
are needed only in a few very specific cases. With the exception of
I3C driver (which doesn't look good for both Jiri and me), all the
drivers have the type of variable passed to the parityXX() matching
the actual variable length. It means that fixed-type versions of the
parity() are simply not needed. So if we don't need them, please don't
introduce it.
> +#define parity(val) \
> +({ \
> + bool __ret; \
> + switch (BITS_PER_TYPE(val)) { \
> + case 64: \
> + __ret = parity64(val); \
> + break; \
> + case 32: \
> + __ret = parity32(val); \
> + break; \
> + case 16: \
> + __ret = parity16(val); \
> + break; \
> + case 8: \
> + __ret = parity8(val); \
> + break; \
> + default: \
> + BUILD_BUG(); \
> + } \
> + __ret; \
> +})
> +
> /**
> * __ffs64 - find first set bit in a 64 bit word
> * @word: The 64 bit word
^ permalink raw reply [flat|nested] 32+ messages in thread* Re: [PATCH v2 01/18] lib/parity: Add __builtin_parity() fallback implementations
2025-03-02 16:02 ` Yury Norov
@ 2025-03-02 17:29 ` Kuan-Wei Chiu
2025-03-02 19:09 ` David Laight
2025-03-03 15:15 ` Yury Norov
0 siblings, 2 replies; 32+ messages in thread
From: Kuan-Wei Chiu @ 2025-03-02 17:29 UTC (permalink / raw)
To: Yury Norov
Cc: tglx, mingo, bp, dave.hansen, x86, jk, joel, eajames,
andrzej.hajda, neil.armstrong, rfoss, maarten.lankhorst, mripard,
tzimmermann, airlied, simona, dmitry.torokhov, mchehab, awalls,
hverkuil, miquel.raynal, richard, vigneshr, louis.peens,
andrew+netdev, davem, edumazet, pabeni, parthiban.veerasooran,
arend.vanspriel, johannes, gregkh, jirislaby, akpm, hpa, alistair,
linux, Laurent.pinchart, jonas, jernej.skrabec, kuba,
linux-kernel, linux-fsi, dri-devel, linux-input, linux-media,
linux-mtd, oss-drivers, netdev, linux-wireless, brcm80211,
brcm80211-dev-list.pdl, linux-serial, bpf, jserv,
david.laight.linux, andrew.cooper3, Yu-Chun Lin
Hi Yury,
On Sun, Mar 02, 2025 at 11:02:12AM -0500, Yury Norov wrote:
> On Sun, Mar 02, 2025 at 04:20:02PM +0800, Kuan-Wei Chiu wrote:
> > Hi Yury,
> >
> > On Sat, Mar 01, 2025 at 10:10:20PM -0500, Yury Norov wrote:
> > > On Sat, Mar 01, 2025 at 10:23:52PM +0800, Kuan-Wei Chiu wrote:
> > > > Add generic C implementations of __paritysi2(), __paritydi2(), and
> > > > __parityti2() as fallback functions in lib/parity.c. These functions
> > > > compute the parity of a given integer using a bitwise approach and are
> > > > marked with __weak, allowing architecture-specific implementations to
> > > > override them.
> > > >
> > > > This patch serves as preparation for using __builtin_parity() by
> > > > ensuring a fallback mechanism is available when the compiler does not
> > > > inline the __builtin_parity().
> > > >
> > > > Co-developed-by: Yu-Chun Lin <eleanor15x@gmail.com>
> > > > Signed-off-by: Yu-Chun Lin <eleanor15x@gmail.com>
> > > > Signed-off-by: Kuan-Wei Chiu <visitorckw@gmail.com>
> > > > ---
> > > > lib/Makefile | 2 +-
> > > > lib/parity.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
> > > > 2 files changed, 49 insertions(+), 1 deletion(-)
> > > > create mode 100644 lib/parity.c
> > > >
> > > > diff --git a/lib/Makefile b/lib/Makefile
> > > > index 7bab71e59019..45affad85ee4 100644
> > > > --- a/lib/Makefile
> > > > +++ b/lib/Makefile
> > > > @@ -51,7 +51,7 @@ obj-y += bcd.o sort.o parser.o debug_locks.o random32.o \
> > > > bsearch.o find_bit.o llist.o lwq.o memweight.o kfifo.o \
> > > > percpu-refcount.o rhashtable.o base64.o \
> > > > once.o refcount.o rcuref.o usercopy.o errseq.o bucket_locks.o \
> > > > - generic-radix-tree.o bitmap-str.o
> > > > + generic-radix-tree.o bitmap-str.o parity.o
> > > > obj-y += string_helpers.o
> > > > obj-y += hexdump.o
> > > > obj-$(CONFIG_TEST_HEXDUMP) += test_hexdump.o
> > > > diff --git a/lib/parity.c b/lib/parity.c
> > > > new file mode 100644
> > > > index 000000000000..a83ff8d96778
> > > > --- /dev/null
> > > > +++ b/lib/parity.c
> > > > @@ -0,0 +1,48 @@
> > > > +// SPDX-License-Identifier: GPL-2.0-only
> > > > +/*
> > > > + * lib/parity.c
> > > > + *
> > > > + * Copyright (C) 2025 Kuan-Wei Chiu <visitorckw@gmail.com>
> > > > + * Copyright (C) 2025 Yu-Chun Lin <eleanor15x@gmail.com>
> > > > + *
> > > > + * __parity[sdt]i2 can be overridden by linking arch-specific versions.
> > > > + */
> > > > +
> > > > +#include <linux/export.h>
> > > > +#include <linux/kernel.h>
> > > > +
> > > > +/*
> > > > + * One explanation of this algorithm:
> > > > + * https://funloop.org/codex/problem/parity/README.html
> > >
> > > I already asked you not to spread this link. Is there any reason to
> > > ignore it?
> > >
> > In v2, this algorithm was removed from bitops.h, so I moved the link
> > here instead. I'm sorry if it seemed like I ignored your comment.
>
> Yes, it is.
>
> > In v1, I used the same approach as parity8() because I couldn't justify
> > the performance impact in a specific driver or subsystem. However,
> > multiple people commented on using __builtin_parity or an x86 assembly
> > implementation. I'm not ignoring their feedback-I want to address these
>
> Please ask those multiple people: are they ready to maintain all that
> zoo of macros, weak implementations, arch implementations and stubs
> for no clear benefit? Performance is always worth it, but again I see
> not even a hint that the drivers care about performance. You don't
> measure it, so don't care as well. Right?
>
> > comments. Before submitting, I sent an email explaining my current
> > approach: using David's suggested method along with __builtin_parity,
> > but no one responded. So, I decided to submit v2 for discussion
> > instead.
>
> For discussion use tag RFC.
>
> >
> > To avoid mistakes in v3, I want to confirm the following changes before
> > sending it:
> >
> > (a) Change the return type from int to bool.
> > (b) Avoid __builtin_parity and use the same approach as parity8().
> > (c) Implement parity16/32/64() as single-line inline functions that
> > call the next smaller variant after xor.
> > (d) Add a parity() macro that selects the appropriate parityXX() based
> > on type size.
> > (e) Update users to use this parity() macro.
> >
> > However, (d) may require a patch affecting multiple subsystems at once
> > since some places that already include bitops.h have functions named
> > parity(), causing conflicts. Unless we decide not to add this macro in
> > the end.
> >
> > As for checkpatch.pl warnings, they are mostly pre-existing coding
> > style issues in this series. I've kept them as-is, but if preferred,
> > I'm fine with fixing them.
>
> Checkpatch only complains on new lines. Particularly this patch should
> trigger checkpatch warning because it adds a new file but doesn't touch
> MAINTAINERS.
>
For example, the following warning:
ERROR: space required after that ',' (ctx:VxV)
#84: FILE: drivers/input/joystick/sidewinder.c:368:
+ if (!parity64(GB(0,33)))
^
This issue already existed before this series, and I'm keeping its
style unchanged for now.
> > If anything is incorrect or if there are concerns, please let me know.
> >
> > Regards,
> > Kuan-Wei
> >
> > diff --git a/include/linux/bitops.h b/include/linux/bitops.h
> > index c1cb53cf2f0f..47b7eca8d3b7 100644
> > --- a/include/linux/bitops.h
> > +++ b/include/linux/bitops.h
> > @@ -260,6 +260,43 @@ static inline int parity8(u8 val)
> > return (0x6996 >> (val & 0xf)) & 1;
> > }
> >
> > +static inline bool parity16(u16 val)
> > +{
> > + return parity8(val ^ (val >> 8));
> > +}
> > +
> > +static inline bool parity32(u32 val)
> > +{
> > + return parity16(val ^ (val >> 16));
> > +}
> > +
> > +static inline bool parity64(u64 val)
> > +{
> > + return parity32(val ^ (val >> 32));
> > +}
>
> That was discussed between Jiri and me in v2. Fixed types functions
> are needed only in a few very specific cases. With the exception of
> I3C driver (which doesn't look good for both Jiri and me), all the
> drivers have the type of variable passed to the parityXX() matching
> the actual variable length. It means that fixed-type versions of the
> parity() are simply not needed. So if we don't need them, please don't
> introduce it.
>
So, I should add the following parity() macro in v3, remove parity8(),
and update all current parity8() users to use this macro, right?
I changed u64 to __auto_type and applied David's suggestion to replace
the >> 32 with >> 16 >> 16 to avoid compiler warnings.
Regards,
Kuan-Wei
#define parity(val) \
({ \
__auto_type __v = (val); \
bool __ret; \
switch (BITS_PER_TYPE(val)) { \
case 64: \
__v ^= __v >> 16 >> 16; \
fallthrough; \
case 32: \
__v ^= __v >> 16; \
fallthrough; \
case 16: \
__v ^= __v >> 8; \
fallthrough; \
case 8: \
__v ^= __v >> 4; \
__ret = (0x6996 >> (__v & 0xf)) & 1; \
break; \
default: \
BUILD_BUG(); \
} \
__ret; \
})
^ permalink raw reply [flat|nested] 32+ messages in thread* Re: [PATCH v2 01/18] lib/parity: Add __builtin_parity() fallback implementations
2025-03-02 17:29 ` Kuan-Wei Chiu
@ 2025-03-02 19:09 ` David Laight
2025-03-03 2:47 ` Kuan-Wei Chiu
2025-03-03 15:25 ` Yury Norov
2025-03-03 15:15 ` Yury Norov
1 sibling, 2 replies; 32+ messages in thread
From: David Laight @ 2025-03-02 19:09 UTC (permalink / raw)
To: Kuan-Wei Chiu
Cc: Yury Norov, tglx, mingo, bp, dave.hansen, x86, jk, joel, eajames,
andrzej.hajda, neil.armstrong, rfoss, maarten.lankhorst, mripard,
tzimmermann, airlied, simona, dmitry.torokhov, mchehab, awalls,
hverkuil, miquel.raynal, richard, vigneshr, louis.peens,
andrew+netdev, davem, edumazet, pabeni, parthiban.veerasooran,
arend.vanspriel, johannes, gregkh, jirislaby, akpm, hpa, alistair,
linux, Laurent.pinchart, jonas, jernej.skrabec, kuba,
linux-kernel, linux-fsi, dri-devel, linux-input, linux-media,
linux-mtd, oss-drivers, netdev, linux-wireless, brcm80211,
brcm80211-dev-list.pdl, linux-serial, bpf, jserv, andrew.cooper3,
Yu-Chun Lin
On Mon, 3 Mar 2025 01:29:19 +0800
Kuan-Wei Chiu <visitorckw@gmail.com> wrote:
> Hi Yury,
>
> On Sun, Mar 02, 2025 at 11:02:12AM -0500, Yury Norov wrote:
> > On Sun, Mar 02, 2025 at 04:20:02PM +0800, Kuan-Wei Chiu wrote:
> > > Hi Yury,
> > >
> > > On Sat, Mar 01, 2025 at 10:10:20PM -0500, Yury Norov wrote:
> > > > On Sat, Mar 01, 2025 at 10:23:52PM +0800, Kuan-Wei Chiu wrote:
> > > > > Add generic C implementations of __paritysi2(), __paritydi2(), and
> > > > > __parityti2() as fallback functions in lib/parity.c. These functions
> > > > > compute the parity of a given integer using a bitwise approach and are
> > > > > marked with __weak, allowing architecture-specific implementations to
> > > > > override them.
> > > > >
> > > > > This patch serves as preparation for using __builtin_parity() by
> > > > > ensuring a fallback mechanism is available when the compiler does not
> > > > > inline the __builtin_parity().
> > > > >
> > > > > Co-developed-by: Yu-Chun Lin <eleanor15x@gmail.com>
> > > > > Signed-off-by: Yu-Chun Lin <eleanor15x@gmail.com>
> > > > > Signed-off-by: Kuan-Wei Chiu <visitorckw@gmail.com>
> > > > > ---
> > > > > lib/Makefile | 2 +-
> > > > > lib/parity.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
> > > > > 2 files changed, 49 insertions(+), 1 deletion(-)
> > > > > create mode 100644 lib/parity.c
> > > > >
> > > > > diff --git a/lib/Makefile b/lib/Makefile
> > > > > index 7bab71e59019..45affad85ee4 100644
> > > > > --- a/lib/Makefile
> > > > > +++ b/lib/Makefile
> > > > > @@ -51,7 +51,7 @@ obj-y += bcd.o sort.o parser.o debug_locks.o random32.o \
> > > > > bsearch.o find_bit.o llist.o lwq.o memweight.o kfifo.o \
> > > > > percpu-refcount.o rhashtable.o base64.o \
> > > > > once.o refcount.o rcuref.o usercopy.o errseq.o bucket_locks.o \
> > > > > - generic-radix-tree.o bitmap-str.o
> > > > > + generic-radix-tree.o bitmap-str.o parity.o
> > > > > obj-y += string_helpers.o
> > > > > obj-y += hexdump.o
> > > > > obj-$(CONFIG_TEST_HEXDUMP) += test_hexdump.o
> > > > > diff --git a/lib/parity.c b/lib/parity.c
> > > > > new file mode 100644
> > > > > index 000000000000..a83ff8d96778
> > > > > --- /dev/null
> > > > > +++ b/lib/parity.c
> > > > > @@ -0,0 +1,48 @@
> > > > > +// SPDX-License-Identifier: GPL-2.0-only
> > > > > +/*
> > > > > + * lib/parity.c
> > > > > + *
> > > > > + * Copyright (C) 2025 Kuan-Wei Chiu <visitorckw@gmail.com>
> > > > > + * Copyright (C) 2025 Yu-Chun Lin <eleanor15x@gmail.com>
> > > > > + *
> > > > > + * __parity[sdt]i2 can be overridden by linking arch-specific versions.
> > > > > + */
> > > > > +
> > > > > +#include <linux/export.h>
> > > > > +#include <linux/kernel.h>
> > > > > +
> > > > > +/*
> > > > > + * One explanation of this algorithm:
> > > > > + * https://funloop.org/codex/problem/parity/README.html
> > > >
> > > > I already asked you not to spread this link. Is there any reason to
> > > > ignore it?
> > > >
> > > In v2, this algorithm was removed from bitops.h, so I moved the link
> > > here instead. I'm sorry if it seemed like I ignored your comment.
> >
> > Yes, it is.
> >
> > > In v1, I used the same approach as parity8() because I couldn't justify
> > > the performance impact in a specific driver or subsystem. However,
> > > multiple people commented on using __builtin_parity or an x86 assembly
> > > implementation. I'm not ignoring their feedback-I want to address these
> >
> > Please ask those multiple people: are they ready to maintain all that
> > zoo of macros, weak implementations, arch implementations and stubs
> > for no clear benefit? Performance is always worth it, but again I see
> > not even a hint that the drivers care about performance. You don't
> > measure it, so don't care as well. Right?
> >
> > > comments. Before submitting, I sent an email explaining my current
> > > approach: using David's suggested method along with __builtin_parity,
> > > but no one responded. So, I decided to submit v2 for discussion
> > > instead.
> >
> > For discussion use tag RFC.
> >
> > >
> > > To avoid mistakes in v3, I want to confirm the following changes before
> > > sending it:
> > >
> > > (a) Change the return type from int to bool.
> > > (b) Avoid __builtin_parity and use the same approach as parity8().
> > > (c) Implement parity16/32/64() as single-line inline functions that
> > > call the next smaller variant after xor.
> > > (d) Add a parity() macro that selects the appropriate parityXX() based
> > > on type size.
> > > (e) Update users to use this parity() macro.
> > >
> > > However, (d) may require a patch affecting multiple subsystems at once
> > > since some places that already include bitops.h have functions named
> > > parity(), causing conflicts. Unless we decide not to add this macro in
> > > the end.
> > >
> > > As for checkpatch.pl warnings, they are mostly pre-existing coding
> > > style issues in this series. I've kept them as-is, but if preferred,
> > > I'm fine with fixing them.
> >
> > Checkpatch only complains on new lines. Particularly this patch should
> > trigger checkpatch warning because it adds a new file but doesn't touch
> > MAINTAINERS.
> >
> For example, the following warning:
>
> ERROR: space required after that ',' (ctx:VxV)
> #84: FILE: drivers/input/joystick/sidewinder.c:368:
> + if (!parity64(GB(0,33)))
> ^
>
> This issue already existed before this series, and I'm keeping its
> style unchanged for now.
>
> > > If anything is incorrect or if there are concerns, please let me know.
> > >
> > > Regards,
> > > Kuan-Wei
> > >
> > > diff --git a/include/linux/bitops.h b/include/linux/bitops.h
> > > index c1cb53cf2f0f..47b7eca8d3b7 100644
> > > --- a/include/linux/bitops.h
> > > +++ b/include/linux/bitops.h
> > > @@ -260,6 +260,43 @@ static inline int parity8(u8 val)
> > > return (0x6996 >> (val & 0xf)) & 1;
> > > }
> > >
> > > +static inline bool parity16(u16 val)
> > > +{
> > > + return parity8(val ^ (val >> 8));
> > > +}
> > > +
> > > +static inline bool parity32(u32 val)
> > > +{
> > > + return parity16(val ^ (val >> 16));
> > > +}
> > > +
> > > +static inline bool parity64(u64 val)
> > > +{
> > > + return parity32(val ^ (val >> 32));
> > > +}
> >
> > That was discussed between Jiri and me in v2. Fixed types functions
> > are needed only in a few very specific cases. With the exception of
> > I3C driver (which doesn't look good for both Jiri and me), all the
> > drivers have the type of variable passed to the parityXX() matching
> > the actual variable length. It means that fixed-type versions of the
> > parity() are simply not needed. So if we don't need them, please don't
> > introduce it.
> >
> So, I should add the following parity() macro in v3, remove parity8(),
> and update all current parity8() users to use this macro, right?
>
> I changed u64 to __auto_type and applied David's suggestion to replace
> the >> 32 with >> 16 >> 16 to avoid compiler warnings.
>
> Regards,
> Kuan-Wei
>
> #define parity(val) \
> ({ \
> __auto_type __v = (val); \
> bool __ret; \
> switch (BITS_PER_TYPE(val)) { \
> case 64: \
> __v ^= __v >> 16 >> 16; \
> fallthrough; \
> case 32: \
> __v ^= __v >> 16; \
> fallthrough; \
> case 16: \
> __v ^= __v >> 8; \
> fallthrough; \
> case 8: \
> __v ^= __v >> 4; \
> __ret = (0x6996 >> (__v & 0xf)) & 1; \
> break; \
> default: \
> BUILD_BUG(); \
> } \
> __ret; \
> })
I'm seeing double-register shifts for 64bit values on 32bit systems.
And gcc is doing 64bit double-register maths all the way down.
That is fixed by changing the top of the define to
#define parity(val) \
({ \
unsigned int __v = (val); \
bool __ret; \
switch (BITS_PER_TYPE(val)) { \
case 64: \
__v ^= val >> 16 >> 16; \
fallthrough; \
But it's need changing to only expand 'val' once.
Perhaps:
auto_type _val = (val);
u32 __ret = val;
and (mostly) s/__v/__ret/g
David
^ permalink raw reply [flat|nested] 32+ messages in thread* Re: [PATCH v2 01/18] lib/parity: Add __builtin_parity() fallback implementations
2025-03-02 19:09 ` David Laight
@ 2025-03-03 2:47 ` Kuan-Wei Chiu
2025-03-03 12:41 ` David Laight
2025-03-03 15:43 ` Yury Norov
2025-03-03 15:25 ` Yury Norov
1 sibling, 2 replies; 32+ messages in thread
From: Kuan-Wei Chiu @ 2025-03-03 2:47 UTC (permalink / raw)
To: David Laight
Cc: Yury Norov, tglx, mingo, bp, dave.hansen, x86, jk, joel, eajames,
andrzej.hajda, neil.armstrong, rfoss, maarten.lankhorst, mripard,
tzimmermann, airlied, simona, dmitry.torokhov, mchehab, awalls,
hverkuil, miquel.raynal, richard, vigneshr, louis.peens,
andrew+netdev, davem, edumazet, pabeni, parthiban.veerasooran,
arend.vanspriel, johannes, gregkh, jirislaby, akpm, hpa, alistair,
linux, Laurent.pinchart, jonas, jernej.skrabec, kuba,
linux-kernel, linux-fsi, dri-devel, linux-input, linux-media,
linux-mtd, oss-drivers, netdev, linux-wireless, brcm80211,
brcm80211-dev-list.pdl, linux-serial, bpf, jserv, andrew.cooper3,
Yu-Chun Lin
On Sun, Mar 02, 2025 at 07:09:54PM +0000, David Laight wrote:
> On Mon, 3 Mar 2025 01:29:19 +0800
> Kuan-Wei Chiu <visitorckw@gmail.com> wrote:
>
> > Hi Yury,
> >
> > On Sun, Mar 02, 2025 at 11:02:12AM -0500, Yury Norov wrote:
> > > On Sun, Mar 02, 2025 at 04:20:02PM +0800, Kuan-Wei Chiu wrote:
> > > > Hi Yury,
> > > >
> > > > On Sat, Mar 01, 2025 at 10:10:20PM -0500, Yury Norov wrote:
> > > > > On Sat, Mar 01, 2025 at 10:23:52PM +0800, Kuan-Wei Chiu wrote:
> > > > > > Add generic C implementations of __paritysi2(), __paritydi2(), and
> > > > > > __parityti2() as fallback functions in lib/parity.c. These functions
> > > > > > compute the parity of a given integer using a bitwise approach and are
> > > > > > marked with __weak, allowing architecture-specific implementations to
> > > > > > override them.
> > > > > >
> > > > > > This patch serves as preparation for using __builtin_parity() by
> > > > > > ensuring a fallback mechanism is available when the compiler does not
> > > > > > inline the __builtin_parity().
> > > > > >
> > > > > > Co-developed-by: Yu-Chun Lin <eleanor15x@gmail.com>
> > > > > > Signed-off-by: Yu-Chun Lin <eleanor15x@gmail.com>
> > > > > > Signed-off-by: Kuan-Wei Chiu <visitorckw@gmail.com>
> > > > > > ---
> > > > > > lib/Makefile | 2 +-
> > > > > > lib/parity.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
> > > > > > 2 files changed, 49 insertions(+), 1 deletion(-)
> > > > > > create mode 100644 lib/parity.c
> > > > > >
> > > > > > diff --git a/lib/Makefile b/lib/Makefile
> > > > > > index 7bab71e59019..45affad85ee4 100644
> > > > > > --- a/lib/Makefile
> > > > > > +++ b/lib/Makefile
> > > > > > @@ -51,7 +51,7 @@ obj-y += bcd.o sort.o parser.o debug_locks.o random32.o \
> > > > > > bsearch.o find_bit.o llist.o lwq.o memweight.o kfifo.o \
> > > > > > percpu-refcount.o rhashtable.o base64.o \
> > > > > > once.o refcount.o rcuref.o usercopy.o errseq.o bucket_locks.o \
> > > > > > - generic-radix-tree.o bitmap-str.o
> > > > > > + generic-radix-tree.o bitmap-str.o parity.o
> > > > > > obj-y += string_helpers.o
> > > > > > obj-y += hexdump.o
> > > > > > obj-$(CONFIG_TEST_HEXDUMP) += test_hexdump.o
> > > > > > diff --git a/lib/parity.c b/lib/parity.c
> > > > > > new file mode 100644
> > > > > > index 000000000000..a83ff8d96778
> > > > > > --- /dev/null
> > > > > > +++ b/lib/parity.c
> > > > > > @@ -0,0 +1,48 @@
> > > > > > +// SPDX-License-Identifier: GPL-2.0-only
> > > > > > +/*
> > > > > > + * lib/parity.c
> > > > > > + *
> > > > > > + * Copyright (C) 2025 Kuan-Wei Chiu <visitorckw@gmail.com>
> > > > > > + * Copyright (C) 2025 Yu-Chun Lin <eleanor15x@gmail.com>
> > > > > > + *
> > > > > > + * __parity[sdt]i2 can be overridden by linking arch-specific versions.
> > > > > > + */
> > > > > > +
> > > > > > +#include <linux/export.h>
> > > > > > +#include <linux/kernel.h>
> > > > > > +
> > > > > > +/*
> > > > > > + * One explanation of this algorithm:
> > > > > > + * https://funloop.org/codex/problem/parity/README.html
> > > > >
> > > > > I already asked you not to spread this link. Is there any reason to
> > > > > ignore it?
> > > > >
> > > > In v2, this algorithm was removed from bitops.h, so I moved the link
> > > > here instead. I'm sorry if it seemed like I ignored your comment.
> > >
> > > Yes, it is.
> > >
> > > > In v1, I used the same approach as parity8() because I couldn't justify
> > > > the performance impact in a specific driver or subsystem. However,
> > > > multiple people commented on using __builtin_parity or an x86 assembly
> > > > implementation. I'm not ignoring their feedback-I want to address these
> > >
> > > Please ask those multiple people: are they ready to maintain all that
> > > zoo of macros, weak implementations, arch implementations and stubs
> > > for no clear benefit? Performance is always worth it, but again I see
> > > not even a hint that the drivers care about performance. You don't
> > > measure it, so don't care as well. Right?
> > >
> > > > comments. Before submitting, I sent an email explaining my current
> > > > approach: using David's suggested method along with __builtin_parity,
> > > > but no one responded. So, I decided to submit v2 for discussion
> > > > instead.
> > >
> > > For discussion use tag RFC.
> > >
> > > >
> > > > To avoid mistakes in v3, I want to confirm the following changes before
> > > > sending it:
> > > >
> > > > (a) Change the return type from int to bool.
> > > > (b) Avoid __builtin_parity and use the same approach as parity8().
> > > > (c) Implement parity16/32/64() as single-line inline functions that
> > > > call the next smaller variant after xor.
> > > > (d) Add a parity() macro that selects the appropriate parityXX() based
> > > > on type size.
> > > > (e) Update users to use this parity() macro.
> > > >
> > > > However, (d) may require a patch affecting multiple subsystems at once
> > > > since some places that already include bitops.h have functions named
> > > > parity(), causing conflicts. Unless we decide not to add this macro in
> > > > the end.
> > > >
> > > > As for checkpatch.pl warnings, they are mostly pre-existing coding
> > > > style issues in this series. I've kept them as-is, but if preferred,
> > > > I'm fine with fixing them.
> > >
> > > Checkpatch only complains on new lines. Particularly this patch should
> > > trigger checkpatch warning because it adds a new file but doesn't touch
> > > MAINTAINERS.
> > >
> > For example, the following warning:
> >
> > ERROR: space required after that ',' (ctx:VxV)
> > #84: FILE: drivers/input/joystick/sidewinder.c:368:
> > + if (!parity64(GB(0,33)))
> > ^
> >
> > This issue already existed before this series, and I'm keeping its
> > style unchanged for now.
> >
> > > > If anything is incorrect or if there are concerns, please let me know.
> > > >
> > > > Regards,
> > > > Kuan-Wei
> > > >
> > > > diff --git a/include/linux/bitops.h b/include/linux/bitops.h
> > > > index c1cb53cf2f0f..47b7eca8d3b7 100644
> > > > --- a/include/linux/bitops.h
> > > > +++ b/include/linux/bitops.h
> > > > @@ -260,6 +260,43 @@ static inline int parity8(u8 val)
> > > > return (0x6996 >> (val & 0xf)) & 1;
> > > > }
> > > >
> > > > +static inline bool parity16(u16 val)
> > > > +{
> > > > + return parity8(val ^ (val >> 8));
> > > > +}
> > > > +
> > > > +static inline bool parity32(u32 val)
> > > > +{
> > > > + return parity16(val ^ (val >> 16));
> > > > +}
> > > > +
> > > > +static inline bool parity64(u64 val)
> > > > +{
> > > > + return parity32(val ^ (val >> 32));
> > > > +}
> > >
> > > That was discussed between Jiri and me in v2. Fixed types functions
> > > are needed only in a few very specific cases. With the exception of
> > > I3C driver (which doesn't look good for both Jiri and me), all the
> > > drivers have the type of variable passed to the parityXX() matching
> > > the actual variable length. It means that fixed-type versions of the
> > > parity() are simply not needed. So if we don't need them, please don't
> > > introduce it.
> > >
> > So, I should add the following parity() macro in v3, remove parity8(),
> > and update all current parity8() users to use this macro, right?
> >
> > I changed u64 to __auto_type and applied David's suggestion to replace
> > the >> 32 with >> 16 >> 16 to avoid compiler warnings.
> >
> > Regards,
> > Kuan-Wei
> >
> > #define parity(val) \
> > ({ \
> > __auto_type __v = (val); \
> > bool __ret; \
> > switch (BITS_PER_TYPE(val)) { \
> > case 64: \
> > __v ^= __v >> 16 >> 16; \
> > fallthrough; \
> > case 32: \
> > __v ^= __v >> 16; \
> > fallthrough; \
> > case 16: \
> > __v ^= __v >> 8; \
> > fallthrough; \
> > case 8: \
> > __v ^= __v >> 4; \
> > __ret = (0x6996 >> (__v & 0xf)) & 1; \
> > break; \
> > default: \
> > BUILD_BUG(); \
> > } \
> > __ret; \
> > })
>
> I'm seeing double-register shifts for 64bit values on 32bit systems.
> And gcc is doing 64bit double-register maths all the way down.
>
> That is fixed by changing the top of the define to
> #define parity(val) \
> ({ \
> unsigned int __v = (val); \
> bool __ret; \
> switch (BITS_PER_TYPE(val)) { \
> case 64: \
> __v ^= val >> 16 >> 16; \
> fallthrough; \
>
> But it's need changing to only expand 'val' once.
> Perhaps:
> auto_type _val = (val);
> u32 __ret = val;
> and (mostly) s/__v/__ret/g
>
I'm happy to make this change, though I'm a bit confused about how much
we care about the code generated by gcc. So this is the macro expected
in v3:
#define parity(val) \
({ \
__auto_type __v = (val); \
u32 __ret = val; \
switch (BITS_PER_TYPE(val)) { \
case 64: \
__ret ^= __v >> 16 >> 16; \
fallthrough; \
case 32: \
__ret ^= __ret >> 16; \
fallthrough; \
case 16: \
__ret ^= __ret >> 8; \
fallthrough; \
case 8: \
__ret ^= __ret >> 4; \
__ret = (0x6996 >> (__ret & 0xf)) & 1; \
break; \
default: \
BUILD_BUG(); \
} \
__ret; \
})
^ permalink raw reply [flat|nested] 32+ messages in thread* Re: [PATCH v2 01/18] lib/parity: Add __builtin_parity() fallback implementations
2025-03-03 2:47 ` Kuan-Wei Chiu
@ 2025-03-03 12:41 ` David Laight
2025-03-03 15:43 ` Yury Norov
1 sibling, 0 replies; 32+ messages in thread
From: David Laight @ 2025-03-03 12:41 UTC (permalink / raw)
To: Kuan-Wei Chiu
Cc: Yury Norov, tglx, mingo, bp, dave.hansen, x86, jk, joel, eajames,
andrzej.hajda, neil.armstrong, rfoss, maarten.lankhorst, mripard,
tzimmermann, airlied, simona, dmitry.torokhov, mchehab, awalls,
hverkuil, miquel.raynal, richard, vigneshr, louis.peens,
andrew+netdev, davem, edumazet, pabeni, parthiban.veerasooran,
arend.vanspriel, johannes, gregkh, jirislaby, akpm, hpa, alistair,
linux, Laurent.pinchart, jonas, jernej.skrabec, kuba,
linux-kernel, linux-fsi, dri-devel, linux-input, linux-media,
linux-mtd, oss-drivers, netdev, linux-wireless, brcm80211,
brcm80211-dev-list.pdl, linux-serial, bpf, jserv, andrew.cooper3,
Yu-Chun Lin
On Mon, 3 Mar 2025 10:47:20 +0800
Kuan-Wei Chiu <visitorckw@gmail.com> wrote:
> On Sun, Mar 02, 2025 at 07:09:54PM +0000, David Laight wrote:
> > On Mon, 3 Mar 2025 01:29:19 +0800
> > Kuan-Wei Chiu <visitorckw@gmail.com> wrote:
> >
> > > Hi Yury,
> > >
...
> > > #define parity(val) \
> > > ({ \
> > > __auto_type __v = (val); \
> > > bool __ret; \
> > > switch (BITS_PER_TYPE(val)) { \
> > > case 64: \
> > > __v ^= __v >> 16 >> 16; \
> > > fallthrough; \
> > > case 32: \
> > > __v ^= __v >> 16; \
> > > fallthrough; \
> > > case 16: \
> > > __v ^= __v >> 8; \
> > > fallthrough; \
> > > case 8: \
> > > __v ^= __v >> 4; \
> > > __ret = (0x6996 >> (__v & 0xf)) & 1; \
> > > break; \
> > > default: \
> > > BUILD_BUG(); \
> > > } \
> > > __ret; \
> > > })
> >
> > I'm seeing double-register shifts for 64bit values on 32bit systems.
> > And gcc is doing 64bit double-register maths all the way down.
> >
> > That is fixed by changing the top of the define to
> > #define parity(val) \
> > ({ \
> > unsigned int __v = (val); \
> > bool __ret; \
> > switch (BITS_PER_TYPE(val)) { \
> > case 64: \
> > __v ^= val >> 16 >> 16; \
> > fallthrough; \
> >
> > But it's need changing to only expand 'val' once.
> > Perhaps:
> > auto_type _val = (val);
> > u32 __ret = val;
> > and (mostly) s/__v/__ret/g
> >
> I'm happy to make this change, though I'm a bit confused about how much
> we care about the code generated by gcc. So this is the macro expected
> in v3:
There is 'good', 'bad' and 'ugly' - it was in the 'bad' to 'ugly' area.
>
> #define parity(val) \
> ({ \
> __auto_type __v = (val); \
> u32 __ret = val; \
> switch (BITS_PER_TYPE(val)) { \
> case 64: \
> __ret ^= __v >> 16 >> 16; \
> fallthrough; \
> case 32: \
> __ret ^= __ret >> 16; \
> fallthrough; \
> case 16: \
> __ret ^= __ret >> 8; \
> fallthrough; \
> case 8: \
> __ret ^= __ret >> 4; \
> __ret = (0x6996 >> (__ret & 0xf)) & 1; \
> break; \
> default: \
> BUILD_BUG(); \
> } \
> __ret; \
> })
That looks like it will avoid double-register shifts on 32bit archs.
arm64 can do slightly better (a couple of instructions) because of its
barrel shifter.
x86 can do a lot better because of the cpu 'parity' flag.
But maybe it is never used anywhere that really matters.
David
^ permalink raw reply [flat|nested] 32+ messages in thread* Re: [PATCH v2 01/18] lib/parity: Add __builtin_parity() fallback implementations
2025-03-03 2:47 ` Kuan-Wei Chiu
2025-03-03 12:41 ` David Laight
@ 2025-03-03 15:43 ` Yury Norov
2025-03-03 16:54 ` Kuan-Wei Chiu
1 sibling, 1 reply; 32+ messages in thread
From: Yury Norov @ 2025-03-03 15:43 UTC (permalink / raw)
To: Kuan-Wei Chiu
Cc: David Laight, tglx, mingo, bp, dave.hansen, x86, jk, joel,
eajames, andrzej.hajda, neil.armstrong, rfoss, maarten.lankhorst,
mripard, tzimmermann, airlied, simona, dmitry.torokhov, mchehab,
awalls, hverkuil, miquel.raynal, richard, vigneshr, louis.peens,
andrew+netdev, davem, edumazet, pabeni, parthiban.veerasooran,
arend.vanspriel, johannes, gregkh, jirislaby, akpm, hpa, alistair,
linux, Laurent.pinchart, jonas, jernej.skrabec, kuba,
linux-kernel, linux-fsi, dri-devel, linux-input, linux-media,
linux-mtd, oss-drivers, netdev, linux-wireless, brcm80211,
brcm80211-dev-list.pdl, linux-serial, bpf, jserv, andrew.cooper3,
Yu-Chun Lin
On Mon, Mar 03, 2025 at 10:47:20AM +0800, Kuan-Wei Chiu wrote:
> > > #define parity(val) \
> > > ({ \
> > > __auto_type __v = (val); \
> > > bool __ret; \
> > > switch (BITS_PER_TYPE(val)) { \
> > > case 64: \
> > > __v ^= __v >> 16 >> 16; \
> > > fallthrough; \
> > > case 32: \
> > > __v ^= __v >> 16; \
> > > fallthrough; \
> > > case 16: \
> > > __v ^= __v >> 8; \
> > > fallthrough; \
> > > case 8: \
> > > __v ^= __v >> 4; \
> > > __ret = (0x6996 >> (__v & 0xf)) & 1; \
> > > break; \
> > > default: \
> > > BUILD_BUG(); \
> > > } \
> > > __ret; \
> > > })
> >
> > I'm seeing double-register shifts for 64bit values on 32bit systems.
> > And gcc is doing 64bit double-register maths all the way down.
> >
> > That is fixed by changing the top of the define to
> > #define parity(val) \
> > ({ \
> > unsigned int __v = (val); \
> > bool __ret; \
> > switch (BITS_PER_TYPE(val)) { \
> > case 64: \
> > __v ^= val >> 16 >> 16; \
> > fallthrough; \
> >
> > But it's need changing to only expand 'val' once.
> > Perhaps:
> > auto_type _val = (val);
> > u32 __ret = val;
> > and (mostly) s/__v/__ret/g
> >
> I'm happy to make this change, though I'm a bit confused about how much
> we care about the code generated by gcc. So this is the macro expected
> in v3:
We do care about code generated by any compiler. But we don't spread
hacks here and there just to make GCC happy. This is entirely broken
strategy. Things should work the other way: compiler people should
collect real-life examples and learn from them.
I'm not happy even with this 'v >> 16 >> 16' hack, I just think that
disabling Wshift-count-overflow is the worse option. Hacking the macro
to optimize parity64() on 32-bit arch case doesn't worth it entirely.
In your patchset, you have only 3 drivers using parity64(). For each
of them, please in the commit message refer that calling generic
parity() with 64-bit argument may lead to sub-optimal code generation
with a certain compiler against 32-bit arches. If you'll get a
feedback that it's a real problem for somebody, we'll think about
mitigating it.
> #define parity(val) \
> ({ \
> __auto_type __v = (val); \
> u32 __ret = val; \
> switch (BITS_PER_TYPE(val)) { \
> case 64: \
> __ret ^= __v >> 16 >> 16; \
> fallthrough; \
> case 32: \
> __ret ^= __ret >> 16; \
> fallthrough; \
> case 16: \
> __ret ^= __ret >> 8; \
> fallthrough; \
> case 8: \
> __ret ^= __ret >> 4; \
> __ret = (0x6996 >> (__ret & 0xf)) & 1; \
> break; \
> default: \
> BUILD_BUG(); \
> } \
> __ret; \
> })
^ permalink raw reply [flat|nested] 32+ messages in thread* Re: [PATCH v2 01/18] lib/parity: Add __builtin_parity() fallback implementations
2025-03-03 15:43 ` Yury Norov
@ 2025-03-03 16:54 ` Kuan-Wei Chiu
0 siblings, 0 replies; 32+ messages in thread
From: Kuan-Wei Chiu @ 2025-03-03 16:54 UTC (permalink / raw)
To: Yury Norov
Cc: David Laight, tglx, mingo, bp, dave.hansen, x86, jk, joel,
eajames, andrzej.hajda, neil.armstrong, rfoss, maarten.lankhorst,
mripard, tzimmermann, airlied, simona, dmitry.torokhov, mchehab,
awalls, hverkuil, miquel.raynal, richard, vigneshr, louis.peens,
andrew+netdev, davem, edumazet, pabeni, parthiban.veerasooran,
arend.vanspriel, johannes, gregkh, jirislaby, akpm, hpa, alistair,
linux, Laurent.pinchart, jonas, jernej.skrabec, kuba,
linux-kernel, linux-fsi, dri-devel, linux-input, linux-media,
linux-mtd, oss-drivers, netdev, linux-wireless, brcm80211,
brcm80211-dev-list.pdl, linux-serial, bpf, jserv, andrew.cooper3,
Yu-Chun Lin
On Mon, Mar 03, 2025 at 10:43:28AM -0500, Yury Norov wrote:
> On Mon, Mar 03, 2025 at 10:47:20AM +0800, Kuan-Wei Chiu wrote:
> > > > #define parity(val) \
> > > > ({ \
> > > > __auto_type __v = (val); \
> > > > bool __ret; \
> > > > switch (BITS_PER_TYPE(val)) { \
> > > > case 64: \
> > > > __v ^= __v >> 16 >> 16; \
> > > > fallthrough; \
> > > > case 32: \
> > > > __v ^= __v >> 16; \
> > > > fallthrough; \
> > > > case 16: \
> > > > __v ^= __v >> 8; \
> > > > fallthrough; \
> > > > case 8: \
> > > > __v ^= __v >> 4; \
> > > > __ret = (0x6996 >> (__v & 0xf)) & 1; \
> > > > break; \
> > > > default: \
> > > > BUILD_BUG(); \
> > > > } \
> > > > __ret; \
> > > > })
> > >
> > > I'm seeing double-register shifts for 64bit values on 32bit systems.
> > > And gcc is doing 64bit double-register maths all the way down.
> > >
> > > That is fixed by changing the top of the define to
> > > #define parity(val) \
> > > ({ \
> > > unsigned int __v = (val); \
> > > bool __ret; \
> > > switch (BITS_PER_TYPE(val)) { \
> > > case 64: \
> > > __v ^= val >> 16 >> 16; \
> > > fallthrough; \
> > >
> > > But it's need changing to only expand 'val' once.
> > > Perhaps:
> > > auto_type _val = (val);
> > > u32 __ret = val;
> > > and (mostly) s/__v/__ret/g
> > >
> > I'm happy to make this change, though I'm a bit confused about how much
> > we care about the code generated by gcc. So this is the macro expected
> > in v3:
>
> We do care about code generated by any compiler. But we don't spread
> hacks here and there just to make GCC happy. This is entirely broken
> strategy. Things should work the other way: compiler people should
> collect real-life examples and learn from them.
>
> I'm not happy even with this 'v >> 16 >> 16' hack, I just think that
> disabling Wshift-count-overflow is the worse option. Hacking the macro
> to optimize parity64() on 32-bit arch case doesn't worth it entirely.
>
> In your patchset, you have only 3 drivers using parity64(). For each
> of them, please in the commit message refer that calling generic
> parity() with 64-bit argument may lead to sub-optimal code generation
> with a certain compiler against 32-bit arches. If you'll get a
> feedback that it's a real problem for somebody, we'll think about
> mitigating it.
>
How about reconsidering using parity8/16/32/64() instead of adding a
parity() macro? They allow compiler to generate correct code without
any hacks, and each implementation is simple and just one line. Jiri
also agreed in the previous thread that we need parity8() in cases like
the i3c driver. I think this might be the easiest solution to satisfy
most people?
Regards,
Kuan-Wei
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH v2 01/18] lib/parity: Add __builtin_parity() fallback implementations
2025-03-02 19:09 ` David Laight
2025-03-03 2:47 ` Kuan-Wei Chiu
@ 2025-03-03 15:25 ` Yury Norov
1 sibling, 0 replies; 32+ messages in thread
From: Yury Norov @ 2025-03-03 15:25 UTC (permalink / raw)
To: David Laight
Cc: Kuan-Wei Chiu, tglx, mingo, bp, dave.hansen, x86, jk, joel,
eajames, andrzej.hajda, neil.armstrong, rfoss, maarten.lankhorst,
mripard, tzimmermann, airlied, simona, dmitry.torokhov, mchehab,
awalls, hverkuil, miquel.raynal, richard, vigneshr, louis.peens,
andrew+netdev, davem, edumazet, pabeni, parthiban.veerasooran,
arend.vanspriel, johannes, gregkh, jirislaby, akpm, hpa, alistair,
linux, Laurent.pinchart, jonas, jernej.skrabec, kuba,
linux-kernel, linux-fsi, dri-devel, linux-input, linux-media,
linux-mtd, oss-drivers, netdev, linux-wireless, brcm80211,
brcm80211-dev-list.pdl, linux-serial, bpf, jserv, andrew.cooper3,
Yu-Chun Lin
On Sun, Mar 02, 2025 at 07:09:54PM +0000, David Laight wrote:
> > #define parity(val) \
> > ({ \
> > __auto_type __v = (val); \
> > bool __ret; \
> > switch (BITS_PER_TYPE(val)) { \
> > case 64: \
> > __v ^= __v >> 16 >> 16; \
> > fallthrough; \
> > case 32: \
> > __v ^= __v >> 16; \
> > fallthrough; \
> > case 16: \
> > __v ^= __v >> 8; \
> > fallthrough; \
> > case 8: \
> > __v ^= __v >> 4; \
> > __ret = (0x6996 >> (__v & 0xf)) & 1; \
> > break; \
> > default: \
> > BUILD_BUG(); \
> > } \
> > __ret; \
> > })
>
> I'm seeing double-register shifts for 64bit values on 32bit systems.
> And gcc is doing 64bit double-register maths all the way down.
If you don't like GCC code generation why don't you discuss it in GCC
maillist?
> That is fixed by changing the top of the define to
> #define parity(val) \
> ({ \
> unsigned int __v = (val); \
> bool __ret; \
> switch (BITS_PER_TYPE(val)) { \
> case 64: \
> __v ^= val >> 16 >> 16; \
> fallthrough; \
>
> But it's need changing to only expand 'val' once.
> Perhaps:
> auto_type _val = (val);
> u32 __ret = val;
> and (mostly) s/__v/__ret/g
You suggest another complication to mitigate a problem that most
likely doesn't exist. I looked through the series and found that
parity64() is used for I2C, joystick and a netronome ethernet card.
For I2C and joystick performance is definitely not a problem. For
ethernet - maybe. But I feel like you didn't compile that driver
for any 32-bit arch, and didn't test with a real hardware. So your
concern is a pure speculation.
NAK.
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH v2 01/18] lib/parity: Add __builtin_parity() fallback implementations
2025-03-02 17:29 ` Kuan-Wei Chiu
2025-03-02 19:09 ` David Laight
@ 2025-03-03 15:15 ` Yury Norov
2025-03-03 19:37 ` David Laight
1 sibling, 1 reply; 32+ messages in thread
From: Yury Norov @ 2025-03-03 15:15 UTC (permalink / raw)
To: Kuan-Wei Chiu
Cc: tglx, mingo, bp, dave.hansen, x86, jk, joel, eajames,
andrzej.hajda, neil.armstrong, rfoss, maarten.lankhorst, mripard,
tzimmermann, airlied, simona, dmitry.torokhov, mchehab, awalls,
hverkuil, miquel.raynal, richard, vigneshr, louis.peens,
andrew+netdev, davem, edumazet, pabeni, parthiban.veerasooran,
arend.vanspriel, johannes, gregkh, jirislaby, akpm, hpa, alistair,
linux, Laurent.pinchart, jonas, jernej.skrabec, kuba,
linux-kernel, linux-fsi, dri-devel, linux-input, linux-media,
linux-mtd, oss-drivers, netdev, linux-wireless, brcm80211,
brcm80211-dev-list.pdl, linux-serial, bpf, jserv,
david.laight.linux, andrew.cooper3, Yu-Chun Lin
On Mon, Mar 03, 2025 at 01:29:19AM +0800, Kuan-Wei Chiu wrote:
> Hi Yury,
>
> On Sun, Mar 02, 2025 at 11:02:12AM -0500, Yury Norov wrote:
> > On Sun, Mar 02, 2025 at 04:20:02PM +0800, Kuan-Wei Chiu wrote:
> > > Hi Yury,
> > >
> > > On Sat, Mar 01, 2025 at 10:10:20PM -0500, Yury Norov wrote:
> > > > On Sat, Mar 01, 2025 at 10:23:52PM +0800, Kuan-Wei Chiu wrote:
> > > > > Add generic C implementations of __paritysi2(), __paritydi2(), and
> > > > > __parityti2() as fallback functions in lib/parity.c. These functions
> > > > > compute the parity of a given integer using a bitwise approach and are
> > > > > marked with __weak, allowing architecture-specific implementations to
> > > > > override them.
> > > > >
> > > > > This patch serves as preparation for using __builtin_parity() by
> > > > > ensuring a fallback mechanism is available when the compiler does not
> > > > > inline the __builtin_parity().
> > > > >
> > > > > Co-developed-by: Yu-Chun Lin <eleanor15x@gmail.com>
> > > > > Signed-off-by: Yu-Chun Lin <eleanor15x@gmail.com>
> > > > > Signed-off-by: Kuan-Wei Chiu <visitorckw@gmail.com>
> > > > > ---
> > > > > lib/Makefile | 2 +-
> > > > > lib/parity.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
> > > > > 2 files changed, 49 insertions(+), 1 deletion(-)
> > > > > create mode 100644 lib/parity.c
> > > > >
> > > > > diff --git a/lib/Makefile b/lib/Makefile
> > > > > index 7bab71e59019..45affad85ee4 100644
> > > > > --- a/lib/Makefile
> > > > > +++ b/lib/Makefile
> > > > > @@ -51,7 +51,7 @@ obj-y += bcd.o sort.o parser.o debug_locks.o random32.o \
> > > > > bsearch.o find_bit.o llist.o lwq.o memweight.o kfifo.o \
> > > > > percpu-refcount.o rhashtable.o base64.o \
> > > > > once.o refcount.o rcuref.o usercopy.o errseq.o bucket_locks.o \
> > > > > - generic-radix-tree.o bitmap-str.o
> > > > > + generic-radix-tree.o bitmap-str.o parity.o
> > > > > obj-y += string_helpers.o
> > > > > obj-y += hexdump.o
> > > > > obj-$(CONFIG_TEST_HEXDUMP) += test_hexdump.o
> > > > > diff --git a/lib/parity.c b/lib/parity.c
> > > > > new file mode 100644
> > > > > index 000000000000..a83ff8d96778
> > > > > --- /dev/null
> > > > > +++ b/lib/parity.c
> > > > > @@ -0,0 +1,48 @@
> > > > > +// SPDX-License-Identifier: GPL-2.0-only
> > > > > +/*
> > > > > + * lib/parity.c
> > > > > + *
> > > > > + * Copyright (C) 2025 Kuan-Wei Chiu <visitorckw@gmail.com>
> > > > > + * Copyright (C) 2025 Yu-Chun Lin <eleanor15x@gmail.com>
> > > > > + *
> > > > > + * __parity[sdt]i2 can be overridden by linking arch-specific versions.
> > > > > + */
> > > > > +
> > > > > +#include <linux/export.h>
> > > > > +#include <linux/kernel.h>
> > > > > +
> > > > > +/*
> > > > > + * One explanation of this algorithm:
> > > > > + * https://funloop.org/codex/problem/parity/README.html
> > > >
> > > > I already asked you not to spread this link. Is there any reason to
> > > > ignore it?
> > > >
> > > In v2, this algorithm was removed from bitops.h, so I moved the link
> > > here instead. I'm sorry if it seemed like I ignored your comment.
> >
> > Yes, it is.
> >
> > > In v1, I used the same approach as parity8() because I couldn't justify
> > > the performance impact in a specific driver or subsystem. However,
> > > multiple people commented on using __builtin_parity or an x86 assembly
> > > implementation. I'm not ignoring their feedback-I want to address these
> >
> > Please ask those multiple people: are they ready to maintain all that
> > zoo of macros, weak implementations, arch implementations and stubs
> > for no clear benefit? Performance is always worth it, but again I see
> > not even a hint that the drivers care about performance. You don't
> > measure it, so don't care as well. Right?
> >
> > > comments. Before submitting, I sent an email explaining my current
> > > approach: using David's suggested method along with __builtin_parity,
> > > but no one responded. So, I decided to submit v2 for discussion
> > > instead.
> >
> > For discussion use tag RFC.
> >
> > >
> > > To avoid mistakes in v3, I want to confirm the following changes before
> > > sending it:
> > >
> > > (a) Change the return type from int to bool.
> > > (b) Avoid __builtin_parity and use the same approach as parity8().
> > > (c) Implement parity16/32/64() as single-line inline functions that
> > > call the next smaller variant after xor.
> > > (d) Add a parity() macro that selects the appropriate parityXX() based
> > > on type size.
> > > (e) Update users to use this parity() macro.
> > >
> > > However, (d) may require a patch affecting multiple subsystems at once
> > > since some places that already include bitops.h have functions named
> > > parity(), causing conflicts. Unless we decide not to add this macro in
> > > the end.
> > >
> > > As for checkpatch.pl warnings, they are mostly pre-existing coding
> > > style issues in this series. I've kept them as-is, but if preferred,
> > > I'm fine with fixing them.
> >
> > Checkpatch only complains on new lines. Particularly this patch should
> > trigger checkpatch warning because it adds a new file but doesn't touch
> > MAINTAINERS.
> >
> For example, the following warning:
>
> ERROR: space required after that ',' (ctx:VxV)
> #84: FILE: drivers/input/joystick/sidewinder.c:368:
> + if (!parity64(GB(0,33)))
> ^
>
> This issue already existed before this series, and I'm keeping its
> style unchanged for now.
>
> > > If anything is incorrect or if there are concerns, please let me know.
> > >
> > > Regards,
> > > Kuan-Wei
> > >
> > > diff --git a/include/linux/bitops.h b/include/linux/bitops.h
> > > index c1cb53cf2f0f..47b7eca8d3b7 100644
> > > --- a/include/linux/bitops.h
> > > +++ b/include/linux/bitops.h
> > > @@ -260,6 +260,43 @@ static inline int parity8(u8 val)
> > > return (0x6996 >> (val & 0xf)) & 1;
> > > }
> > >
> > > +static inline bool parity16(u16 val)
> > > +{
> > > + return parity8(val ^ (val >> 8));
> > > +}
> > > +
> > > +static inline bool parity32(u32 val)
> > > +{
> > > + return parity16(val ^ (val >> 16));
> > > +}
> > > +
> > > +static inline bool parity64(u64 val)
> > > +{
> > > + return parity32(val ^ (val >> 32));
> > > +}
> >
> > That was discussed between Jiri and me in v2. Fixed types functions
> > are needed only in a few very specific cases. With the exception of
> > I3C driver (which doesn't look good for both Jiri and me), all the
> > drivers have the type of variable passed to the parityXX() matching
> > the actual variable length. It means that fixed-type versions of the
> > parity() are simply not needed. So if we don't need them, please don't
> > introduce it.
> >
> So, I should add the following parity() macro in v3, remove parity8(),
> and update all current parity8() users to use this macro, right?
If you go with macro, please apply my patch and modify it in-place
with this __auto_type thing and GCC hack. Feel free to add your
co-developed-by, or tested, or whatever.
> I changed u64 to __auto_type and applied David's suggestion to replace
> the >> 32 with >> 16 >> 16 to avoid compiler warnings.
>
> Regards,
> Kuan-Wei
>
> #define parity(val) \
> ({ \
> __auto_type __v = (val); \
> bool __ret; \
> switch (BITS_PER_TYPE(val)) { \
> case 64: \
> __v ^= __v >> 16 >> 16; \
> fallthrough; \
This hack should be GCC-only, and well documented.
For clang it should be
__v ^= __v >> 32; \
> case 32: \
> __v ^= __v >> 16; \
> fallthrough; \
> case 16: \
> __v ^= __v >> 8; \
> fallthrough; \
> case 8: \
> __v ^= __v >> 4; \
> __ret = (0x6996 >> (__v & 0xf)) & 1; \
> break; \
> default: \
> BUILD_BUG(); \
> } \
> __ret; \
> })
^ permalink raw reply [flat|nested] 32+ messages in thread* Re: [PATCH v2 01/18] lib/parity: Add __builtin_parity() fallback implementations
2025-03-03 15:15 ` Yury Norov
@ 2025-03-03 19:37 ` David Laight
0 siblings, 0 replies; 32+ messages in thread
From: David Laight @ 2025-03-03 19:37 UTC (permalink / raw)
To: Yury Norov
Cc: Kuan-Wei Chiu, tglx, mingo, bp, dave.hansen, x86, jk, joel,
eajames, andrzej.hajda, neil.armstrong, rfoss, maarten.lankhorst,
mripard, tzimmermann, airlied, simona, dmitry.torokhov, mchehab,
awalls, hverkuil, miquel.raynal, richard, vigneshr, louis.peens,
andrew+netdev, davem, edumazet, pabeni, parthiban.veerasooran,
arend.vanspriel, johannes, gregkh, jirislaby, akpm, hpa, alistair,
linux, Laurent.pinchart, jonas, jernej.skrabec, kuba,
linux-kernel, linux-fsi, dri-devel, linux-input, linux-media,
linux-mtd, oss-drivers, netdev, linux-wireless, brcm80211,
brcm80211-dev-list.pdl, linux-serial, bpf, jserv, andrew.cooper3,
Yu-Chun Lin
On Mon, 3 Mar 2025 10:15:41 -0500
Yury Norov <yury.norov@gmail.com> wrote:
> On Mon, Mar 03, 2025 at 01:29:19AM +0800, Kuan-Wei Chiu wrote:
> > Hi Yury,
> >
> > On Sun, Mar 02, 2025 at 11:02:12AM -0500, Yury Norov wrote:
> > > On Sun, Mar 02, 2025 at 04:20:02PM +0800, Kuan-Wei Chiu wrote:
> > > > Hi Yury,
> > > >
> > > > On Sat, Mar 01, 2025 at 10:10:20PM -0500, Yury Norov wrote:
> > > > > On Sat, Mar 01, 2025 at 10:23:52PM +0800, Kuan-Wei Chiu wrote:
> > > > > > Add generic C implementations of __paritysi2(), __paritydi2(), and
> > > > > > __parityti2() as fallback functions in lib/parity.c. These functions
> > > > > > compute the parity of a given integer using a bitwise approach and are
> > > > > > marked with __weak, allowing architecture-specific implementations to
> > > > > > override them.
> > > > > >
> > > > > > This patch serves as preparation for using __builtin_parity() by
> > > > > > ensuring a fallback mechanism is available when the compiler does not
> > > > > > inline the __builtin_parity().
> > > > > >
> > > > > > Co-developed-by: Yu-Chun Lin <eleanor15x@gmail.com>
> > > > > > Signed-off-by: Yu-Chun Lin <eleanor15x@gmail.com>
> > > > > > Signed-off-by: Kuan-Wei Chiu <visitorckw@gmail.com>
> > > > > > ---
> > > > > > lib/Makefile | 2 +-
> > > > > > lib/parity.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
> > > > > > 2 files changed, 49 insertions(+), 1 deletion(-)
> > > > > > create mode 100644 lib/parity.c
> > > > > >
> > > > > > diff --git a/lib/Makefile b/lib/Makefile
> > > > > > index 7bab71e59019..45affad85ee4 100644
> > > > > > --- a/lib/Makefile
> > > > > > +++ b/lib/Makefile
> > > > > > @@ -51,7 +51,7 @@ obj-y += bcd.o sort.o parser.o debug_locks.o random32.o \
> > > > > > bsearch.o find_bit.o llist.o lwq.o memweight.o kfifo.o \
> > > > > > percpu-refcount.o rhashtable.o base64.o \
> > > > > > once.o refcount.o rcuref.o usercopy.o errseq.o bucket_locks.o \
> > > > > > - generic-radix-tree.o bitmap-str.o
> > > > > > + generic-radix-tree.o bitmap-str.o parity.o
> > > > > > obj-y += string_helpers.o
> > > > > > obj-y += hexdump.o
> > > > > > obj-$(CONFIG_TEST_HEXDUMP) += test_hexdump.o
> > > > > > diff --git a/lib/parity.c b/lib/parity.c
> > > > > > new file mode 100644
> > > > > > index 000000000000..a83ff8d96778
> > > > > > --- /dev/null
> > > > > > +++ b/lib/parity.c
> > > > > > @@ -0,0 +1,48 @@
> > > > > > +// SPDX-License-Identifier: GPL-2.0-only
> > > > > > +/*
> > > > > > + * lib/parity.c
> > > > > > + *
> > > > > > + * Copyright (C) 2025 Kuan-Wei Chiu <visitorckw@gmail.com>
> > > > > > + * Copyright (C) 2025 Yu-Chun Lin <eleanor15x@gmail.com>
> > > > > > + *
> > > > > > + * __parity[sdt]i2 can be overridden by linking arch-specific versions.
> > > > > > + */
> > > > > > +
> > > > > > +#include <linux/export.h>
> > > > > > +#include <linux/kernel.h>
> > > > > > +
> > > > > > +/*
> > > > > > + * One explanation of this algorithm:
> > > > > > + * https://funloop.org/codex/problem/parity/README.html
> > > > >
> > > > > I already asked you not to spread this link. Is there any reason to
> > > > > ignore it?
> > > > >
> > > > In v2, this algorithm was removed from bitops.h, so I moved the link
> > > > here instead. I'm sorry if it seemed like I ignored your comment.
> > >
> > > Yes, it is.
> > >
> > > > In v1, I used the same approach as parity8() because I couldn't justify
> > > > the performance impact in a specific driver or subsystem. However,
> > > > multiple people commented on using __builtin_parity or an x86 assembly
> > > > implementation. I'm not ignoring their feedback-I want to address these
> > >
> > > Please ask those multiple people: are they ready to maintain all that
> > > zoo of macros, weak implementations, arch implementations and stubs
> > > for no clear benefit? Performance is always worth it, but again I see
> > > not even a hint that the drivers care about performance. You don't
> > > measure it, so don't care as well. Right?
> > >
> > > > comments. Before submitting, I sent an email explaining my current
> > > > approach: using David's suggested method along with __builtin_parity,
> > > > but no one responded. So, I decided to submit v2 for discussion
> > > > instead.
> > >
> > > For discussion use tag RFC.
> > >
> > > >
> > > > To avoid mistakes in v3, I want to confirm the following changes before
> > > > sending it:
> > > >
> > > > (a) Change the return type from int to bool.
> > > > (b) Avoid __builtin_parity and use the same approach as parity8().
> > > > (c) Implement parity16/32/64() as single-line inline functions that
> > > > call the next smaller variant after xor.
> > > > (d) Add a parity() macro that selects the appropriate parityXX() based
> > > > on type size.
> > > > (e) Update users to use this parity() macro.
> > > >
> > > > However, (d) may require a patch affecting multiple subsystems at once
> > > > since some places that already include bitops.h have functions named
> > > > parity(), causing conflicts. Unless we decide not to add this macro in
> > > > the end.
> > > >
> > > > As for checkpatch.pl warnings, they are mostly pre-existing coding
> > > > style issues in this series. I've kept them as-is, but if preferred,
> > > > I'm fine with fixing them.
> > >
> > > Checkpatch only complains on new lines. Particularly this patch should
> > > trigger checkpatch warning because it adds a new file but doesn't touch
> > > MAINTAINERS.
> > >
> > For example, the following warning:
> >
> > ERROR: space required after that ',' (ctx:VxV)
> > #84: FILE: drivers/input/joystick/sidewinder.c:368:
> > + if (!parity64(GB(0,33)))
> > ^
> >
> > This issue already existed before this series, and I'm keeping its
> > style unchanged for now.
> >
> > > > If anything is incorrect or if there are concerns, please let me know.
> > > >
> > > > Regards,
> > > > Kuan-Wei
> > > >
> > > > diff --git a/include/linux/bitops.h b/include/linux/bitops.h
> > > > index c1cb53cf2f0f..47b7eca8d3b7 100644
> > > > --- a/include/linux/bitops.h
> > > > +++ b/include/linux/bitops.h
> > > > @@ -260,6 +260,43 @@ static inline int parity8(u8 val)
> > > > return (0x6996 >> (val & 0xf)) & 1;
> > > > }
> > > >
> > > > +static inline bool parity16(u16 val)
> > > > +{
> > > > + return parity8(val ^ (val >> 8));
> > > > +}
> > > > +
> > > > +static inline bool parity32(u32 val)
> > > > +{
> > > > + return parity16(val ^ (val >> 16));
> > > > +}
> > > > +
> > > > +static inline bool parity64(u64 val)
> > > > +{
> > > > + return parity32(val ^ (val >> 32));
> > > > +}
> > >
> > > That was discussed between Jiri and me in v2. Fixed types functions
> > > are needed only in a few very specific cases. With the exception of
> > > I3C driver (which doesn't look good for both Jiri and me), all the
> > > drivers have the type of variable passed to the parityXX() matching
> > > the actual variable length. It means that fixed-type versions of the
> > > parity() are simply not needed. So if we don't need them, please don't
> > > introduce it.
> > >
> > So, I should add the following parity() macro in v3, remove parity8(),
> > and update all current parity8() users to use this macro, right?
>
> If you go with macro, please apply my patch and modify it in-place
> with this __auto_type thing and GCC hack. Feel free to add your
> co-developed-by, or tested, or whatever.
>
> > I changed u64 to __auto_type and applied David's suggestion to replace
> > the >> 32 with >> 16 >> 16 to avoid compiler warnings.
> >
> > Regards,
> > Kuan-Wei
> >
> > #define parity(val) \
> > ({ \
> > __auto_type __v = (val); \
> > bool __ret; \
> > switch (BITS_PER_TYPE(val)) { \
> > case 64: \
> > __v ^= __v >> 16 >> 16; \
> > fallthrough; \
>
> This hack should be GCC-only, and well documented.
> For clang it should be
> __v ^= __v >> 32; \
There is no point doing a conditional - it just obscures things.
>
> > case 32: \
> > __v ^= __v >> 16; \
> > fallthrough; \
> > case 16: \
> > __v ^= __v >> 8; \
> > fallthrough; \
> > case 8: \
> > __v ^= __v >> 4; \
> > __ret = (0x6996 >> (__v & 0xf)) & 1; \
> > break; \
> > default: \
> > BUILD_BUG(); \
> > } \
> > __ret; \
> > })
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH v2 02/18] bitops: Optimize parity8() using __builtin_parity()
2025-03-01 14:23 [PATCH v2 00/18] Introduce and use generic parity16/32/64 helper Kuan-Wei Chiu
2025-03-01 14:23 ` [PATCH v2 01/18] lib/parity: Add __builtin_parity() fallback implementations Kuan-Wei Chiu
@ 2025-03-01 14:23 ` Kuan-Wei Chiu
2025-03-01 14:23 ` [PATCH v2 03/18] bitops: Add parity16(), parity32(), and parity64() helpers Kuan-Wei Chiu
` (15 subsequent siblings)
17 siblings, 0 replies; 32+ messages in thread
From: Kuan-Wei Chiu @ 2025-03-01 14:23 UTC (permalink / raw)
To: tglx, mingo, bp, dave.hansen, x86, jk, joel, eajames,
andrzej.hajda, neil.armstrong, rfoss, maarten.lankhorst, mripard,
tzimmermann, airlied, simona, dmitry.torokhov, mchehab, awalls,
hverkuil, miquel.raynal, richard, vigneshr, louis.peens,
andrew+netdev, davem, edumazet, pabeni, parthiban.veerasooran,
arend.vanspriel, johannes, gregkh, jirislaby, yury.norov, akpm
Cc: hpa, alistair, linux, Laurent.pinchart, jonas, jernej.skrabec,
kuba, linux-kernel, linux-fsi, dri-devel, linux-input,
linux-media, linux-mtd, oss-drivers, netdev, linux-wireless,
brcm80211, brcm80211-dev-list.pdl, linux-serial, bpf, jserv,
david.laight.linux, andrew.cooper3, Kuan-Wei Chiu, Yu-Chun Lin
Refactor parity8() to use __builtin_parity() when no
architecture-specific implementation is available. If the input is a
compile-time constant, expand it using the _parity_const() macro to
enable constant folding, allowing the compiler to optimize it at
compile time.
Additionally, mark parity8() with __attribute_const__ to indicate its
pure nature, ensuring better optimization opportunities.
This change improves efficiency by leveraging compiler intrinsics while
maintaining a fallback mechanism for architectures without specific
implementations.
Co-developed-by: Yu-Chun Lin <eleanor15x@gmail.com>
Signed-off-by: Yu-Chun Lin <eleanor15x@gmail.com>
Signed-off-by: Kuan-Wei Chiu <visitorckw@gmail.com>
---
include/linux/bitops.h | 30 +++++++++++++++++++++++-------
1 file changed, 23 insertions(+), 7 deletions(-)
diff --git a/include/linux/bitops.h b/include/linux/bitops.h
index c1cb53cf2f0f..4c307d9c1545 100644
--- a/include/linux/bitops.h
+++ b/include/linux/bitops.h
@@ -229,6 +229,27 @@ static inline int get_count_order_long(unsigned long l)
return (int)fls_long(--l);
}
+#define _parity_const(val) \
+({ \
+ u64 __v = (val); \
+ int __ret; \
+ __v ^= __v >> 32; \
+ __v ^= __v >> 16; \
+ __v ^= __v >> 8; \
+ __v ^= __v >> 4; \
+ __v ^= __v >> 2; \
+ __v ^= __v >> 1; \
+ __ret = __v & 1; \
+ __ret; \
+})
+
+#ifndef _parity8
+static inline __attribute_const__ int _parity8(u8 val)
+{
+ return __builtin_parity(val);
+}
+#endif
+
/**
* parity8 - get the parity of an u8 value
* @value: the value to be examined
@@ -250,14 +271,9 @@ static inline int get_count_order_long(unsigned long l)
* if (parity8(val) == 0)
* val ^= BIT(7);
*/
-static inline int parity8(u8 val)
+static inline __attribute_const__ int parity8(u8 val)
{
- /*
- * One explanation of this algorithm:
- * https://funloop.org/codex/problem/parity/README.html
- */
- val ^= val >> 4;
- return (0x6996 >> (val & 0xf)) & 1;
+ return __builtin_constant_p(val) ? _parity_const(val) : _parity8(val);
}
/**
--
2.34.1
^ permalink raw reply related [flat|nested] 32+ messages in thread* [PATCH v2 03/18] bitops: Add parity16(), parity32(), and parity64() helpers
2025-03-01 14:23 [PATCH v2 00/18] Introduce and use generic parity16/32/64 helper Kuan-Wei Chiu
2025-03-01 14:23 ` [PATCH v2 01/18] lib/parity: Add __builtin_parity() fallback implementations Kuan-Wei Chiu
2025-03-01 14:23 ` [PATCH v2 02/18] bitops: Optimize parity8() using __builtin_parity() Kuan-Wei Chiu
@ 2025-03-01 14:23 ` Kuan-Wei Chiu
2025-03-05 16:20 ` Simon Horman
2025-03-01 14:23 ` [PATCH v2 04/18] media: media/test_drivers: Replace open-coded parity calculation with parity8() Kuan-Wei Chiu
` (14 subsequent siblings)
17 siblings, 1 reply; 32+ messages in thread
From: Kuan-Wei Chiu @ 2025-03-01 14:23 UTC (permalink / raw)
To: tglx, mingo, bp, dave.hansen, x86, jk, joel, eajames,
andrzej.hajda, neil.armstrong, rfoss, maarten.lankhorst, mripard,
tzimmermann, airlied, simona, dmitry.torokhov, mchehab, awalls,
hverkuil, miquel.raynal, richard, vigneshr, louis.peens,
andrew+netdev, davem, edumazet, pabeni, parthiban.veerasooran,
arend.vanspriel, johannes, gregkh, jirislaby, yury.norov, akpm
Cc: hpa, alistair, linux, Laurent.pinchart, jonas, jernej.skrabec,
kuba, linux-kernel, linux-fsi, dri-devel, linux-input,
linux-media, linux-mtd, oss-drivers, netdev, linux-wireless,
brcm80211, brcm80211-dev-list.pdl, linux-serial, bpf, jserv,
david.laight.linux, andrew.cooper3, Kuan-Wei Chiu, Yu-Chun Lin
Introduce parity16(), parity32(), and parity64() functions for
computing parity on 16-bit, 32-bit, and 64-bit integers, respectively.
These functions use __builtin_parity() or __builtin_parityll() when
available, ensuring efficient computation. If the input is a
compile-time constant, they expand using the _parity_const() macro to
allow constant folding.
These additions provide parity computation helpers for larger integer
types, ensuring consistency and performance across different
bit-widths.
Co-developed-by: Yu-Chun Lin <eleanor15x@gmail.com>
Signed-off-by: Yu-Chun Lin <eleanor15x@gmail.com>
Signed-off-by: Kuan-Wei Chiu <visitorckw@gmail.com>
---
include/linux/bitops.h | 63 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 63 insertions(+)
diff --git a/include/linux/bitops.h b/include/linux/bitops.h
index 4c307d9c1545..41e9e7fb894b 100644
--- a/include/linux/bitops.h
+++ b/include/linux/bitops.h
@@ -276,6 +276,69 @@ static inline __attribute_const__ int parity8(u8 val)
return __builtin_constant_p(val) ? _parity_const(val) : _parity8(val);
}
+#ifndef _parity16
+static inline __attribute_const__ int _parity16(u16 val)
+{
+ return __builtin_parity(val);
+}
+#endif
+
+/**
+ * parity16 - get the parity of an u16 value
+ * @value: the value to be examined
+ *
+ * Determine the parity of the u16 argument.
+ *
+ * Returns:
+ * 0 for even parity, 1 for odd parity
+ */
+static inline __attribute_const__ int parity16(u16 val)
+{
+ return __builtin_constant_p(val) ? _parity_const(val) : _parity16(val);
+}
+
+#ifndef _parity32
+static inline __attribute_const__ int _parity32(u32 val)
+{
+ return __builtin_parity(val);
+}
+#endif
+
+/**
+ * parity32 - get the parity of an u32 value
+ * @value: the value to be examined
+ *
+ * Determine the parity of the u32 argument.
+ *
+ * Returns:
+ * 0 for even parity, 1 for odd parity
+ */
+static inline __attribute_const__ int parity32(u32 val)
+{
+ return __builtin_constant_p(val) ? _parity_const(val) : _parity32(val);
+}
+
+#ifndef _parity64
+static inline __attribute_const__ int _parity64(u64 val)
+{
+ return __builtin_parityll(val);
+}
+#endif
+
+/**
+ * parity64 - get the parity of an u64 value
+ * @value: the value to be examined
+ *
+ * Determine the parity of the u64 argument.
+ *
+ * Returns:
+ * 0 for even parity, 1 for odd parity
+ */
+static inline __attribute_const__ int parity64(u64 val)
+{
+ return __builtin_constant_p(val) ? _parity_const(val) : _parity64(val);
+}
+
/**
* __ffs64 - find first set bit in a 64 bit word
* @word: The 64 bit word
--
2.34.1
^ permalink raw reply related [flat|nested] 32+ messages in thread* Re: [PATCH v2 03/18] bitops: Add parity16(), parity32(), and parity64() helpers
2025-03-01 14:23 ` [PATCH v2 03/18] bitops: Add parity16(), parity32(), and parity64() helpers Kuan-Wei Chiu
@ 2025-03-05 16:20 ` Simon Horman
0 siblings, 0 replies; 32+ messages in thread
From: Simon Horman @ 2025-03-05 16:20 UTC (permalink / raw)
To: Kuan-Wei Chiu
Cc: tglx, mingo, bp, dave.hansen, x86, jk, joel, eajames,
andrzej.hajda, neil.armstrong, rfoss, maarten.lankhorst, mripard,
tzimmermann, airlied, simona, dmitry.torokhov, mchehab, awalls,
hverkuil, miquel.raynal, richard, vigneshr, louis.peens,
andrew+netdev, davem, edumazet, pabeni, parthiban.veerasooran,
arend.vanspriel, johannes, gregkh, jirislaby, yury.norov, akpm,
hpa, alistair, linux, Laurent.pinchart, jonas, jernej.skrabec,
kuba, linux-kernel, linux-fsi, dri-devel, linux-input,
linux-media, linux-mtd, oss-drivers, netdev, linux-wireless,
brcm80211, brcm80211-dev-list.pdl, linux-serial, bpf, jserv,
david.laight.linux, andrew.cooper3, Yu-Chun Lin
On Sat, Mar 01, 2025 at 10:23:54PM +0800, Kuan-Wei Chiu wrote:
> Introduce parity16(), parity32(), and parity64() functions for
> computing parity on 16-bit, 32-bit, and 64-bit integers, respectively.
> These functions use __builtin_parity() or __builtin_parityll() when
> available, ensuring efficient computation. If the input is a
> compile-time constant, they expand using the _parity_const() macro to
> allow constant folding.
>
> These additions provide parity computation helpers for larger integer
> types, ensuring consistency and performance across different
> bit-widths.
>
> Co-developed-by: Yu-Chun Lin <eleanor15x@gmail.com>
> Signed-off-by: Yu-Chun Lin <eleanor15x@gmail.com>
> Signed-off-by: Kuan-Wei Chiu <visitorckw@gmail.com>
> ---
> include/linux/bitops.h | 63 ++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 63 insertions(+)
>
> diff --git a/include/linux/bitops.h b/include/linux/bitops.h
> index 4c307d9c1545..41e9e7fb894b 100644
> --- a/include/linux/bitops.h
> +++ b/include/linux/bitops.h
> @@ -276,6 +276,69 @@ static inline __attribute_const__ int parity8(u8 val)
> return __builtin_constant_p(val) ? _parity_const(val) : _parity8(val);
> }
>
> +#ifndef _parity16
> +static inline __attribute_const__ int _parity16(u16 val)
> +{
> + return __builtin_parity(val);
> +}
> +#endif
> +
> +/**
> + * parity16 - get the parity of an u16 value
> + * @value: the value to be examined
nit: This really ought to be @val to match the function signature.
Likewise for parity8, parity32, and parity64.
> + *
> + * Determine the parity of the u16 argument.
> + *
> + * Returns:
> + * 0 for even parity, 1 for odd parity
> + */
> +static inline __attribute_const__ int parity16(u16 val)
> +{
> + return __builtin_constant_p(val) ? _parity_const(val) : _parity16(val);
> +}
...
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH v2 04/18] media: media/test_drivers: Replace open-coded parity calculation with parity8()
2025-03-01 14:23 [PATCH v2 00/18] Introduce and use generic parity16/32/64 helper Kuan-Wei Chiu
` (2 preceding siblings ...)
2025-03-01 14:23 ` [PATCH v2 03/18] bitops: Add parity16(), parity32(), and parity64() helpers Kuan-Wei Chiu
@ 2025-03-01 14:23 ` Kuan-Wei Chiu
2025-03-01 14:23 ` [PATCH v2 05/18] media: pci: cx18-av-vbi: " Kuan-Wei Chiu
` (13 subsequent siblings)
17 siblings, 0 replies; 32+ messages in thread
From: Kuan-Wei Chiu @ 2025-03-01 14:23 UTC (permalink / raw)
To: tglx, mingo, bp, dave.hansen, x86, jk, joel, eajames,
andrzej.hajda, neil.armstrong, rfoss, maarten.lankhorst, mripard,
tzimmermann, airlied, simona, dmitry.torokhov, mchehab, awalls,
hverkuil, miquel.raynal, richard, vigneshr, louis.peens,
andrew+netdev, davem, edumazet, pabeni, parthiban.veerasooran,
arend.vanspriel, johannes, gregkh, jirislaby, yury.norov, akpm
Cc: hpa, alistair, linux, Laurent.pinchart, jonas, jernej.skrabec,
kuba, linux-kernel, linux-fsi, dri-devel, linux-input,
linux-media, linux-mtd, oss-drivers, netdev, linux-wireless,
brcm80211, brcm80211-dev-list.pdl, linux-serial, bpf, jserv,
david.laight.linux, andrew.cooper3, Kuan-Wei Chiu, Yu-Chun Lin
Refactor parity calculations to use the standard parity8() helper. This
change eliminates redundant implementations and improves code
efficiency.
Co-developed-by: Yu-Chun Lin <eleanor15x@gmail.com>
Signed-off-by: Yu-Chun Lin <eleanor15x@gmail.com>
Signed-off-by: Kuan-Wei Chiu <visitorckw@gmail.com>
---
drivers/media/test-drivers/vivid/vivid-vbi-gen.c | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/drivers/media/test-drivers/vivid/vivid-vbi-gen.c b/drivers/media/test-drivers/vivid/vivid-vbi-gen.c
index 70a4024d461e..e0f4151bda18 100644
--- a/drivers/media/test-drivers/vivid/vivid-vbi-gen.c
+++ b/drivers/media/test-drivers/vivid/vivid-vbi-gen.c
@@ -5,6 +5,7 @@
* Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
*/
+#include <linux/bitops.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/ktime.h>
@@ -165,12 +166,7 @@ static const u8 vivid_cc_sequence2[30] = {
static u8 calc_parity(u8 val)
{
- unsigned i;
- unsigned tot = 0;
-
- for (i = 0; i < 7; i++)
- tot += (val & (1 << i)) ? 1 : 0;
- return val | ((tot & 1) ? 0 : 0x80);
+ return val | (parity8(val) ? 0 : 0x80);
}
static void vivid_vbi_gen_set_time_of_day(u8 *packet)
--
2.34.1
^ permalink raw reply related [flat|nested] 32+ messages in thread* [PATCH v2 05/18] media: pci: cx18-av-vbi: Replace open-coded parity calculation with parity8()
2025-03-01 14:23 [PATCH v2 00/18] Introduce and use generic parity16/32/64 helper Kuan-Wei Chiu
` (3 preceding siblings ...)
2025-03-01 14:23 ` [PATCH v2 04/18] media: media/test_drivers: Replace open-coded parity calculation with parity8() Kuan-Wei Chiu
@ 2025-03-01 14:23 ` Kuan-Wei Chiu
2025-03-01 14:23 ` [PATCH v2 06/18] media: saa7115: " Kuan-Wei Chiu
` (12 subsequent siblings)
17 siblings, 0 replies; 32+ messages in thread
From: Kuan-Wei Chiu @ 2025-03-01 14:23 UTC (permalink / raw)
To: tglx, mingo, bp, dave.hansen, x86, jk, joel, eajames,
andrzej.hajda, neil.armstrong, rfoss, maarten.lankhorst, mripard,
tzimmermann, airlied, simona, dmitry.torokhov, mchehab, awalls,
hverkuil, miquel.raynal, richard, vigneshr, louis.peens,
andrew+netdev, davem, edumazet, pabeni, parthiban.veerasooran,
arend.vanspriel, johannes, gregkh, jirislaby, yury.norov, akpm
Cc: hpa, alistair, linux, Laurent.pinchart, jonas, jernej.skrabec,
kuba, linux-kernel, linux-fsi, dri-devel, linux-input,
linux-media, linux-mtd, oss-drivers, netdev, linux-wireless,
brcm80211, brcm80211-dev-list.pdl, linux-serial, bpf, jserv,
david.laight.linux, andrew.cooper3, Kuan-Wei Chiu, Yu-Chun Lin
Refactor parity calculations to use the standard parity8() helper. This
change eliminates redundant implementations and improves code
efficiency.
Co-developed-by: Yu-Chun Lin <eleanor15x@gmail.com>
Signed-off-by: Yu-Chun Lin <eleanor15x@gmail.com>
Signed-off-by: Kuan-Wei Chiu <visitorckw@gmail.com>
---
drivers/media/pci/cx18/cx18-av-vbi.c | 12 ++----------
1 file changed, 2 insertions(+), 10 deletions(-)
diff --git a/drivers/media/pci/cx18/cx18-av-vbi.c b/drivers/media/pci/cx18/cx18-av-vbi.c
index 65281d40c681..1a113aad9cd4 100644
--- a/drivers/media/pci/cx18/cx18-av-vbi.c
+++ b/drivers/media/pci/cx18/cx18-av-vbi.c
@@ -8,6 +8,7 @@
*/
+#include <linux/bitops.h>
#include "cx18-driver.h"
/*
@@ -56,15 +57,6 @@ struct vbi_anc_data {
/* u8 fill[]; Variable number of fill bytes */
};
-static int odd_parity(u8 c)
-{
- c ^= (c >> 4);
- c ^= (c >> 2);
- c ^= (c >> 1);
-
- return c & 1;
-}
-
static int decode_vps(u8 *dst, u8 *p)
{
static const u8 biphase_tbl[] = {
@@ -278,7 +270,7 @@ int cx18_av_decode_vbi_line(struct v4l2_subdev *sd,
break;
case 6:
sdid = V4L2_SLICED_CAPTION_525;
- err = !odd_parity(p[0]) || !odd_parity(p[1]);
+ err = !parity8(p[0]) || !parity8(p[1]);
break;
case 9:
sdid = V4L2_SLICED_VPS;
--
2.34.1
^ permalink raw reply related [flat|nested] 32+ messages in thread* [PATCH v2 06/18] media: saa7115: Replace open-coded parity calculation with parity8()
2025-03-01 14:23 [PATCH v2 00/18] Introduce and use generic parity16/32/64 helper Kuan-Wei Chiu
` (4 preceding siblings ...)
2025-03-01 14:23 ` [PATCH v2 05/18] media: pci: cx18-av-vbi: " Kuan-Wei Chiu
@ 2025-03-01 14:23 ` Kuan-Wei Chiu
2025-03-01 14:23 ` [PATCH v2 07/18] serial: max3100: " Kuan-Wei Chiu
` (11 subsequent siblings)
17 siblings, 0 replies; 32+ messages in thread
From: Kuan-Wei Chiu @ 2025-03-01 14:23 UTC (permalink / raw)
To: tglx, mingo, bp, dave.hansen, x86, jk, joel, eajames,
andrzej.hajda, neil.armstrong, rfoss, maarten.lankhorst, mripard,
tzimmermann, airlied, simona, dmitry.torokhov, mchehab, awalls,
hverkuil, miquel.raynal, richard, vigneshr, louis.peens,
andrew+netdev, davem, edumazet, pabeni, parthiban.veerasooran,
arend.vanspriel, johannes, gregkh, jirislaby, yury.norov, akpm
Cc: hpa, alistair, linux, Laurent.pinchart, jonas, jernej.skrabec,
kuba, linux-kernel, linux-fsi, dri-devel, linux-input,
linux-media, linux-mtd, oss-drivers, netdev, linux-wireless,
brcm80211, brcm80211-dev-list.pdl, linux-serial, bpf, jserv,
david.laight.linux, andrew.cooper3, Kuan-Wei Chiu, Yu-Chun Lin
Refactor parity calculations to use the standard parity8() helper. This
change eliminates redundant implementations and improves code
efficiency.
Co-developed-by: Yu-Chun Lin <eleanor15x@gmail.com>
Signed-off-by: Yu-Chun Lin <eleanor15x@gmail.com>
Signed-off-by: Kuan-Wei Chiu <visitorckw@gmail.com>
---
drivers/media/i2c/saa7115.c | 12 ++----------
1 file changed, 2 insertions(+), 10 deletions(-)
diff --git a/drivers/media/i2c/saa7115.c b/drivers/media/i2c/saa7115.c
index a1c71187e773..b8b8f206ec3a 100644
--- a/drivers/media/i2c/saa7115.c
+++ b/drivers/media/i2c/saa7115.c
@@ -25,6 +25,7 @@
#include "saa711x_regs.h"
+#include <linux/bitops.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
@@ -664,15 +665,6 @@ static const unsigned char saa7115_init_misc[] = {
0x00, 0x00
};
-static int saa711x_odd_parity(u8 c)
-{
- c ^= (c >> 4);
- c ^= (c >> 2);
- c ^= (c >> 1);
-
- return c & 1;
-}
-
static int saa711x_decode_vps(u8 *dst, u8 *p)
{
static const u8 biphase_tbl[] = {
@@ -1227,7 +1219,7 @@ static int saa711x_decode_vbi_line(struct v4l2_subdev *sd, struct v4l2_decode_vb
vbi->type = V4L2_SLICED_TELETEXT_B;
break;
case 4:
- if (!saa711x_odd_parity(p[0]) || !saa711x_odd_parity(p[1]))
+ if (!parity8(p[0]) || !parity8(p[1]))
return 0;
vbi->type = V4L2_SLICED_CAPTION_525;
break;
--
2.34.1
^ permalink raw reply related [flat|nested] 32+ messages in thread* [PATCH v2 07/18] serial: max3100: Replace open-coded parity calculation with parity8()
2025-03-01 14:23 [PATCH v2 00/18] Introduce and use generic parity16/32/64 helper Kuan-Wei Chiu
` (5 preceding siblings ...)
2025-03-01 14:23 ` [PATCH v2 06/18] media: saa7115: " Kuan-Wei Chiu
@ 2025-03-01 14:23 ` Kuan-Wei Chiu
2025-03-01 14:23 ` [PATCH v2 08/18] lib/bch: Replace open-coded parity calculation with parity32() Kuan-Wei Chiu
` (10 subsequent siblings)
17 siblings, 0 replies; 32+ messages in thread
From: Kuan-Wei Chiu @ 2025-03-01 14:23 UTC (permalink / raw)
To: tglx, mingo, bp, dave.hansen, x86, jk, joel, eajames,
andrzej.hajda, neil.armstrong, rfoss, maarten.lankhorst, mripard,
tzimmermann, airlied, simona, dmitry.torokhov, mchehab, awalls,
hverkuil, miquel.raynal, richard, vigneshr, louis.peens,
andrew+netdev, davem, edumazet, pabeni, parthiban.veerasooran,
arend.vanspriel, johannes, gregkh, jirislaby, yury.norov, akpm
Cc: hpa, alistair, linux, Laurent.pinchart, jonas, jernej.skrabec,
kuba, linux-kernel, linux-fsi, dri-devel, linux-input,
linux-media, linux-mtd, oss-drivers, netdev, linux-wireless,
brcm80211, brcm80211-dev-list.pdl, linux-serial, bpf, jserv,
david.laight.linux, andrew.cooper3, Kuan-Wei Chiu, Yu-Chun Lin
Refactor parity calculations to use the standard parity8() helper. This
change eliminates redundant implementations and improves code
efficiency.
Co-developed-by: Yu-Chun Lin <eleanor15x@gmail.com>
Signed-off-by: Yu-Chun Lin <eleanor15x@gmail.com>
Signed-off-by: Kuan-Wei Chiu <visitorckw@gmail.com>
---
drivers/tty/serial/max3100.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/tty/serial/max3100.c b/drivers/tty/serial/max3100.c
index cde5f1c86353..3b05ed113a67 100644
--- a/drivers/tty/serial/max3100.c
+++ b/drivers/tty/serial/max3100.c
@@ -16,6 +16,7 @@
/* 4 MAX3100s should be enough for everyone */
#define MAX_MAX3100 4
+#include <linux/bitops.h>
#include <linux/container_of.h>
#include <linux/delay.h>
#include <linux/device.h>
@@ -133,7 +134,7 @@ static int max3100_do_parity(struct max3100_port *s, u16 c)
else
c &= 0xff;
- parity = parity ^ (hweight8(c) & 1);
+ parity = parity ^ parity8(c);
return parity;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 32+ messages in thread* [PATCH v2 08/18] lib/bch: Replace open-coded parity calculation with parity32()
2025-03-01 14:23 [PATCH v2 00/18] Introduce and use generic parity16/32/64 helper Kuan-Wei Chiu
` (6 preceding siblings ...)
2025-03-01 14:23 ` [PATCH v2 07/18] serial: max3100: " Kuan-Wei Chiu
@ 2025-03-01 14:23 ` Kuan-Wei Chiu
2025-03-01 14:24 ` [PATCH v2 09/18] Input: joystick - " Kuan-Wei Chiu
` (9 subsequent siblings)
17 siblings, 0 replies; 32+ messages in thread
From: Kuan-Wei Chiu @ 2025-03-01 14:23 UTC (permalink / raw)
To: tglx, mingo, bp, dave.hansen, x86, jk, joel, eajames,
andrzej.hajda, neil.armstrong, rfoss, maarten.lankhorst, mripard,
tzimmermann, airlied, simona, dmitry.torokhov, mchehab, awalls,
hverkuil, miquel.raynal, richard, vigneshr, louis.peens,
andrew+netdev, davem, edumazet, pabeni, parthiban.veerasooran,
arend.vanspriel, johannes, gregkh, jirislaby, yury.norov, akpm
Cc: hpa, alistair, linux, Laurent.pinchart, jonas, jernej.skrabec,
kuba, linux-kernel, linux-fsi, dri-devel, linux-input,
linux-media, linux-mtd, oss-drivers, netdev, linux-wireless,
brcm80211, brcm80211-dev-list.pdl, linux-serial, bpf, jserv,
david.laight.linux, andrew.cooper3, Kuan-Wei Chiu, Yu-Chun Lin
Refactor parity calculations to use the standard parity32() helper.
This change eliminates redundant implementations and improves code
efficiency.
Co-developed-by: Yu-Chun Lin <eleanor15x@gmail.com>
Signed-off-by: Yu-Chun Lin <eleanor15x@gmail.com>
Signed-off-by: Kuan-Wei Chiu <visitorckw@gmail.com>
---
lib/bch.c | 14 +-------------
1 file changed, 1 insertion(+), 13 deletions(-)
diff --git a/lib/bch.c b/lib/bch.c
index 1c0cb07cdfeb..769459749982 100644
--- a/lib/bch.c
+++ b/lib/bch.c
@@ -311,18 +311,6 @@ static inline int deg(unsigned int poly)
return fls(poly)-1;
}
-static inline int parity(unsigned int x)
-{
- /*
- * public domain code snippet, lifted from
- * http://www-graphics.stanford.edu/~seander/bithacks.html
- */
- x ^= x >> 1;
- x ^= x >> 2;
- x = (x & 0x11111111U) * 0x11111111U;
- return (x >> 28) & 1;
-}
-
/* Galois field basic operations: multiply, divide, inverse, etc. */
static inline unsigned int gf_mul(struct bch_control *bch, unsigned int a,
@@ -524,7 +512,7 @@ static int solve_linear_system(struct bch_control *bch, unsigned int *rows,
tmp = 0;
for (r = m-1; r >= 0; r--) {
mask = rows[r] & (tmp|1);
- tmp |= parity(mask) << (m-r);
+ tmp |= parity32(mask) << (m-r);
}
sol[p] = tmp >> 1;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 32+ messages in thread* [PATCH v2 09/18] Input: joystick - Replace open-coded parity calculation with parity32()
2025-03-01 14:23 [PATCH v2 00/18] Introduce and use generic parity16/32/64 helper Kuan-Wei Chiu
` (7 preceding siblings ...)
2025-03-01 14:23 ` [PATCH v2 08/18] lib/bch: Replace open-coded parity calculation with parity32() Kuan-Wei Chiu
@ 2025-03-01 14:24 ` Kuan-Wei Chiu
2025-03-01 14:24 ` [PATCH v2 10/18] net: ethernet: oa_tc6: " Kuan-Wei Chiu
` (8 subsequent siblings)
17 siblings, 0 replies; 32+ messages in thread
From: Kuan-Wei Chiu @ 2025-03-01 14:24 UTC (permalink / raw)
To: tglx, mingo, bp, dave.hansen, x86, jk, joel, eajames,
andrzej.hajda, neil.armstrong, rfoss, maarten.lankhorst, mripard,
tzimmermann, airlied, simona, dmitry.torokhov, mchehab, awalls,
hverkuil, miquel.raynal, richard, vigneshr, louis.peens,
andrew+netdev, davem, edumazet, pabeni, parthiban.veerasooran,
arend.vanspriel, johannes, gregkh, jirislaby, yury.norov, akpm
Cc: hpa, alistair, linux, Laurent.pinchart, jonas, jernej.skrabec,
kuba, linux-kernel, linux-fsi, dri-devel, linux-input,
linux-media, linux-mtd, oss-drivers, netdev, linux-wireless,
brcm80211, brcm80211-dev-list.pdl, linux-serial, bpf, jserv,
david.laight.linux, andrew.cooper3, Kuan-Wei Chiu, Yu-Chun Lin
Refactor parity calculations to use the standard parity32() helper.
This change eliminates redundant implementations and improves code
efficiency.
Co-developed-by: Yu-Chun Lin <eleanor15x@gmail.com>
Signed-off-by: Yu-Chun Lin <eleanor15x@gmail.com>
Signed-off-by: Kuan-Wei Chiu <visitorckw@gmail.com>
---
drivers/input/joystick/grip_mp.c | 17 ++---------------
1 file changed, 2 insertions(+), 15 deletions(-)
diff --git a/drivers/input/joystick/grip_mp.c b/drivers/input/joystick/grip_mp.c
index 5eadb5a3ca37..897ce13753dc 100644
--- a/drivers/input/joystick/grip_mp.c
+++ b/drivers/input/joystick/grip_mp.c
@@ -18,6 +18,7 @@
#include <linux/delay.h>
#include <linux/proc_fs.h>
#include <linux/jiffies.h>
+#include <linux/bitops.h>
#define DRIVER_DESC "Gravis Grip Multiport driver"
@@ -112,20 +113,6 @@ static const int axis_map[] = { 5, 9, 1, 5, 6, 10, 2, 6, 4, 8, 0, 4, 5, 9, 1, 5
static int register_slot(int i, struct grip_mp *grip);
-/*
- * Returns whether an odd or even number of bits are on in pkt.
- */
-
-static int bit_parity(u32 pkt)
-{
- int x = pkt ^ (pkt >> 16);
- x ^= x >> 8;
- x ^= x >> 4;
- x ^= x >> 2;
- x ^= x >> 1;
- return x & 1;
-}
-
/*
* Poll gameport; return true if all bits set in 'onbits' are on and
* all bits set in 'offbits' are off.
@@ -236,7 +223,7 @@ static int mp_io(struct gameport* gameport, int sendflags, int sendcode, u32 *pa
pkt = (pkt >> 2) | 0xf0000000;
}
- if (bit_parity(pkt) == 1)
+ if (parity32(pkt) == 1)
return IO_RESET;
/* Acknowledge packet receipt */
--
2.34.1
^ permalink raw reply related [flat|nested] 32+ messages in thread* [PATCH v2 10/18] net: ethernet: oa_tc6: Replace open-coded parity calculation with parity32()
2025-03-01 14:23 [PATCH v2 00/18] Introduce and use generic parity16/32/64 helper Kuan-Wei Chiu
` (8 preceding siblings ...)
2025-03-01 14:24 ` [PATCH v2 09/18] Input: joystick - " Kuan-Wei Chiu
@ 2025-03-01 14:24 ` Kuan-Wei Chiu
2025-03-01 14:24 ` [PATCH v2 11/18] wifi: brcm80211: " Kuan-Wei Chiu
` (7 subsequent siblings)
17 siblings, 0 replies; 32+ messages in thread
From: Kuan-Wei Chiu @ 2025-03-01 14:24 UTC (permalink / raw)
To: tglx, mingo, bp, dave.hansen, x86, jk, joel, eajames,
andrzej.hajda, neil.armstrong, rfoss, maarten.lankhorst, mripard,
tzimmermann, airlied, simona, dmitry.torokhov, mchehab, awalls,
hverkuil, miquel.raynal, richard, vigneshr, louis.peens,
andrew+netdev, davem, edumazet, pabeni, parthiban.veerasooran,
arend.vanspriel, johannes, gregkh, jirislaby, yury.norov, akpm
Cc: hpa, alistair, linux, Laurent.pinchart, jonas, jernej.skrabec,
kuba, linux-kernel, linux-fsi, dri-devel, linux-input,
linux-media, linux-mtd, oss-drivers, netdev, linux-wireless,
brcm80211, brcm80211-dev-list.pdl, linux-serial, bpf, jserv,
david.laight.linux, andrew.cooper3, Kuan-Wei Chiu, Yu-Chun Lin
Refactor parity calculations to use the standard parity32() helper.
This change eliminates redundant implementations and improves code
efficiency.
Co-developed-by: Yu-Chun Lin <eleanor15x@gmail.com>
Signed-off-by: Yu-Chun Lin <eleanor15x@gmail.com>
Signed-off-by: Kuan-Wei Chiu <visitorckw@gmail.com>
---
drivers/net/ethernet/oa_tc6.c | 19 +++----------------
1 file changed, 3 insertions(+), 16 deletions(-)
diff --git a/drivers/net/ethernet/oa_tc6.c b/drivers/net/ethernet/oa_tc6.c
index db200e4ec284..f02dba7b89a1 100644
--- a/drivers/net/ethernet/oa_tc6.c
+++ b/drivers/net/ethernet/oa_tc6.c
@@ -6,6 +6,7 @@
*/
#include <linux/bitfield.h>
+#include <linux/bitops.h>
#include <linux/iopoll.h>
#include <linux/mdio.h>
#include <linux/phy.h>
@@ -177,19 +178,6 @@ static int oa_tc6_spi_transfer(struct oa_tc6 *tc6,
return spi_sync(tc6->spi, &msg);
}
-static int oa_tc6_get_parity(u32 p)
-{
- /* Public domain code snippet, lifted from
- * http://www-graphics.stanford.edu/~seander/bithacks.html
- */
- p ^= p >> 1;
- p ^= p >> 2;
- p = (p & 0x11111111U) * 0x11111111U;
-
- /* Odd parity is used here */
- return !((p >> 28) & 1);
-}
-
static __be32 oa_tc6_prepare_ctrl_header(u32 addr, u8 length,
enum oa_tc6_register_op reg_op)
{
@@ -202,7 +190,7 @@ static __be32 oa_tc6_prepare_ctrl_header(u32 addr, u8 length,
FIELD_PREP(OA_TC6_CTRL_HEADER_ADDR, addr) |
FIELD_PREP(OA_TC6_CTRL_HEADER_LENGTH, length - 1);
header |= FIELD_PREP(OA_TC6_CTRL_HEADER_PARITY,
- oa_tc6_get_parity(header));
+ !parity32(header));
return cpu_to_be32(header);
}
@@ -940,8 +928,7 @@ static __be32 oa_tc6_prepare_data_header(bool data_valid, bool start_valid,
FIELD_PREP(OA_TC6_DATA_HEADER_END_BYTE_OFFSET,
end_byte_offset);
- header |= FIELD_PREP(OA_TC6_DATA_HEADER_PARITY,
- oa_tc6_get_parity(header));
+ header |= FIELD_PREP(OA_TC6_DATA_HEADER_PARITY, !parity32(header));
return cpu_to_be32(header);
}
--
2.34.1
^ permalink raw reply related [flat|nested] 32+ messages in thread* [PATCH v2 11/18] wifi: brcm80211: Replace open-coded parity calculation with parity32()
2025-03-01 14:23 [PATCH v2 00/18] Introduce and use generic parity16/32/64 helper Kuan-Wei Chiu
` (9 preceding siblings ...)
2025-03-01 14:24 ` [PATCH v2 10/18] net: ethernet: oa_tc6: " Kuan-Wei Chiu
@ 2025-03-01 14:24 ` Kuan-Wei Chiu
2025-03-01 14:24 ` [PATCH v2 12/18] drm/bridge: dw-hdmi: " Kuan-Wei Chiu
` (6 subsequent siblings)
17 siblings, 0 replies; 32+ messages in thread
From: Kuan-Wei Chiu @ 2025-03-01 14:24 UTC (permalink / raw)
To: tglx, mingo, bp, dave.hansen, x86, jk, joel, eajames,
andrzej.hajda, neil.armstrong, rfoss, maarten.lankhorst, mripard,
tzimmermann, airlied, simona, dmitry.torokhov, mchehab, awalls,
hverkuil, miquel.raynal, richard, vigneshr, louis.peens,
andrew+netdev, davem, edumazet, pabeni, parthiban.veerasooran,
arend.vanspriel, johannes, gregkh, jirislaby, yury.norov, akpm
Cc: hpa, alistair, linux, Laurent.pinchart, jonas, jernej.skrabec,
kuba, linux-kernel, linux-fsi, dri-devel, linux-input,
linux-media, linux-mtd, oss-drivers, netdev, linux-wireless,
brcm80211, brcm80211-dev-list.pdl, linux-serial, bpf, jserv,
david.laight.linux, andrew.cooper3, Kuan-Wei Chiu, Yu-Chun Lin
Refactor parity calculations to use the standard parity32() helper.
This change eliminates redundant implementations and improves code
efficiency.
Co-developed-by: Yu-Chun Lin <eleanor15x@gmail.com>
Signed-off-by: Yu-Chun Lin <eleanor15x@gmail.com>
Signed-off-by: Kuan-Wei Chiu <visitorckw@gmail.com>
Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
---
.../wireless/broadcom/brcm80211/brcmsmac/dma.c | 16 +---------------
1 file changed, 1 insertion(+), 15 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/dma.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/dma.c
index 80c35027787a..d1a1ecd97d42 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/dma.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/dma.c
@@ -17,6 +17,7 @@
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/pci.h>
+#include <linux/bitops.h>
#include <net/cfg80211.h>
#include <net/mac80211.h>
@@ -283,21 +284,6 @@ struct dma_info {
bool aligndesc_4k;
};
-/* Check for odd number of 1's */
-static u32 parity32(__le32 data)
-{
- /* no swap needed for counting 1's */
- u32 par_data = *(u32 *)&data;
-
- par_data ^= par_data >> 16;
- par_data ^= par_data >> 8;
- par_data ^= par_data >> 4;
- par_data ^= par_data >> 2;
- par_data ^= par_data >> 1;
-
- return par_data & 1;
-}
-
static bool dma64_dd_parity(struct dma64desc *dd)
{
return parity32(dd->addrlow ^ dd->addrhigh ^ dd->ctrl1 ^ dd->ctrl2);
--
2.34.1
^ permalink raw reply related [flat|nested] 32+ messages in thread* [PATCH v2 12/18] drm/bridge: dw-hdmi: Replace open-coded parity calculation with parity32()
2025-03-01 14:23 [PATCH v2 00/18] Introduce and use generic parity16/32/64 helper Kuan-Wei Chiu
` (10 preceding siblings ...)
2025-03-01 14:24 ` [PATCH v2 11/18] wifi: brcm80211: " Kuan-Wei Chiu
@ 2025-03-01 14:24 ` Kuan-Wei Chiu
2025-03-01 14:24 ` [PATCH v2 13/18] mtd: ssfdc: " Kuan-Wei Chiu
` (5 subsequent siblings)
17 siblings, 0 replies; 32+ messages in thread
From: Kuan-Wei Chiu @ 2025-03-01 14:24 UTC (permalink / raw)
To: tglx, mingo, bp, dave.hansen, x86, jk, joel, eajames,
andrzej.hajda, neil.armstrong, rfoss, maarten.lankhorst, mripard,
tzimmermann, airlied, simona, dmitry.torokhov, mchehab, awalls,
hverkuil, miquel.raynal, richard, vigneshr, louis.peens,
andrew+netdev, davem, edumazet, pabeni, parthiban.veerasooran,
arend.vanspriel, johannes, gregkh, jirislaby, yury.norov, akpm
Cc: hpa, alistair, linux, Laurent.pinchart, jonas, jernej.skrabec,
kuba, linux-kernel, linux-fsi, dri-devel, linux-input,
linux-media, linux-mtd, oss-drivers, netdev, linux-wireless,
brcm80211, brcm80211-dev-list.pdl, linux-serial, bpf, jserv,
david.laight.linux, andrew.cooper3, Kuan-Wei Chiu, Yu-Chun Lin
Refactor parity calculations to use the standard parity32() helper.
This change eliminates redundant implementations and improves code
efficiency.
Co-developed-by: Yu-Chun Lin <eleanor15x@gmail.com>
Signed-off-by: Yu-Chun Lin <eleanor15x@gmail.com>
Signed-off-by: Kuan-Wei Chiu <visitorckw@gmail.com>
---
drivers/gpu/drm/bridge/synopsys/dw-hdmi-ahb-audio.c | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-ahb-audio.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-ahb-audio.c
index cf1f66b7b192..833e65f33483 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-ahb-audio.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-ahb-audio.c
@@ -4,6 +4,7 @@
*
* Written and tested against the Designware HDMI Tx found in iMX6.
*/
+#include <linux/bitops.h>
#include <linux/io.h>
#include <linux/interrupt.h>
#include <linux/module.h>
@@ -171,12 +172,7 @@ static void dw_hdmi_reformat_iec958(struct snd_dw_hdmi *dw,
static u32 parity(u32 sample)
{
- sample ^= sample >> 16;
- sample ^= sample >> 8;
- sample ^= sample >> 4;
- sample ^= sample >> 2;
- sample ^= sample >> 1;
- return (sample & 1) << 27;
+ return parity32(sample) << 27;
}
static void dw_hdmi_reformat_s24(struct snd_dw_hdmi *dw,
--
2.34.1
^ permalink raw reply related [flat|nested] 32+ messages in thread* [PATCH v2 13/18] mtd: ssfdc: Replace open-coded parity calculation with parity32()
2025-03-01 14:23 [PATCH v2 00/18] Introduce and use generic parity16/32/64 helper Kuan-Wei Chiu
` (11 preceding siblings ...)
2025-03-01 14:24 ` [PATCH v2 12/18] drm/bridge: dw-hdmi: " Kuan-Wei Chiu
@ 2025-03-01 14:24 ` Kuan-Wei Chiu
2025-03-01 14:24 ` [PATCH v2 14/18] fsi: i2cr: " Kuan-Wei Chiu
` (4 subsequent siblings)
17 siblings, 0 replies; 32+ messages in thread
From: Kuan-Wei Chiu @ 2025-03-01 14:24 UTC (permalink / raw)
To: tglx, mingo, bp, dave.hansen, x86, jk, joel, eajames,
andrzej.hajda, neil.armstrong, rfoss, maarten.lankhorst, mripard,
tzimmermann, airlied, simona, dmitry.torokhov, mchehab, awalls,
hverkuil, miquel.raynal, richard, vigneshr, louis.peens,
andrew+netdev, davem, edumazet, pabeni, parthiban.veerasooran,
arend.vanspriel, johannes, gregkh, jirislaby, yury.norov, akpm
Cc: hpa, alistair, linux, Laurent.pinchart, jonas, jernej.skrabec,
kuba, linux-kernel, linux-fsi, dri-devel, linux-input,
linux-media, linux-mtd, oss-drivers, netdev, linux-wireless,
brcm80211, brcm80211-dev-list.pdl, linux-serial, bpf, jserv,
david.laight.linux, andrew.cooper3, Kuan-Wei Chiu, Yu-Chun Lin
Refactor parity calculations to use the standard parity32() helper.
This change eliminates redundant implementations and improves code
efficiency.
Co-developed-by: Yu-Chun Lin <eleanor15x@gmail.com>
Signed-off-by: Yu-Chun Lin <eleanor15x@gmail.com>
Signed-off-by: Kuan-Wei Chiu <visitorckw@gmail.com>
---
drivers/mtd/ssfdc.c | 17 ++---------------
1 file changed, 2 insertions(+), 15 deletions(-)
diff --git a/drivers/mtd/ssfdc.c b/drivers/mtd/ssfdc.c
index 46c01fa2ec46..e7f9e73da644 100644
--- a/drivers/mtd/ssfdc.c
+++ b/drivers/mtd/ssfdc.c
@@ -7,6 +7,7 @@
* Based on NTFL and MTDBLOCK_RO drivers
*/
+#include <linux/bitops.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
@@ -178,20 +179,6 @@ static int read_raw_oob(struct mtd_info *mtd, loff_t offs, uint8_t *buf)
return 0;
}
-/* Parity calculator on a word of n bit size */
-static int get_parity(int number, int size)
-{
- int k;
- int parity;
-
- parity = 1;
- for (k = 0; k < size; k++) {
- parity += (number >> k);
- parity &= 1;
- }
- return parity;
-}
-
/* Read and validate the logical block address field stored in the OOB */
static int get_logical_address(uint8_t *oob_buf)
{
@@ -215,7 +202,7 @@ static int get_logical_address(uint8_t *oob_buf)
block_address &= 0x7FF;
block_address >>= 1;
- if (get_parity(block_address, 10) != parity) {
+ if (parity32(block_address & 0x3ff) == parity) {
pr_debug("SSFDC_RO: logical address field%d"
"parity error(0x%04X)\n", j+1,
block_address);
--
2.34.1
^ permalink raw reply related [flat|nested] 32+ messages in thread* [PATCH v2 14/18] fsi: i2cr: Replace open-coded parity calculation with parity32()
2025-03-01 14:23 [PATCH v2 00/18] Introduce and use generic parity16/32/64 helper Kuan-Wei Chiu
` (12 preceding siblings ...)
2025-03-01 14:24 ` [PATCH v2 13/18] mtd: ssfdc: " Kuan-Wei Chiu
@ 2025-03-01 14:24 ` Kuan-Wei Chiu
2025-03-01 14:24 ` [PATCH v2 15/18] fsi: i2cr: Replace open-coded parity calculation with parity64() Kuan-Wei Chiu
` (3 subsequent siblings)
17 siblings, 0 replies; 32+ messages in thread
From: Kuan-Wei Chiu @ 2025-03-01 14:24 UTC (permalink / raw)
To: tglx, mingo, bp, dave.hansen, x86, jk, joel, eajames,
andrzej.hajda, neil.armstrong, rfoss, maarten.lankhorst, mripard,
tzimmermann, airlied, simona, dmitry.torokhov, mchehab, awalls,
hverkuil, miquel.raynal, richard, vigneshr, louis.peens,
andrew+netdev, davem, edumazet, pabeni, parthiban.veerasooran,
arend.vanspriel, johannes, gregkh, jirislaby, yury.norov, akpm
Cc: hpa, alistair, linux, Laurent.pinchart, jonas, jernej.skrabec,
kuba, linux-kernel, linux-fsi, dri-devel, linux-input,
linux-media, linux-mtd, oss-drivers, netdev, linux-wireless,
brcm80211, brcm80211-dev-list.pdl, linux-serial, bpf, jserv,
david.laight.linux, andrew.cooper3, Kuan-Wei Chiu, Yu-Chun Lin
Refactor parity calculations to use the standard parity32() helper.
This change eliminates redundant implementations and improves code
efficiency.
Co-developed-by: Yu-Chun Lin <eleanor15x@gmail.com>
Signed-off-by: Yu-Chun Lin <eleanor15x@gmail.com>
Signed-off-by: Kuan-Wei Chiu <visitorckw@gmail.com>
---
drivers/fsi/fsi-master-i2cr.c | 10 ++--------
1 file changed, 2 insertions(+), 8 deletions(-)
diff --git a/drivers/fsi/fsi-master-i2cr.c b/drivers/fsi/fsi-master-i2cr.c
index 40f1f4d231e5..8212b99ab2f9 100644
--- a/drivers/fsi/fsi-master-i2cr.c
+++ b/drivers/fsi/fsi-master-i2cr.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0
/* Copyright (C) IBM Corporation 2023 */
+#include <linux/bitops.h>
#include <linux/device.h>
#include <linux/fsi.h>
#include <linux/i2c.h>
@@ -38,14 +39,7 @@ static const u8 i2cr_cfam[] = {
static bool i2cr_check_parity32(u32 v, bool parity)
{
- u32 i;
-
- for (i = 0; i < 32; ++i) {
- if (v & (1u << i))
- parity = !parity;
- }
-
- return parity;
+ return parity ^ parity32(v);
}
static bool i2cr_check_parity64(u64 v)
--
2.34.1
^ permalink raw reply related [flat|nested] 32+ messages in thread* [PATCH v2 15/18] fsi: i2cr: Replace open-coded parity calculation with parity64()
2025-03-01 14:23 [PATCH v2 00/18] Introduce and use generic parity16/32/64 helper Kuan-Wei Chiu
` (13 preceding siblings ...)
2025-03-01 14:24 ` [PATCH v2 14/18] fsi: i2cr: " Kuan-Wei Chiu
@ 2025-03-01 14:24 ` Kuan-Wei Chiu
2025-03-01 14:24 ` [PATCH v2 16/18] Input: joystick - " Kuan-Wei Chiu
` (2 subsequent siblings)
17 siblings, 0 replies; 32+ messages in thread
From: Kuan-Wei Chiu @ 2025-03-01 14:24 UTC (permalink / raw)
To: tglx, mingo, bp, dave.hansen, x86, jk, joel, eajames,
andrzej.hajda, neil.armstrong, rfoss, maarten.lankhorst, mripard,
tzimmermann, airlied, simona, dmitry.torokhov, mchehab, awalls,
hverkuil, miquel.raynal, richard, vigneshr, louis.peens,
andrew+netdev, davem, edumazet, pabeni, parthiban.veerasooran,
arend.vanspriel, johannes, gregkh, jirislaby, yury.norov, akpm
Cc: hpa, alistair, linux, Laurent.pinchart, jonas, jernej.skrabec,
kuba, linux-kernel, linux-fsi, dri-devel, linux-input,
linux-media, linux-mtd, oss-drivers, netdev, linux-wireless,
brcm80211, brcm80211-dev-list.pdl, linux-serial, bpf, jserv,
david.laight.linux, andrew.cooper3, Kuan-Wei Chiu, Yu-Chun Lin
Refactor parity calculations to use the standard parity64() helper.
This change eliminates redundant implementations and improves code
efficiency.
Co-developed-by: Yu-Chun Lin <eleanor15x@gmail.com>
Signed-off-by: Yu-Chun Lin <eleanor15x@gmail.com>
Signed-off-by: Kuan-Wei Chiu <visitorckw@gmail.com>
---
drivers/fsi/fsi-master-i2cr.c | 8 +-------
1 file changed, 1 insertion(+), 7 deletions(-)
diff --git a/drivers/fsi/fsi-master-i2cr.c b/drivers/fsi/fsi-master-i2cr.c
index 8212b99ab2f9..8f558b7c6dbc 100644
--- a/drivers/fsi/fsi-master-i2cr.c
+++ b/drivers/fsi/fsi-master-i2cr.c
@@ -44,15 +44,9 @@ static bool i2cr_check_parity32(u32 v, bool parity)
static bool i2cr_check_parity64(u64 v)
{
- u32 i;
bool parity = I2CR_INITIAL_PARITY;
- for (i = 0; i < 64; ++i) {
- if (v & (1llu << i))
- parity = !parity;
- }
-
- return parity;
+ return parity ^ parity64(v);
}
static u32 i2cr_get_command(u32 address, bool parity)
--
2.34.1
^ permalink raw reply related [flat|nested] 32+ messages in thread* [PATCH v2 16/18] Input: joystick - Replace open-coded parity calculation with parity64()
2025-03-01 14:23 [PATCH v2 00/18] Introduce and use generic parity16/32/64 helper Kuan-Wei Chiu
` (14 preceding siblings ...)
2025-03-01 14:24 ` [PATCH v2 15/18] fsi: i2cr: Replace open-coded parity calculation with parity64() Kuan-Wei Chiu
@ 2025-03-01 14:24 ` Kuan-Wei Chiu
2025-03-01 14:24 ` [PATCH v2 17/18] nfp: bpf: " Kuan-Wei Chiu
2025-03-01 14:24 ` [PATCH v2 18/18] bitops: Add parity() macro for automatic type-based selection Kuan-Wei Chiu
17 siblings, 0 replies; 32+ messages in thread
From: Kuan-Wei Chiu @ 2025-03-01 14:24 UTC (permalink / raw)
To: tglx, mingo, bp, dave.hansen, x86, jk, joel, eajames,
andrzej.hajda, neil.armstrong, rfoss, maarten.lankhorst, mripard,
tzimmermann, airlied, simona, dmitry.torokhov, mchehab, awalls,
hverkuil, miquel.raynal, richard, vigneshr, louis.peens,
andrew+netdev, davem, edumazet, pabeni, parthiban.veerasooran,
arend.vanspriel, johannes, gregkh, jirislaby, yury.norov, akpm
Cc: hpa, alistair, linux, Laurent.pinchart, jonas, jernej.skrabec,
kuba, linux-kernel, linux-fsi, dri-devel, linux-input,
linux-media, linux-mtd, oss-drivers, netdev, linux-wireless,
brcm80211, brcm80211-dev-list.pdl, linux-serial, bpf, jserv,
david.laight.linux, andrew.cooper3, Kuan-Wei Chiu, Yu-Chun Lin
Refactor parity calculations to use the standard parity64() helper.
This change eliminates redundant implementations and improves code
efficiency.
Co-developed-by: Yu-Chun Lin <eleanor15x@gmail.com>
Signed-off-by: Yu-Chun Lin <eleanor15x@gmail.com>
Signed-off-by: Kuan-Wei Chiu <visitorckw@gmail.com>
---
drivers/input/joystick/sidewinder.c | 24 +++++-------------------
1 file changed, 5 insertions(+), 19 deletions(-)
diff --git a/drivers/input/joystick/sidewinder.c b/drivers/input/joystick/sidewinder.c
index 3a5873e5fcb3..9fe980096f70 100644
--- a/drivers/input/joystick/sidewinder.c
+++ b/drivers/input/joystick/sidewinder.c
@@ -7,6 +7,7 @@
* Microsoft SideWinder joystick family driver for Linux
*/
+#include <linux/bitops.h>
#include <linux/delay.h>
#include <linux/kernel.h>
#include <linux/module.h>
@@ -240,21 +241,6 @@ static void sw_init_digital(struct gameport *gameport)
local_irq_restore(flags);
}
-/*
- * sw_parity() computes parity of __u64
- */
-
-static int sw_parity(__u64 t)
-{
- int x = t ^ (t >> 32);
-
- x ^= x >> 16;
- x ^= x >> 8;
- x ^= x >> 4;
- x ^= x >> 2;
- x ^= x >> 1;
- return x & 1;
-}
/*
* sw_ccheck() checks synchronization bits and computes checksum of nibbles.
@@ -316,7 +302,7 @@ static int sw_parse(unsigned char *buf, struct sw *sw)
for (i = 0; i < sw->number; i ++) {
- if (sw_parity(GB(i*15,15)))
+ if (parity64(GB(i*15,15)))
return -1;
input_report_abs(sw->dev[i], ABS_X, GB(i*15+3,1) - GB(i*15+2,1));
@@ -333,7 +319,7 @@ static int sw_parse(unsigned char *buf, struct sw *sw)
case SW_ID_PP:
case SW_ID_FFP:
- if (!sw_parity(GB(0,48)) || (hat = GB(42,4)) > 8)
+ if (!parity64(GB(0,48)) || (hat = GB(42,4)) > 8)
return -1;
dev = sw->dev[0];
@@ -354,7 +340,7 @@ static int sw_parse(unsigned char *buf, struct sw *sw)
case SW_ID_FSP:
- if (!sw_parity(GB(0,43)) || (hat = GB(28,4)) > 8)
+ if (!parity64(GB(0,43)) || (hat = GB(28,4)) > 8)
return -1;
dev = sw->dev[0];
@@ -379,7 +365,7 @@ static int sw_parse(unsigned char *buf, struct sw *sw)
case SW_ID_FFW:
- if (!sw_parity(GB(0,33)))
+ if (!parity64(GB(0,33)))
return -1;
dev = sw->dev[0];
--
2.34.1
^ permalink raw reply related [flat|nested] 32+ messages in thread* [PATCH v2 17/18] nfp: bpf: Replace open-coded parity calculation with parity64()
2025-03-01 14:23 [PATCH v2 00/18] Introduce and use generic parity16/32/64 helper Kuan-Wei Chiu
` (15 preceding siblings ...)
2025-03-01 14:24 ` [PATCH v2 16/18] Input: joystick - " Kuan-Wei Chiu
@ 2025-03-01 14:24 ` Kuan-Wei Chiu
2025-03-01 14:24 ` [PATCH v2 18/18] bitops: Add parity() macro for automatic type-based selection Kuan-Wei Chiu
17 siblings, 0 replies; 32+ messages in thread
From: Kuan-Wei Chiu @ 2025-03-01 14:24 UTC (permalink / raw)
To: tglx, mingo, bp, dave.hansen, x86, jk, joel, eajames,
andrzej.hajda, neil.armstrong, rfoss, maarten.lankhorst, mripard,
tzimmermann, airlied, simona, dmitry.torokhov, mchehab, awalls,
hverkuil, miquel.raynal, richard, vigneshr, louis.peens,
andrew+netdev, davem, edumazet, pabeni, parthiban.veerasooran,
arend.vanspriel, johannes, gregkh, jirislaby, yury.norov, akpm
Cc: hpa, alistair, linux, Laurent.pinchart, jonas, jernej.skrabec,
kuba, linux-kernel, linux-fsi, dri-devel, linux-input,
linux-media, linux-mtd, oss-drivers, netdev, linux-wireless,
brcm80211, brcm80211-dev-list.pdl, linux-serial, bpf, jserv,
david.laight.linux, andrew.cooper3, Kuan-Wei Chiu, Yu-Chun Lin
Refactor parity calculations to use the standard parity64() helper.
This change eliminates redundant implementations and improves code
efficiency.
Co-developed-by: Yu-Chun Lin <eleanor15x@gmail.com>
Signed-off-by: Yu-Chun Lin <eleanor15x@gmail.com>
Signed-off-by: Kuan-Wei Chiu <visitorckw@gmail.com>
---
drivers/net/ethernet/netronome/nfp/nfp_asm.c | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_asm.c b/drivers/net/ethernet/netronome/nfp/nfp_asm.c
index 154399c5453f..3646f84a6e8c 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_asm.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_asm.c
@@ -295,11 +295,6 @@ static const u64 nfp_ustore_ecc_polynomials[NFP_USTORE_ECC_POLY_WORDS] = {
0x0daf69a46910ULL,
};
-static bool parity(u64 value)
-{
- return hweight64(value) & 1;
-}
-
int nfp_ustore_check_valid_no_ecc(u64 insn)
{
if (insn & ~GENMASK_ULL(NFP_USTORE_OP_BITS, 0))
@@ -314,7 +309,7 @@ u64 nfp_ustore_calc_ecc_insn(u64 insn)
int i;
for (i = 0; i < NFP_USTORE_ECC_POLY_WORDS; i++)
- ecc |= parity(nfp_ustore_ecc_polynomials[i] & insn) << i;
+ ecc |= parity64(nfp_ustore_ecc_polynomials[i] & insn) << i;
return insn | (u64)ecc << NFP_USTORE_OP_BITS;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 32+ messages in thread* [PATCH v2 18/18] bitops: Add parity() macro for automatic type-based selection
2025-03-01 14:23 [PATCH v2 00/18] Introduce and use generic parity16/32/64 helper Kuan-Wei Chiu
` (16 preceding siblings ...)
2025-03-01 14:24 ` [PATCH v2 17/18] nfp: bpf: " Kuan-Wei Chiu
@ 2025-03-01 14:24 ` Kuan-Wei Chiu
17 siblings, 0 replies; 32+ messages in thread
From: Kuan-Wei Chiu @ 2025-03-01 14:24 UTC (permalink / raw)
To: tglx, mingo, bp, dave.hansen, x86, jk, joel, eajames,
andrzej.hajda, neil.armstrong, rfoss, maarten.lankhorst, mripard,
tzimmermann, airlied, simona, dmitry.torokhov, mchehab, awalls,
hverkuil, miquel.raynal, richard, vigneshr, louis.peens,
andrew+netdev, davem, edumazet, pabeni, parthiban.veerasooran,
arend.vanspriel, johannes, gregkh, jirislaby, yury.norov, akpm
Cc: hpa, alistair, linux, Laurent.pinchart, jonas, jernej.skrabec,
kuba, linux-kernel, linux-fsi, dri-devel, linux-input,
linux-media, linux-mtd, oss-drivers, netdev, linux-wireless,
brcm80211, brcm80211-dev-list.pdl, linux-serial, bpf, jserv,
david.laight.linux, andrew.cooper3, Kuan-Wei Chiu, Yu-Chun Lin
Introduce the parity() macro, which selects the appropriate parity
function (parity8(), parity16(), parity32(), or parity64()) based on
the size of the input type. This improves usability by allowing a
generic parity calculation without requiring explicit function
selection.
If the input type does not match the supported sizes, BUILD_BUG() is
triggered to catch invalid usage at compile time.
Co-developed-by: Yu-Chun Lin <eleanor15x@gmail.com>
Signed-off-by: Yu-Chun Lin <eleanor15x@gmail.com>
Signed-off-by: Kuan-Wei Chiu <visitorckw@gmail.com>
---
Place this patch last in the series to avoid compilation errors.
include/linux/bitops.h | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/include/linux/bitops.h b/include/linux/bitops.h
index 41e9e7fb894b..fa4e45741dff 100644
--- a/include/linux/bitops.h
+++ b/include/linux/bitops.h
@@ -339,6 +339,28 @@ static inline __attribute_const__ int parity64(u64 val)
return __builtin_constant_p(val) ? _parity_const(val) : _parity64(val);
}
+#define parity(val) \
+({ \
+ int __ret; \
+ switch (BITS_PER_TYPE(val)) { \
+ case 64: \
+ __ret = parity64(val); \
+ break; \
+ case 32: \
+ __ret = parity32(val); \
+ break; \
+ case 16: \
+ __ret = parity16(val); \
+ break; \
+ case 8: \
+ __ret = parity8(val); \
+ break; \
+ default: \
+ BUILD_BUG(); \
+ } \
+ __ret; \
+})
+
/**
* __ffs64 - find first set bit in a 64 bit word
* @word: The 64 bit word
--
2.34.1
^ permalink raw reply related [flat|nested] 32+ messages in thread