LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
* [PATCH] tracing: silence GCC 9 array bounds warning
@ 2019-05-17  9:25 Miguel Ojeda
  2019-05-17 16:47 ` Steven Rostedt
                   ` (2 more replies)
  0 siblings, 3 replies; 11+ messages in thread
From: Miguel Ojeda @ 2019-05-17  9:25 UTC (permalink / raw)
  To: Steven Rostedt, Ingo Molnar; +Cc: linux-kernel

Starting with GCC 9, -Warray-bounds detects cases when memset is called
starting on a member of a struct but the size to be cleared ends up
writing over further members.

Such a call happens in the trace code to clear, at once, all members
after and including `seq` on struct trace_iterator:

    In function 'memset',
        inlined from 'ftrace_dump' at kernel/trace/trace.c:8914:3:
    ./include/linux/string.h:344:9: warning: '__builtin_memset' offset
    [8505, 8560] from the object at 'iter' is out of the bounds of
    referenced subobject 'seq' with type 'struct trace_seq' at offset
    4368 [-Warray-bounds]
      344 |  return __builtin_memset(p, c, size);
          |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~

In order to avoid GCC complaining about it, we compute the address
ourselves by adding the offsetof distance instead of referring
directly to the member.

Since there are two places doing this clear (trace.c and trace_kdb.c),
take the chance to move the workaround into a single place in
the internal header.

Signed-off-by: Miguel Ojeda <miguel.ojeda.sandonis@gmail.com>
---
 kernel/trace/trace.c     |  7 +------
 kernel/trace/trace.h     | 14 ++++++++++++++
 kernel/trace/trace_kdb.c |  7 +------
 3 files changed, 16 insertions(+), 12 deletions(-)

diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index ca1ee656d6d8..37990532351b 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -8627,12 +8627,7 @@ void ftrace_dump(enum ftrace_dump_mode oops_dump_mode)
 
 		cnt++;
 
-		/* reset all but tr, trace, and overruns */
-		memset(&iter.seq, 0,
-		       sizeof(struct trace_iterator) -
-		       offsetof(struct trace_iterator, seq));
-		iter.iter_flags |= TRACE_FILE_LAT_FMT;
-		iter.pos = -1;
+		trace_iterator_reset(&iter);
 
 		if (trace_find_next_entry_inc(&iter) != NULL) {
 			int ret;
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
index d80cee49e0eb..80ad656f43eb 100644
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -1964,4 +1964,18 @@ static inline void tracer_hardirqs_off(unsigned long a0, unsigned long a1) { }
 
 extern struct trace_iterator *tracepoint_print_iter;
 
+/* reset all but tr, trace, and overruns */
+static __always_inline void trace_iterator_reset(struct trace_iterator * iter)
+{
+	/*
+	 * Equivalent to &iter->seq, but avoids GCC 9 complaining about
+	 * overwriting more members than just iter->seq (-Warray-bounds)
+	 */
+	memset((char *)(iter) + offsetof(struct trace_iterator, seq), 0,
+	       sizeof(struct trace_iterator) -
+	       offsetof(struct trace_iterator, seq));
+	iter->iter_flags |= TRACE_FILE_LAT_FMT;
+	iter->pos = -1;
+}
+
 #endif /* _LINUX_KERNEL_TRACE_H */
diff --git a/kernel/trace/trace_kdb.c b/kernel/trace/trace_kdb.c
index 810d78a8d14c..0a2a166ee716 100644
--- a/kernel/trace/trace_kdb.c
+++ b/kernel/trace/trace_kdb.c
@@ -41,12 +41,7 @@ static void ftrace_dump_buf(int skip_lines, long cpu_file)
 
 	kdb_printf("Dumping ftrace buffer:\n");
 
-	/* reset all but tr, trace, and overruns */
-	memset(&iter.seq, 0,
-		   sizeof(struct trace_iterator) -
-		   offsetof(struct trace_iterator, seq));
-	iter.iter_flags |= TRACE_FILE_LAT_FMT;
-	iter.pos = -1;
+	trace_iterator_reset(&iter);
 
 	if (cpu_file == RING_BUFFER_ALL_CPUS) {
 		for_each_tracing_cpu(cpu) {
-- 
2.17.1


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

* Re: [PATCH] tracing: silence GCC 9 array bounds warning
  2019-05-17  9:25 [PATCH] tracing: silence GCC 9 array bounds warning Miguel Ojeda
@ 2019-05-17 16:47 ` Steven Rostedt
  2019-05-17 18:45   ` Miguel Ojeda
  2019-05-17 17:59 ` Linus Torvalds
  2019-05-17 20:54 ` Miguel Ojeda
  2 siblings, 1 reply; 11+ messages in thread
From: Steven Rostedt @ 2019-05-17 16:47 UTC (permalink / raw)
  To: Miguel Ojeda; +Cc: Ingo Molnar, linux-kernel, Linus Torvalds

On Fri, 17 May 2019 11:25:02 +0200
Miguel Ojeda <miguel.ojeda.sandonis@gmail.com> wrote:

> Starting with GCC 9, -Warray-bounds detects cases when memset is called
> starting on a member of a struct but the size to be cleared ends up
> writing over further members.
> 
> Such a call happens in the trace code to clear, at once, all members
> after and including `seq` on struct trace_iterator:
> 
>     In function 'memset',
>         inlined from 'ftrace_dump' at kernel/trace/trace.c:8914:3:
>     ./include/linux/string.h:344:9: warning: '__builtin_memset' offset
>     [8505, 8560] from the object at 'iter' is out of the bounds of
>     referenced subobject 'seq' with type 'struct trace_seq' at offset
>     4368 [-Warray-bounds]
>       344 |  return __builtin_memset(p, c, size);
>           |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
> 
> In order to avoid GCC complaining about it, we compute the address
> ourselves by adding the offsetof distance instead of referring
> directly to the member.
> 
> Since there are two places doing this clear (trace.c and trace_kdb.c),
> take the chance to move the workaround into a single place in
> the internal header.

Hi Miguel,

Linus mentioned this too.

 https://lore.kernel.org/lkml/CAHk-=wihYB8w__YQjgYjYZsVniu5CtkTcFycmCGdqVg8GUje7g@mail.gmail.com/T/#u

I was going to do a helper function, and put it in the queue for the
next merge window (as it isn't really a bug, just gcc complaining a
little more aggressively). But since you already did the patch, I'll
use yours. But I have some nits about it below.


Add here:

Reported-by: Linus Torvalds <torvalds@linux-foundation.org>
Link: http://lkml.kernel.org/r/CAHk-=wihYB8w__YQjgYjYZsVniu5CtkTcFycmCGdqVg8GUje7g@mail.gmail.com

> 
> Signed-off-by: Miguel Ojeda <miguel.ojeda.sandonis@gmail.com>
> ---
>  kernel/trace/trace.c     |  7 +------
>  kernel/trace/trace.h     | 14 ++++++++++++++
>  kernel/trace/trace_kdb.c |  7 +------
>  3 files changed, 16 insertions(+), 12 deletions(-)
> 
> diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
> index ca1ee656d6d8..37990532351b 100644
> --- a/kernel/trace/trace.c
> +++ b/kernel/trace/trace.c
> @@ -8627,12 +8627,7 @@ void ftrace_dump(enum ftrace_dump_mode
> oops_dump_mode) 
>  		cnt++;
>  
> -		/* reset all but tr, trace, and overruns */
> -		memset(&iter.seq, 0,
> -		       sizeof(struct trace_iterator) -
> -		       offsetof(struct trace_iterator, seq));
> -		iter.iter_flags |= TRACE_FILE_LAT_FMT;

Setting the LAT_FMT isn't something a function called "reset" should do.

> -		iter.pos = -1;
> +		trace_iterator_reset(&iter);
>  
>  		if (trace_find_next_entry_inc(&iter) != NULL) {
>  			int ret;
> diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
> index d80cee49e0eb..80ad656f43eb 100644
> --- a/kernel/trace/trace.h
> +++ b/kernel/trace/trace.h
> @@ -1964,4 +1964,18 @@ static inline void
> tracer_hardirqs_off(unsigned long a0, unsigned long a1) { } 
>  extern struct trace_iterator *tracepoint_print_iter;
>  
> +/* reset all but tr, trace, and overruns */
> +static __always_inline void trace_iterator_reset(struct
> trace_iterator * iter) +{
> +	/*
> +	 * Equivalent to &iter->seq, but avoids GCC 9 complaining
> about
> +	 * overwriting more members than just iter->seq
> (-Warray-bounds)
> +	 */
> +	memset((char *)(iter) + offsetof(struct trace_iterator,

Why (char *)? Please use (void *).

> seq), 0,
> +	       sizeof(struct trace_iterator) -
> +	       offsetof(struct trace_iterator, seq));

Make a variable for offset and reuse that (see Linus's email).

> +	iter->iter_flags |= TRACE_FILE_LAT_FMT;

Again, leave the LAT_FMT change in the other locations.

Please send a v2 version with these updates.

Thanks!

-- Steve

> +	iter->pos = -1;
> +}
> +
>  #endif /* _LINUX_KERNEL_TRACE_H */
> diff --git a/kernel/trace/trace_kdb.c b/kernel/trace/trace_kdb.c
> index 810d78a8d14c..0a2a166ee716 100644
> --- a/kernel/trace/trace_kdb.c
> +++ b/kernel/trace/trace_kdb.c
> @@ -41,12 +41,7 @@ static void ftrace_dump_buf(int skip_lines, long
> cpu_file) 
>  	kdb_printf("Dumping ftrace buffer:\n");
>  
> -	/* reset all but tr, trace, and overruns */
> -	memset(&iter.seq, 0,
> -		   sizeof(struct trace_iterator) -
> -		   offsetof(struct trace_iterator, seq));
> -	iter.iter_flags |= TRACE_FILE_LAT_FMT;
> -	iter.pos = -1;
> +	trace_iterator_reset(&iter);
>  
>  	if (cpu_file == RING_BUFFER_ALL_CPUS) {
>  		for_each_tracing_cpu(cpu) {


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

* Re: [PATCH] tracing: silence GCC 9 array bounds warning
  2019-05-17  9:25 [PATCH] tracing: silence GCC 9 array bounds warning Miguel Ojeda
  2019-05-17 16:47 ` Steven Rostedt
@ 2019-05-17 17:59 ` Linus Torvalds
  2019-05-17 19:09   ` Miguel Ojeda
  2019-05-17 20:54 ` Miguel Ojeda
  2 siblings, 1 reply; 11+ messages in thread
From: Linus Torvalds @ 2019-05-17 17:59 UTC (permalink / raw)
  To: Miguel Ojeda; +Cc: Steven Rostedt, Ingo Molnar, Linux List Kernel Mailing

On Fri, May 17, 2019 at 2:25 AM Miguel Ojeda
<miguel.ojeda.sandonis@gmail.com> wrote:
>
> +       memset((char *)(iter) + offsetof(struct trace_iterator, seq), 0,
> +              sizeof(struct trace_iterator) -
> +              offsetof(struct trace_iterator, seq));

Honestly, the above is nasty.

Whenever you have to split an expression or statement over several
lines, you should ask yourself why it's so complicated.

This can be trivially rewritten as

        const unsigned int offset = offsetof(struct trace_iterator, seq);
        memset(offset + (void *)iter, 0, sizeof(*iter) - offset);

and now we have two much simpler expressions that are each much easier
to read and don't need multiple lines.

In particular using that "offset" variable means that you can
trivially see that "oh, we're starting the memset at that offset, and
we're using the 'sizeof() - offset' thing to limit the size". It's a
lot clearer to use the same trivial 'offset' thing in both the offset
and the size, than to have a more complex expression that it
duplicated twice and is not at all as visually obvious that it's the
exact same thing simply because it's bigger and more complex.

Also, the while 'offset' is a variable, any compiler will immediately
see that it's a constant value, so it's not like this will affect the
generated code at all. Unless you compile with something crazy like
'-O0', which is not a supported configuration exactly because we
expect compilers to not be terminally stupid.

So you get simpler and clearer source, with no downsides.

               Linus

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

* Re: [PATCH] tracing: silence GCC 9 array bounds warning
  2019-05-17 16:47 ` Steven Rostedt
@ 2019-05-17 18:45   ` Miguel Ojeda
  0 siblings, 0 replies; 11+ messages in thread
From: Miguel Ojeda @ 2019-05-17 18:45 UTC (permalink / raw)
  To: Steven Rostedt; +Cc: Ingo Molnar, linux-kernel, Linus Torvalds

Hi Steven,

On Fri, May 17, 2019 at 6:47 PM Steven Rostedt <rostedt@goodmis.org> wrote:
>
> Hi Miguel,
>
> Linus mentioned this too.
>
>  https://lore.kernel.org/lkml/CAHk-=wihYB8w__YQjgYjYZsVniu5CtkTcFycmCGdqVg8GUje7g@mail.gmail.com/T/#u

Ah, I didn't see that. We were discussing here [1] backporting to 4.19
some cleanups we did for GCC 9 a few months ago, so I was testing that
Linus' master was still clean a few hours ago. When I found that
couple of warnings I quickly made a patch before I forgot. I should
probably have added RFC :-)

[1] https://lore.kernel.org/lkml/CANiq72=fsL5m2_e+bNovFCHy3=YVf53EKGtGE_sWvsAD=ONHuQ@mail.gmail.com/

> Setting the LAT_FMT isn't something a function called "reset" should do.

I added the surrounding code heuristically since it was in a single
block with the comment above and since it was repeated in both places,
but I had no idea on the semantics. :-)

> > +     memset((char *)(iter) + offsetof(struct trace_iterator,
>
> Why (char *)? Please use (void *).

We are adding a byte-sized offset, so char * is the one that makes
sense. Doing it with void * works, although it is a GNU extension. But
as you prefer :-)

Cheers,
Miguel

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

* Re: [PATCH] tracing: silence GCC 9 array bounds warning
  2019-05-17 17:59 ` Linus Torvalds
@ 2019-05-17 19:09   ` Miguel Ojeda
  2019-05-19 21:35     ` Steven Rostedt
  0 siblings, 1 reply; 11+ messages in thread
From: Miguel Ojeda @ 2019-05-17 19:09 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Steven Rostedt, Ingo Molnar, Linux List Kernel Mailing

On Fri, May 17, 2019 at 7:59 PM Linus Torvalds
<torvalds@linux-foundation.org> wrote:
>
> On Fri, May 17, 2019 at 2:25 AM Miguel Ojeda
> <miguel.ojeda.sandonis@gmail.com> wrote:
> >
> > +       memset((char *)(iter) + offsetof(struct trace_iterator, seq), 0,
> > +              sizeof(struct trace_iterator) -
> > +              offsetof(struct trace_iterator, seq));
>
> Honestly, the above is nasty.
>
> Whenever you have to split an expression or statement over several
> lines, you should ask yourself why it's so complicated.

Will do -- I was trying to keep the code as closely to the original as
possible (I simply replaced the &iter.seq expression :-)

By the way, how do you all feel about moving this as a generic
facility to zero out the suffix/prefix of an structure? In particular,
since we won't have the LAT* stuff according to Steven.

> Also, the while 'offset' is a variable, any compiler will immediately
> see that it's a constant value, so it's not like this will affect the
> generated code at all.

I like C++'s constexpr (for variable defs), maybe one day we will get
it on C; it is useful to cleanly annotate compile-time values like
this.

> Unless you compile with something crazy like
> '-O0', which is not a supported configuration exactly because we
> expect compilers to not be terminally stupid.

Fun fact: it seems clang folds some of these even under -O0. In
godbolt I see it folding the third argument completely. The first one
isn't, but it is computed on the function prologue, leaving the
'offset' variable unused.

Cheers,
Miguel

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

* Re: [PATCH] tracing: silence GCC 9 array bounds warning
  2019-05-17  9:25 [PATCH] tracing: silence GCC 9 array bounds warning Miguel Ojeda
  2019-05-17 16:47 ` Steven Rostedt
  2019-05-17 17:59 ` Linus Torvalds
@ 2019-05-17 20:54 ` Miguel Ojeda
  2 siblings, 0 replies; 11+ messages in thread
From: Miguel Ojeda @ 2019-05-17 20:54 UTC (permalink / raw)
  To: Steven Rostedt, Ingo Molnar; +Cc: linux-kernel, Linus Torvalds

On Fri, May 17, 2019 at 11:25 AM Miguel Ojeda
<miguel.ojeda.sandonis@gmail.com> wrote:
>
>     ./include/linux/string.h:344:9: warning: '__builtin_memset' offset
>     [8505, 8560] from the object at 'iter' is out of the bounds of

By the way, I noticed these offsets of the new warning seem to be off
by 1, reported here:

    https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90525

Cheers,
Miguel

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

* Re: [PATCH] tracing: silence GCC 9 array bounds warning
  2019-05-17 19:09   ` Miguel Ojeda
@ 2019-05-19 21:35     ` Steven Rostedt
  0 siblings, 0 replies; 11+ messages in thread
From: Steven Rostedt @ 2019-05-19 21:35 UTC (permalink / raw)
  To: Miguel Ojeda; +Cc: Linus Torvalds, Ingo Molnar, Linux List Kernel Mailing

On Fri, 17 May 2019 21:09:21 +0200
Miguel Ojeda <miguel.ojeda.sandonis@gmail.com> wrote:

> By the way, how do you all feel about moving this as a generic
> facility to zero out the suffix/prefix of an structure? In particular,
> since we won't have the LAT* stuff according to Steven.

Is this done in other places? If so, how many.

Note, the LAT* update doesn't belong in the iterator reset function,
but the pos = -1 still does.

Thanks!

-- Steve

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

* Re: [PATCH] tracing: silence GCC 9 array bounds warning
  2019-05-24  4:05   ` Miguel Ojeda
@ 2019-05-24 11:52     ` Steven Rostedt
  0 siblings, 0 replies; 11+ messages in thread
From: Steven Rostedt @ 2019-05-24 11:52 UTC (permalink / raw)
  To: Miguel Ojeda; +Cc: Ingo Molnar, Linus Torvalds, linux-kernel

On Fri, 24 May 2019 06:05:36 +0200
Miguel Ojeda <miguel.ojeda.sandonis@gmail.com> wrote:

> On Fri, May 24, 2019 at 4:12 AM Steven Rostedt <rostedt@goodmis.org> wrote:
> >
> > On Thu, 23 May 2019 14:45:35 +0200
> > Miguel Ojeda <miguel.ojeda.sandonis@gmail.com> wrote:
> >
> > I still prefer the typecast of void *, as that's used a bit more in the
> > kernel, but since char * is also used (not as much), I'll leave it. But
> > the parenthesis around iter are unnecessary. I'll remove them.  
> 
> If the preferred style in the kernel is void *, change it on your
> side, please! :-) Maybe we should mention it in the coding guidelines.
>

Well, it's not officially the preferred style. There's 240 uses of
(void *) in memset, compared to 98 uses of (char *)

$ git grep memset | grep '(void \*)' | wc -l
240

$ git grep memset | grep '(char \*)' | wc -l
98

I was about to make the conversion, but when I added addition to the
equation, the (char *) went ahead slightly:

$ git grep memset | grep '(void \*)' | grep '+' | wc -l
32

$ git grep memset | grep '(char \*)' | grep '+' | wc -l
35

Both are fine and legit, but as the weight is slightly higher doing
byte arithmetic with char *, I'll keep it as is.

-- STeve

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

* Re: [PATCH] tracing: silence GCC 9 array bounds warning
  2019-05-24  2:12 ` Steven Rostedt
@ 2019-05-24  4:05   ` Miguel Ojeda
  2019-05-24 11:52     ` Steven Rostedt
  0 siblings, 1 reply; 11+ messages in thread
From: Miguel Ojeda @ 2019-05-24  4:05 UTC (permalink / raw)
  To: Steven Rostedt; +Cc: Ingo Molnar, Linus Torvalds, linux-kernel

On Fri, May 24, 2019 at 4:12 AM Steven Rostedt <rostedt@goodmis.org> wrote:
>
> On Thu, 23 May 2019 14:45:35 +0200
> Miguel Ojeda <miguel.ojeda.sandonis@gmail.com> wrote:
>
> I still prefer the typecast of void *, as that's used a bit more in the
> kernel, but since char * is also used (not as much), I'll leave it. But
> the parenthesis around iter are unnecessary. I'll remove them.

If the preferred style in the kernel is void *, change it on your
side, please! :-) Maybe we should mention it in the coding guidelines.

Cheers,
Miguel

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

* Re: [PATCH] tracing: silence GCC 9 array bounds warning
  2019-05-23 12:45 Miguel Ojeda
@ 2019-05-24  2:12 ` Steven Rostedt
  2019-05-24  4:05   ` Miguel Ojeda
  0 siblings, 1 reply; 11+ messages in thread
From: Steven Rostedt @ 2019-05-24  2:12 UTC (permalink / raw)
  To: Miguel Ojeda; +Cc: Ingo Molnar, Linus Torvalds, linux-kernel

On Thu, 23 May 2019 14:45:35 +0200
Miguel Ojeda <miguel.ojeda.sandonis@gmail.com> wrote:

> +/*
> + * Reset the state of the trace_iterator so that it can read consumed data.
> + * Normally, the trace_iterator is used for reading the data when it is not
> + * consumed, and must retain state.
> + */
> +static __always_inline void trace_iterator_reset(struct trace_iterator *iter)
> +{
> +	const size_t offset = offsetof(struct trace_iterator, seq);
> +
> +	/*
> +	 * Keep gcc from complaining about overwriting more than just one
> +	 * member in the structure.
> +	 */
> +	memset((char *)(iter) + offset, 0, sizeof(struct trace_iterator) - offset);

I still prefer the typecast of void *, as that's used a bit more in the
kernel, but since char * is also used (not as much), I'll leave it. But
the parenthesis around iter are unnecessary. I'll remove them.

-- Steve


> +
> +	iter->pos = -1;
> +}
> +

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

* [PATCH] tracing: silence GCC 9 array bounds warning
@ 2019-05-23 12:45 Miguel Ojeda
  2019-05-24  2:12 ` Steven Rostedt
  0 siblings, 1 reply; 11+ messages in thread
From: Miguel Ojeda @ 2019-05-23 12:45 UTC (permalink / raw)
  To: Steven Rostedt, Ingo Molnar; +Cc: Linus Torvalds, linux-kernel

Starting with GCC 9, -Warray-bounds detects cases when memset is called
starting on a member of a struct but the size to be cleared ends up
writing over further members.

Such a call happens in the trace code to clear, at once, all members
after and including `seq` on struct trace_iterator:

    In function 'memset',
        inlined from 'ftrace_dump' at kernel/trace/trace.c:8914:3:
    ./include/linux/string.h:344:9: warning: '__builtin_memset' offset
    [8505, 8560] from the object at 'iter' is out of the bounds of
    referenced subobject 'seq' with type 'struct trace_seq' at offset
    4368 [-Warray-bounds]
      344 |  return __builtin_memset(p, c, size);
          |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~

In order to avoid GCC complaining about it, we compute the address
ourselves by adding the offsetof distance instead of referring
directly to the member.

Since there are two places doing this clear (trace.c and trace_kdb.c),
take the chance to move the workaround into a single place in
the internal header.

Signed-off-by: Miguel Ojeda <miguel.ojeda.sandonis@gmail.com>
---
 kernel/trace/trace.c     |  6 +-----
 kernel/trace/trace.h     | 18 ++++++++++++++++++
 kernel/trace/trace_kdb.c |  6 +-----
 3 files changed, 20 insertions(+), 10 deletions(-)

diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 2c92b3d9ea30..1c80521fd436 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -8910,12 +8910,8 @@ void ftrace_dump(enum ftrace_dump_mode oops_dump_mode)
 
 		cnt++;
 
-		/* reset all but tr, trace, and overruns */
-		memset(&iter.seq, 0,
-		       sizeof(struct trace_iterator) -
-		       offsetof(struct trace_iterator, seq));
+		trace_iterator_reset(&iter);
 		iter.iter_flags |= TRACE_FILE_LAT_FMT;
-		iter.pos = -1;
 
 		if (trace_find_next_entry_inc(&iter) != NULL) {
 			int ret;
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
index 1974ce818ddb..ac63ad5acb93 100644
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -1967,4 +1967,22 @@ static inline void tracer_hardirqs_off(unsigned long a0, unsigned long a1) { }
 
 extern struct trace_iterator *tracepoint_print_iter;
 
+/*
+ * Reset the state of the trace_iterator so that it can read consumed data.
+ * Normally, the trace_iterator is used for reading the data when it is not
+ * consumed, and must retain state.
+ */
+static __always_inline void trace_iterator_reset(struct trace_iterator *iter)
+{
+	const size_t offset = offsetof(struct trace_iterator, seq);
+
+	/*
+	 * Keep gcc from complaining about overwriting more than just one
+	 * member in the structure.
+	 */
+	memset((char *)(iter) + offset, 0, sizeof(struct trace_iterator) - offset);
+
+	iter->pos = -1;
+}
+
 #endif /* _LINUX_KERNEL_TRACE_H */
diff --git a/kernel/trace/trace_kdb.c b/kernel/trace/trace_kdb.c
index 6c1ae6b752d1..cca65044c14c 100644
--- a/kernel/trace/trace_kdb.c
+++ b/kernel/trace/trace_kdb.c
@@ -37,12 +37,8 @@ static void ftrace_dump_buf(int skip_entries, long cpu_file)
 	if (skip_entries)
 		kdb_printf("(skipping %d entries)\n", skip_entries);
 
-	/* reset all but tr, trace, and overruns */
-	memset(&iter.seq, 0,
-		   sizeof(struct trace_iterator) -
-		   offsetof(struct trace_iterator, seq));
+	trace_iterator_reset(&iter);
 	iter.iter_flags |= TRACE_FILE_LAT_FMT;
-	iter.pos = -1;
 
 	if (cpu_file == RING_BUFFER_ALL_CPUS) {
 		for_each_tracing_cpu(cpu) {
-- 
2.17.1


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

end of thread, other threads:[~2019-05-24 11:52 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-05-17  9:25 [PATCH] tracing: silence GCC 9 array bounds warning Miguel Ojeda
2019-05-17 16:47 ` Steven Rostedt
2019-05-17 18:45   ` Miguel Ojeda
2019-05-17 17:59 ` Linus Torvalds
2019-05-17 19:09   ` Miguel Ojeda
2019-05-19 21:35     ` Steven Rostedt
2019-05-17 20:54 ` Miguel Ojeda
2019-05-23 12:45 Miguel Ojeda
2019-05-24  2:12 ` Steven Rostedt
2019-05-24  4:05   ` Miguel Ojeda
2019-05-24 11:52     ` Steven Rostedt

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).