Thread (15 messages) 15 messages, 2 authors, 2021-11-29

Re: [RFC PATCH 1/1] mm/slub: fix endless "No data" printing for alloc/free_traces attribute

From: Vlastimil Babka <hidden>
Date: 2021-11-23 14:19:53
Also in: linux-s390, lkml

On 11/22/21 21:33, Gerald Schaefer wrote:
On Mon, 22 Nov 2021 21:14:00 +0100
Gerald Schaefer [off-list ref] wrote:

[...]
quoted
Thanks. While testing this properly, yet another bug showed up. The idx
in op->show remains 0 in all iterations, so I always see the same line
printed t->count times (or infinitely, ATM). Not sure if this only shows
on s390 due to endianness, but the reason is this:

  unsigned int idx = *(unsigned int *)v;
Uh, good catch. I was actually looking suspiciously at how we cast signed to
unsigned, but didn't occur to me that shortening together with endiannes is
the problem.
quoted
IIUC, void *v is always the same as loff_t *ppos, and therefore idx also
should be *ppos. De-referencing the loff_t * with an unsigned int * only
gives the upper 32 bit half of the 64 bit value, which remains 0.

This would be fixed e.g. with

  unsigned int idx = (unsigned int) *(loff_t *) v;
With all this experience I'm now inclined to rather follow more the example
in Documentation/filesystems/seq_file.rst and don't pass around the pointer
that we got as ppos in slab_debugfs_start(), and that seq_file.c points to
m->index.

In that example an own value is kmalloced:

loff_t *spos = kmalloc(sizeof(loff_t), GFP_KERNEL);

while we could just make this a field of loc_track?

quoted
With this fixed, my original patch actually also works for t->count > 0,
because then op->show would return w/o printing anything when idx reaches
t->count. For t->count > 0, it would even work w/o any extra checks in
op->start because of that, only "No data" would be printed infinitely.
Oh, no, that would actually also fix the "No data" part, as op->show
will then also return w/o printing in the next iteration, so that op->next
would correctly end it all.

This could also explain why it might all have worked fine on x86 (haven't
verified), and really only showed on big-endian s390.

Hmm, now I'm not so sure anymore if we really want the additional
checks and return NULL in op->start, just to make it "double safe".
I guess we don't.
quoted
It probably still makes sense to make this explicit in op->start, by
checking separately for !*ppos && !t->count, and returning NULL for
*ppos >= t->count, as you suggested.

I think I will also make idx an unsigned long again, like it was before
commit 64dd68497be7, and similar to t->count. Not sure if it needs to
be, and with proper casting unsigned int is also possible, but why
change it?
  
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help