Re: How to increase rcu_head size without breaking -mm ?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 8/25/22 04:56, Joel Fernandes wrote:
> Hi,
> I am trying to add some debug information to rcu_head for some patches, and need
> your help! At least this used to work some time ago (> 1 year).

Hmm, got a patch of how it worked back then? Because what I see (in v5.12)
struct page definition:

	struct rcu_head rcu_head;

is in union with the whole of

	struct {        /* slab, slob and slub */ ... }

which starts with

	union { struct list_head slab_list;  ... }
	struct kmem_cache *slab_cache; /* not slob */

and there's e.g. kmem_rcu_free() in mm/slab.c that does

        page = container_of(head, struct page, rcu_head);
        cachep = page->slab_cache;

and very similar thing in mm/slub.c rcu_free_slab() - we assume that the
rcu_head and slab_cache fields can coexist.

So this looks silently fragile to me? In case rcu_head becomes larger than
list_head, e.g. with your buf[4], it would start overlaping the
page->slab_cache field, no?

AFAICS the way it's structured now in struct slab in mm/slab.h, it makes the
overlap impossible, thus the struct slab will grow as rcu_head grows, and
offsets of the later fields stop matching struct page counterparts, which
doesn't grow. Hmm.

> I get various SLAB_MATCH() errors with a change like this:
> 
> diff --git a/include/linux/types.h b/include/linux/types.h
> index ea8cf60a8a79..daf7682a7a3b 100644
> --- a/include/linux/types.h
> +++ b/include/linux/types.h
> @@ -220,6 +220,7 @@ struct ustat {
>  struct callback_head {
>         struct callback_head *next;
>         void (*func)(struct callback_head *head);
> +       char buf[4];
>  } __attribute__((aligned(sizeof(void *))));
>  #define rcu_head callback_head
> ---
> 
> Errors:
> mm/slab.h:67:9: note: in expansion of macro ‘static_assert’
>    67 |         static_assert(offsetof(struct page, pg) == offsetof(struct slab,
> sl))
>       |         ^~~~~~~~~~~~~
> mm/slab.h:73:1: note: in expansion of macro ‘SLAB_MATCH’
>    73 | SLAB_MATCH(_refcount, __page_refcount);
>       | ^~~~~~~~~~
> 
> ----------
> 
> I tried various things like increasing the struct slab or struct page size using
> dummy variables, but nothing gives.
> 
> I tried to print the offsets of the struct using the compiler, but that requires
> compilation to actually succeed. The same exercise with a pre-processor also
> does not help because nested structures could also including rcu_heads.
> 
> If I at least knew how the offsets were off, I could hack it for my needs (of
> course upstreaming such a change is a different story, but I do want to upstream
> some variant of rcu_head debug info).
> 
> Any thoughts on how we can accomplish this?
> 
> Thanks!
> 
>  - Joel




[Index of Archives]     [Linux Samsung SoC]     [Linux Rockchip SoC]     [Linux Actions SoC]     [Linux for Synopsys ARC Processors]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]


  Powered by Linux