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