linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] sched/fair: Replace zero-length array with flexible-array member
@ 2020-02-13 15:19 Gustavo A. R. Silva
  2020-02-13 16:45 ` Peter Zijlstra
  0 siblings, 1 reply; 8+ messages in thread
From: Gustavo A. R. Silva @ 2020-02-13 15:19 UTC (permalink / raw)
  To: Ingo Molnar, Peter Zijlstra, Juri Lelli, Vincent Guittot,
	Dietmar Eggemann, Steven Rostedt, Ben Segall, Mel Gorman
  Cc: linux-kernel, Gustavo A. R. Silva

The current codebase makes use of the zero-length array language
extension to the C90 standard, but the preferred mechanism to declare
variable-length types such as these ones is a flexible array member[1][2],
introduced in C99:

struct foo {
        int stuff;
        struct boo array[];
};

By making use of the mechanism above, we will get a compiler warning
in case the flexible array does not occur last in the structure, which
will help us prevent some kind of undefined behavior bugs from being
inadvertently introduced[3] to the codebase from now on.

Also, notice that, dynamic memory allocations won't be affected by
this change:

"Flexible array members have incomplete type, and so the sizeof operator
may not be applied. As a quirk of the original implementation of
zero-length arrays, sizeof evaluates to zero."[1]

This issue was found with the help of Coccinelle.

[1] https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html
[2] https://github.com/KSPP/linux/issues/21
[3] commit 76497732932f ("cxgb3/l2t: Fix undefined behaviour")

Signed-off-by: Gustavo A. R. Silva <gustavo@embeddedor.com>
---
 kernel/sched/fair.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index f38ff5a335d3..12a424878b23 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -1081,7 +1081,7 @@ struct numa_group {
 	 * more by CPU use than by memory faults.
 	 */
 	unsigned long *faults_cpu;
-	unsigned long faults[0];
+	unsigned long faults[];
 };
 
 /*
-- 
2.25.0


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

* Re: [PATCH] sched/fair: Replace zero-length array with flexible-array member
  2020-02-13 15:19 [PATCH] sched/fair: Replace zero-length array with flexible-array member Gustavo A. R. Silva
@ 2020-02-13 16:45 ` Peter Zijlstra
  2020-02-13 16:58   ` Gustavo A. R. Silva
  0 siblings, 1 reply; 8+ messages in thread
From: Peter Zijlstra @ 2020-02-13 16:45 UTC (permalink / raw)
  To: Gustavo A. R. Silva
  Cc: Ingo Molnar, Juri Lelli, Vincent Guittot, Dietmar Eggemann,
	Steven Rostedt, Ben Segall, Mel Gorman, linux-kernel

On Thu, Feb 13, 2020 at 09:19:51AM -0600, Gustavo A. R. Silva wrote:
> The current codebase makes use of the zero-length array language
> extension to the C90 standard, but the preferred mechanism to declare
> variable-length types such as these ones is a flexible array member[1][2],
> introduced in C99:
> 
> struct foo {
>         int stuff;
>         struct boo array[];
> };
> 
> By making use of the mechanism above, we will get a compiler warning
> in case the flexible array does not occur last in the structure, which
> will help us prevent some kind of undefined behavior bugs from being
> inadvertently introduced[3] to the codebase from now on.
> 
> Also, notice that, dynamic memory allocations won't be affected by
> this change:
> 
> "Flexible array members have incomplete type, and so the sizeof operator
> may not be applied. As a quirk of the original implementation of
> zero-length arrays, sizeof evaluates to zero."[1]
> 
> This issue was found with the help of Coccinelle.
> 
> [1] https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html
> [2] https://github.com/KSPP/linux/issues/21
> [3] commit 76497732932f ("cxgb3/l2t: Fix undefined behaviour")
> 
> Signed-off-by: Gustavo A. R. Silva <gustavo@embeddedor.com>
> ---
>  kernel/sched/fair.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
> index f38ff5a335d3..12a424878b23 100644
> --- a/kernel/sched/fair.c
> +++ b/kernel/sched/fair.c
> @@ -1081,7 +1081,7 @@ struct numa_group {
>  	 * more by CPU use than by memory faults.
>  	 */
>  	unsigned long *faults_cpu;
> -	unsigned long faults[0];
> +	unsigned long faults[];
>  };

Hurmph, and where are all the other similar changes for kernel/sched/ ?
Because this really isn't the only such usage and I really don't see the
point in having a separate patch for every single one of them.

Also; couldn't you've taught the compiler to also warn about [0] ?
There's really no other purpose to having a zero length array.

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

* Re: [PATCH] sched/fair: Replace zero-length array with flexible-array member
  2020-02-13 16:45 ` Peter Zijlstra
@ 2020-02-13 16:58   ` Gustavo A. R. Silva
  2020-02-13 17:06     ` Peter Zijlstra
  0 siblings, 1 reply; 8+ messages in thread
From: Gustavo A. R. Silva @ 2020-02-13 16:58 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: Ingo Molnar, Juri Lelli, Vincent Guittot, Dietmar Eggemann,
	Steven Rostedt, Ben Segall, Mel Gorman, linux-kernel



On 2/13/20 10:45, Peter Zijlstra wrote:
> On Thu, Feb 13, 2020 at 09:19:51AM -0600, Gustavo A. R. Silva wrote:
>> The current codebase makes use of the zero-length array language
>> extension to the C90 standard, but the preferred mechanism to declare
>> variable-length types such as these ones is a flexible array member[1][2],
>> introduced in C99:
>>
>> struct foo {
>>         int stuff;
>>         struct boo array[];
>> };
>>
>> By making use of the mechanism above, we will get a compiler warning
>> in case the flexible array does not occur last in the structure, which
>> will help us prevent some kind of undefined behavior bugs from being
>> inadvertently introduced[3] to the codebase from now on.
>>
>> Also, notice that, dynamic memory allocations won't be affected by
>> this change:
>>
>> "Flexible array members have incomplete type, and so the sizeof operator
>> may not be applied. As a quirk of the original implementation of
>> zero-length arrays, sizeof evaluates to zero."[1]
>>
>> This issue was found with the help of Coccinelle.
>>
>> [1] https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html
>> [2] https://github.com/KSPP/linux/issues/21
>> [3] commit 76497732932f ("cxgb3/l2t: Fix undefined behaviour")
>>
>> Signed-off-by: Gustavo A. R. Silva <gustavo@embeddedor.com>
>> ---
>>  kernel/sched/fair.c | 2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
>> index f38ff5a335d3..12a424878b23 100644
>> --- a/kernel/sched/fair.c
>> +++ b/kernel/sched/fair.c
>> @@ -1081,7 +1081,7 @@ struct numa_group {
>>  	 * more by CPU use than by memory faults.
>>  	 */
>>  	unsigned long *faults_cpu;
>> -	unsigned long faults[0];
>> +	unsigned long faults[];
>>  };
> 
> Hurmph, and where are all the other similar changes for kernel/sched/ ?
> Because this really isn't the only such usage and I really don't see the
> point in having a separate patch for every single one of them.
> 

Yeah. I can do that. I'll send a patch for the whole kernel/sched.

> Also; couldn't you've taught the compiler to also warn about [0] ?
> There's really no other purpose to having a zero length array.
> 

Yeah, this is something we'd like to see in the short future.
Unfortunately, for now, the only way for the compiler to warn
about zero-length arrays in through the use of "-pedantic".
And we definitely don't want to follow this path.

What we can do, in the meantime, is to add a test for it to
checkpatch.

Thanks
--
Gustavo

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

* Re: [PATCH] sched/fair: Replace zero-length array with flexible-array member
  2020-02-13 16:58   ` Gustavo A. R. Silva
@ 2020-02-13 17:06     ` Peter Zijlstra
  2020-02-13 22:02       ` Joe Perches
  0 siblings, 1 reply; 8+ messages in thread
From: Peter Zijlstra @ 2020-02-13 17:06 UTC (permalink / raw)
  To: Gustavo A. R. Silva
  Cc: Ingo Molnar, Juri Lelli, Vincent Guittot, Dietmar Eggemann,
	Steven Rostedt, Ben Segall, Mel Gorman, linux-kernel

On Thu, Feb 13, 2020 at 10:58:31AM -0600, Gustavo A. R. Silva wrote:
> > Hurmph, and where are all the other similar changes for kernel/sched/ ?
> > Because this really isn't the only such usage and I really don't see the
> > point in having a separate patch for every single one of them.
> > 
> 
> Yeah. I can do that. I'll send a patch for the whole kernel/sched.

Thanks!

> > Also; couldn't you've taught the compiler to also warn about [0] ?
> > There's really no other purpose to having a zero length array.
> > 
> 
> Yeah, this is something we'd like to see in the short future.
> Unfortunately, for now, the only way for the compiler to warn
> about zero-length arrays in through the use of "-pedantic".
> And we definitely don't want to follow this path.
> 
> What we can do, in the meantime, is to add a test for it to
> checkpatch.

Oh, I means, warn if it isn't the last member of a struct. Not warn on
any use. Or we mean the same and I'm just confused.

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

* Re: [PATCH] sched/fair: Replace zero-length array with flexible-array member
  2020-02-13 17:06     ` Peter Zijlstra
@ 2020-02-13 22:02       ` Joe Perches
  2020-02-14  0:25         ` Valentin Schneider
  0 siblings, 1 reply; 8+ messages in thread
From: Joe Perches @ 2020-02-13 22:02 UTC (permalink / raw)
  To: Peter Zijlstra, Gustavo A. R. Silva
  Cc: Ingo Molnar, Juri Lelli, Vincent Guittot, Dietmar Eggemann,
	Steven Rostedt, Ben Segall, Mel Gorman, linux-kernel

On Thu, 2020-02-13 at 18:06 +0100, Peter Zijlstra wrote:
> On Thu, Feb 13, 2020 at 10:58:31AM -0600, Gustavo A. R. Silva wrote:
> > > Hurmph, and where are all the other similar changes for kernel/sched/ ?
> > > Because this really isn't the only such usage and I really don't see the
> > > point in having a separate patch for every single one of them.
> > > 
> > 
> > Yeah. I can do that. I'll send a patch for the whole kernel/sched.
> 
> Thanks!
> 
> > > Also; couldn't you've taught the compiler to also warn about [0] ?
> > > There's really no other purpose to having a zero length array.
> > > 
> > 
> > Yeah, this is something we'd like to see in the short future.
> > Unfortunately, for now, the only way for the compiler to warn
> > about zero-length arrays in through the use of "-pedantic".
> > And we definitely don't want to follow this path.
> > 
> > What we can do, in the meantime, is to add a test for it to
> > checkpatch.
> 
> Oh, I means, warn if it isn't the last member of a struct. Not warn on
> any use. Or we mean the same and I'm just confused.

That might be a somewhat difficult thing to add to checkpatch
as it is effectively a per-line scanner:

Try something like:

$ git grep -P -A1 '^\s*(?!return)(\w+\s+){1,3}\w+\[0\];' -- '*.[ch]'

and look at the results.

In checkpatch that could be something like:

	if ($line =~ /^.\s*$Type\s+$Ident\s*\[\s*0\s*\]\s*;/) {
		warn...
	}




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

* Re: [PATCH] sched/fair: Replace zero-length array with flexible-array member
  2020-02-13 22:02       ` Joe Perches
@ 2020-02-14  0:25         ` Valentin Schneider
  2020-02-14  2:05           ` Joe Perches
  0 siblings, 1 reply; 8+ messages in thread
From: Valentin Schneider @ 2020-02-14  0:25 UTC (permalink / raw)
  To: Joe Perches, Peter Zijlstra, Gustavo A. R. Silva
  Cc: Ingo Molnar, Juri Lelli, Vincent Guittot, Dietmar Eggemann,
	Steven Rostedt, Ben Segall, Mel Gorman, linux-kernel

On 13/02/2020 22:02, Joe Perches wrote:
> That might be a somewhat difficult thing to add to checkpatch
> as it is effectively a per-line scanner:
> 
> Try something like:
> 
> $ git grep -P -A1 '^\s*(?!return)(\w+\s+){1,3}\w+\[0\];' -- '*.[ch]'
> 
> and look at the results.
> 
> In checkpatch that could be something like:
> 
> 	if ($line =~ /^.\s*$Type\s+$Ident\s*\[\s*0\s*\]\s*;/) {
> 		warn...
> 	}
> 

So FWIW I felt like doing some coccinelle and ended up with this:

This patches up valid ZLAs:
  $ spatch -D patch zero_length_array.cocci kernel/sched/fair.c

This prints out the location of invalid ZLAs:
  $ spatch -D report zero_length_array.cocci kernel/sched/fair.c

---
virtual patch
virtual report

@valid_zla depends on patch@
identifier struct_name;
type T;
identifier zla;
position pos;
@@
struct struct_name {
       ...
       T zla@pos
- [0];
+ [];
};

@invalid_zla depends on report@
identifier struct_name;
type T1;
identifier zla;
type T2;
identifier tail;
position pos;
@@
struct struct_name {
       ...
       T1 zla[0]@pos;
       T2 tail;
       ...
};

@script:python depends on invalid_zla@
pos << invalid_zla.pos;
@@
coccilib.report.print_report(pos[0], "Invalid ZLA!");
---
 

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

* Re: [PATCH] sched/fair: Replace zero-length array with flexible-array member
  2020-02-14  0:25         ` Valentin Schneider
@ 2020-02-14  2:05           ` Joe Perches
  2020-02-16 23:38             ` Valentin Schneider
  0 siblings, 1 reply; 8+ messages in thread
From: Joe Perches @ 2020-02-14  2:05 UTC (permalink / raw)
  To: Valentin Schneider, Peter Zijlstra, Gustavo A. R. Silva
  Cc: Ingo Molnar, Juri Lelli, Vincent Guittot, Dietmar Eggemann,
	Steven Rostedt, Ben Segall, Mel Gorman, linux-kernel

On Fri, 2020-02-14 at 00:25 +0000, Valentin Schneider wrote:
> On 13/02/2020 22:02, Joe Perches wrote:
> > That might be a somewhat difficult thing to add to checkpatch
> > as it is effectively a per-line scanner:
> > 
> > Try something like:
> > 
> > $ git grep -P -A1 '^\s*(?!return)(\w+\s+){1,3}\w+\[0\];' -- '*.[ch]'
> > 
> > and look at the results.
> > 
> > In checkpatch that could be something like:
> > 
> > 	if ($line =~ /^.\s*$Type\s+$Ident\s*\[\s*0\s*\]\s*;/) {
> > 		warn...
> > 	}
> > 
> 
> So FWIW I felt like doing some coccinelle and ended up with this:
> 
> This patches up valid ZLAs:
>   $ spatch -D patch zero_length_array.cocci kernel/sched/fair.c
> 
> This prints out the location of invalid ZLAs:
>   $ spatch -D report zero_length_array.cocci kernel/sched/fair.c
> 
> ---
> virtual patch
> virtual report
> 
> @valid_zla depends on patch@
> identifier struct_name;
> type T;
> identifier zla;
> position pos;
> @@
> struct struct_name {
>        ...
>        T zla@pos
> - [0];
> + [];
> };
> 
> @invalid_zla depends on report@
> identifier struct_name;
> type T1;
> identifier zla;
> type T2;
> identifier tail;
> position pos;
> @@
> struct struct_name {
>        ...
>        T1 zla[0]@pos;
>        T2 tail;
>        ...
> };
> 
> @script:python depends on invalid_zla@
> pos << invalid_zla.pos;
> @@
> coccilib.report.print_report(pos[0], "Invalid ZLA!");
> ---

Nice.
It would miss a few forms like:

	typedef struct tagfoo {
		...
		type t[0];
	} foo;

and

	struct {
		...
		type t[0];
	} foo;

and

	struct foo {
		...
		type t[0];
	} *foo;

etc...



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

* Re: [PATCH] sched/fair: Replace zero-length array with flexible-array member
  2020-02-14  2:05           ` Joe Perches
@ 2020-02-16 23:38             ` Valentin Schneider
  0 siblings, 0 replies; 8+ messages in thread
From: Valentin Schneider @ 2020-02-16 23:38 UTC (permalink / raw)
  To: Joe Perches, Peter Zijlstra, Gustavo A. R. Silva
  Cc: Ingo Molnar, Juri Lelli, Vincent Guittot, Dietmar Eggemann,
	Steven Rostedt, Ben Segall, Mel Gorman, linux-kernel

On 14/02/2020 02:05, Joe Perches wrote:
> Nice.
> It would miss a few forms like:
> 
> 	typedef struct tagfoo {
> 		...
> 		type t[0];
> 	} foo;
> 
> and
> 
> 	struct {
> 		...
> 		type t[0];
> 	} foo;
> 
> and
> 
> 	struct foo {
> 		...
> 		type t[0];
> 	} *foo;
> 
> etc...
> 
> 

Right! Digging around for some examples on handling typedefs & co I stumbled
on this construct:

T {
   <blah>
};

This matches your typedef case, but none of the other two. I haven't found
a nice way to match them without listing down some special cases, which I
don't really like.

I might dig around sometime to figure out how this should be expressed; in
the meantime a simple 'grep -r "\[0\];"' will most likely yield faster results
(for hunting down ZLAs, that is).

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

end of thread, other threads:[~2020-02-16 23:39 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-02-13 15:19 [PATCH] sched/fair: Replace zero-length array with flexible-array member Gustavo A. R. Silva
2020-02-13 16:45 ` Peter Zijlstra
2020-02-13 16:58   ` Gustavo A. R. Silva
2020-02-13 17:06     ` Peter Zijlstra
2020-02-13 22:02       ` Joe Perches
2020-02-14  0:25         ` Valentin Schneider
2020-02-14  2:05           ` Joe Perches
2020-02-16 23:38             ` Valentin Schneider

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).