Linux wireless drivers development
 help / color / mirror / Atom feed
* [rfc, PATCH v1 0/2] overflow: Convert size_add() to take variadic arguments
@ 2026-06-17 11:12 Andy Shevchenko
  2026-06-17 11:12 ` [PATCH v1 1/2] overflow: Allow to sum a few arguments at once Andy Shevchenko
  2026-06-17 11:12 ` [PATCH v1 2/2] wifi: nl80211: Call size_add() only once Andy Shevchenko
  0 siblings, 2 replies; 5+ messages in thread
From: Andy Shevchenko @ 2026-06-17 11:12 UTC (permalink / raw)
  To: Johannes Berg, linux-hardening, linux-kernel, linux-wireless
  Cc: Kees Cook, Gustavo A. R. Silva, Johannes Berg, Andy Shevchenko

This is an RFC!

We have already users that want add sizes of up to 5 arguments and
I know about at least one that also wants 3 or 4.

This is brave move to make size_add() to take variadic arguments.
The second patch is an example of use.

The implementation includes a case with a single argument on a purpose.
In the future it might be extended to take an array as an argument,
something like

	int sizes[21];
	size_add(sizes);

where the first element is amount of entries in the array (the same format
as used in get_options() call) or other possible variants. This can be
distinguished by _Generic().

But it may be dropped and we require always two arguments at minimum.

The RFC just to collect opinions and perception. Note, array3*(), min3()/max3()
and all like that also can use similar approach.

Andy Shevchenko (2):
  overflow: Allow to sum a few arguments at once
  wifi: nl80211: Call size_add() only once

 include/linux/overflow.h | 37 ++++++++++++++++++++++++++-----------
 net/wireless/nl80211.c   | 11 ++++-------
 2 files changed, 30 insertions(+), 18 deletions(-)

-- 
2.50.1


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH v1 1/2] overflow: Allow to sum a few arguments at once
  2026-06-17 11:12 [rfc, PATCH v1 0/2] overflow: Convert size_add() to take variadic arguments Andy Shevchenko
@ 2026-06-17 11:12 ` Andy Shevchenko
  2026-06-17 12:56   ` Johannes Berg
  2026-06-17 11:12 ` [PATCH v1 2/2] wifi: nl80211: Call size_add() only once Andy Shevchenko
  1 sibling, 1 reply; 5+ messages in thread
From: Andy Shevchenko @ 2026-06-17 11:12 UTC (permalink / raw)
  To: Johannes Berg, linux-hardening, linux-kernel, linux-wireless
  Cc: Kees Cook, Gustavo A. R. Silva, Johannes Berg, Andy Shevchenko

Convert size_add() to take variadic argument, so we can simplify users
with using a macro only once.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 include/linux/overflow.h | 37 ++++++++++++++++++++++++++-----------
 1 file changed, 26 insertions(+), 11 deletions(-)

diff --git a/include/linux/overflow.h b/include/linux/overflow.h
index a8cb6319b4fb..a8b0325e73f3 100644
--- a/include/linux/overflow.h
+++ b/include/linux/overflow.h
@@ -2,9 +2,10 @@
 #ifndef __LINUX_OVERFLOW_H
 #define __LINUX_OVERFLOW_H
 
+#include <linux/args.h>
 #include <linux/compiler.h>
-#include <linux/limits.h>
 #include <linux/const.h>
+#include <linux/limits.h>
 
 /*
  * We need to compute the minimum and maximum values representable in a given
@@ -337,16 +338,7 @@ static __always_inline size_t __must_check size_mul(size_t factor1, size_t facto
 	return bytes;
 }
 
-/**
- * size_add() - Calculate size_t addition with saturation at SIZE_MAX
- * @addend1: first addend
- * @addend2: second addend
- *
- * Returns: calculate @addend1 + @addend2, both promoted to size_t,
- * with any overflow causing the return value to be SIZE_MAX. The
- * lvalue must be size_t to avoid implicit type conversion.
- */
-static __always_inline size_t __must_check size_add(size_t addend1, size_t addend2)
+static __always_inline size_t __must_check __size_add(size_t addend1, size_t addend2)
 {
 	size_t bytes;
 
@@ -356,6 +348,29 @@ static __always_inline size_t __must_check size_add(size_t addend1, size_t adden
 	return bytes;
 }
 
+#define __size_add0(addend1, ...)						\
+	__size_add(addend1, 0)
+#define __size_add1(addend1, addend2, ...)					\
+	__size_add(addend1,  addend2)
+#define __size_add2(addend1, addend2, addend3, ...)				\
+	__size_add(__size_add(addend1,  addend2), addend3)
+#define __size_add3(addend1, addend2, addend3, addend4, ...)			\
+	__size_add(__size_add2(addend1,  addend2, addend3), addend4)
+#define __size_add4(addend1, addend2, addend3, addend4, addend5, ...)		\
+	__size_add(__size_add3(addend1,  addend2, addend3, addend4), addend5)
+
+/**
+ * size_add() - Calculate size_t addition with saturation at SIZE_MAX
+ * @addend1: first addend
+ * @...: more to add (optional)
+ *
+ * Returns: calculate @addend1 + @addend2, both promoted to size_t,
+ * with any overflow causing the return value to be SIZE_MAX. The
+ * lvalue must be size_t to avoid implicit type conversion.
+ */
+#define size_add(addend1, ...)	\
+	CONCATENATE(__size_add, COUNT_ARGS(__VA_ARGS__))(addend1, __VA_ARGS__)
+
 /**
  * size_sub() - Calculate size_t subtraction with saturation at SIZE_MAX
  * @minuend: value to subtract from
-- 
2.50.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v1 2/2] wifi: nl80211: Call size_add() only once
  2026-06-17 11:12 [rfc, PATCH v1 0/2] overflow: Convert size_add() to take variadic arguments Andy Shevchenko
  2026-06-17 11:12 ` [PATCH v1 1/2] overflow: Allow to sum a few arguments at once Andy Shevchenko
@ 2026-06-17 11:12 ` Andy Shevchenko
  1 sibling, 0 replies; 5+ messages in thread
From: Andy Shevchenko @ 2026-06-17 11:12 UTC (permalink / raw)
  To: Johannes Berg, linux-hardening, linux-kernel, linux-wireless
  Cc: Kees Cook, Gustavo A. R. Silva, Johannes Berg, Andy Shevchenko

Since size_add() may take a few arguments at once, call it only once.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 net/wireless/nl80211.c | 11 ++++-------
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 53b4b3f76697..98f92c268944 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -11560,13 +11560,10 @@ nl80211_parse_sched_scan(struct wiphy *wiphy, struct wireless_dev *wdev,
 	     attrs[NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST]))
 		return ERR_PTR(-EINVAL);
 
-	size = struct_size(request, channels, n_channels);
-	size = size_add(size, array_size(sizeof(*request->ssids), n_ssids));
-	size = size_add(size, array_size(sizeof(*request->match_sets),
-					 n_match_sets));
-	size = size_add(size, array_size(sizeof(*request->scan_plans),
-					 n_plans));
-	size = size_add(size, ie_len);
+	size = size_add(struct_size(request, channels, n_channels), ie_len,
+			array_size(sizeof(*request->ssids), n_ssids),
+			array_size(sizeof(*request->match_sets), n_match_sets),
+			array_size(sizeof(*request->scan_plans), n_plans));
 	request = kzalloc(size, GFP_KERNEL);
 	if (!request)
 		return ERR_PTR(-ENOMEM);
-- 
2.50.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH v1 1/2] overflow: Allow to sum a few arguments at once
  2026-06-17 11:12 ` [PATCH v1 1/2] overflow: Allow to sum a few arguments at once Andy Shevchenko
@ 2026-06-17 12:56   ` Johannes Berg
  2026-06-17 21:30     ` David Laight
  0 siblings, 1 reply; 5+ messages in thread
From: Johannes Berg @ 2026-06-17 12:56 UTC (permalink / raw)
  To: Andy Shevchenko, linux-hardening, linux-kernel, linux-wireless
  Cc: Kees Cook, Gustavo A. R. Silva

On Wed, 2026-06-17 at 13:12 +0200, Andy Shevchenko wrote:
> Convert size_add() to take variadic argument, so we can simplify users
> with using a macro only once.

> +#define __size_add3(addend1, addend2, addend3, addend4, ...)			\
> +	__size_add(__size_add2(addend1,  addend2, addend3), addend4)
> +#define __size_add4(addend1, addend2, addend3, addend4, addend5, ...)		\
> +	__size_add(__size_add3(addend1,  addend2, addend3, addend4), addend5)

I guess it's not going to really matter, but it would generate fewer
calls to have something more like

#define __size_add3(a1, a2, a3, a4) \
	size_add(size_add(a1, a2), size_add(a3, a4))
#define __size_add4(a1, a2, a3, a4, a5) \
	size_add(size_add(a1, a2), size_add(a3, a4, a5))

as a binary tree, rather than only cutting one off every time. Not sure
that results in hugely different code though - maybe fewer overflow
checks?

Although your version make it really completely equivalent to the
nl80211.c code, clearly it doesn't matter if all the values are "good",
and I believe the overflow behaviour means it doesn't matter for the
overflow case either?

johannes

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH v1 1/2] overflow: Allow to sum a few arguments at once
  2026-06-17 12:56   ` Johannes Berg
@ 2026-06-17 21:30     ` David Laight
  0 siblings, 0 replies; 5+ messages in thread
From: David Laight @ 2026-06-17 21:30 UTC (permalink / raw)
  To: Johannes Berg
  Cc: Andy Shevchenko, linux-hardening, linux-kernel, linux-wireless,
	Kees Cook, Gustavo A. R. Silva

On Wed, 17 Jun 2026 14:56:09 +0200
Johannes Berg <johannes@sipsolutions.net> wrote:

> On Wed, 2026-06-17 at 13:12 +0200, Andy Shevchenko wrote:
> > Convert size_add() to take variadic argument, so we can simplify users
> > with using a macro only once.  
> 
> > +#define __size_add3(addend1, addend2, addend3, addend4, ...)			\
> > +	__size_add(__size_add2(addend1,  addend2, addend3), addend4)
> > +#define __size_add4(addend1, addend2, addend3, addend4, addend5, ...)		\
> > +	__size_add(__size_add3(addend1,  addend2, addend3, addend4), addend5)  
> 
> I guess it's not going to really matter, but it would generate fewer
> calls to have something more like
> 
> #define __size_add3(a1, a2, a3, a4) \
> 	size_add(size_add(a1, a2), size_add(a3, a4))
> #define __size_add4(a1, a2, a3, a4, a5) \
> 	size_add(size_add(a1, a2), size_add(a3, a4, a5))
> 
> as a binary tree, rather than only cutting one off every time. Not sure
> that results in hugely different code though - maybe fewer overflow
> checks?

The binary tree stands a chance of executing less slowly because the leaf
adds can be executed in parallel.
Excluding the saturation checks (wtf is it called size_add() not
saturating_add() ?) (a + b) + (c + d) will usually execute faster than
((a + b) + c) + d because the (a + b) and (c + d) can execute at the
same time; unfortunately gcc will always generate the latter.

	David

> 
> Although your version make it really completely equivalent to the
> nl80211.c code, clearly it doesn't matter if all the values are "good",
> and I believe the overflow behaviour means it doesn't matter for the
> overflow case either?
> 
> johannes
> 


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2026-06-17 21:30 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-17 11:12 [rfc, PATCH v1 0/2] overflow: Convert size_add() to take variadic arguments Andy Shevchenko
2026-06-17 11:12 ` [PATCH v1 1/2] overflow: Allow to sum a few arguments at once Andy Shevchenko
2026-06-17 12:56   ` Johannes Berg
2026-06-17 21:30     ` David Laight
2026-06-17 11:12 ` [PATCH v1 2/2] wifi: nl80211: Call size_add() only once Andy Shevchenko

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox