On Mon, 18 Aug 2014, Paul E. McKenney wrote: > > +#ifdef CONFIG_RCU_DEBUG_XYZ > > If you make CONFIG_RCU_DEBUG_XYZ instead be CONFIG_DEBUG_OBJECTS_RCU_HEAD, > then it will automatically show up when it needs to. Ok. > The rest looks plausible, for whatever that is worth. We talked in the hallway about init_rcu_head not touching the contents of the rcu_head. If that is the case then we can simplify the patch. We could also remove the #ifdefs if init_rcu_head and destroy_rcu_head are no ops if CONFIG_DEBUG_RCU_HEAD is not defined. Index: linux/mm/slub.c =================================================================== --- linux.orig/mm/slub.c +++ linux/mm/slub.c @@ -1308,6 +1308,25 @@ static inline struct page *alloc_slab_pa return page; } +#define need_reserve_slab_rcu \ + (sizeof(((struct page *)NULL)->lru) < sizeof(struct rcu_head)) + +static struct rcu_head *get_rcu_head(struct kmem_cache *s, struct page *page) +{ + if (need_reserve_slab_rcu) { + int order = compound_order(page); + int offset = (PAGE_SIZE << order) - s->reserved; + + VM_BUG_ON(s->reserved != sizeof(struct rcu_head)); + return page_address(page) + offset; + } else { + /* + * RCU free overloads the RCU head over the LRU + */ + return (void *)&page->lru; + } +} + static struct page *allocate_slab(struct kmem_cache *s, gfp_t flags, int node) { struct page *page; @@ -1357,6 +1376,22 @@ static struct page *allocate_slab(struct kmemcheck_mark_unallocated_pages(page, pages); } +#ifdef CONFIG_DEBUG_OBJECTS_RCU_HEAD + if (unlikely(s->flags & SLAB_DESTROY_BY_RCU) && page) + /* + * Initialize various things. However, this init is + * not allowed to modify the contents of the rcu head. + * Allocations are permitted. However, the use of + * the same cache or another cache with SLAB_RCU_DESTROY + * set may cause additional recursions. + * + * So in order to be safe the slab caches used + * in init_rcu_head should be restricted to be of the + * non rcu kind only. + */ + init_rcu_head(get_rcu_head(s, page)); +#endif + if (flags & __GFP_WAIT) local_irq_disable(); if (!page) @@ -1452,13 +1487,13 @@ static void __free_slab(struct kmem_cach memcg_uncharge_slab(s, order); } -#define need_reserve_slab_rcu \ - (sizeof(((struct page *)NULL)->lru) < sizeof(struct rcu_head)) - static void rcu_free_slab(struct rcu_head *h) { struct page *page; +#ifdef CONFIG_DEBUG_OBJECTS_RCU_HEAD + destroy_rcu_head(h); +#endif if (need_reserve_slab_rcu) page = virt_to_head_page(h); else @@ -1469,24 +1504,9 @@ static void rcu_free_slab(struct rcu_hea static void free_slab(struct kmem_cache *s, struct page *page) { - if (unlikely(s->flags & SLAB_DESTROY_BY_RCU)) { - struct rcu_head *head; - - if (need_reserve_slab_rcu) { - int order = compound_order(page); - int offset = (PAGE_SIZE << order) - s->reserved; - - VM_BUG_ON(s->reserved != sizeof(*head)); - head = page_address(page) + offset; - } else { - /* - * RCU free overloads the RCU head over the LRU - */ - head = (void *)&page->lru; - } - - call_rcu(head, rcu_free_slab); - } else + if (unlikely(s->flags & SLAB_DESTROY_BY_RCU)) + call_rcu(get_rcu_head(s, page), rcu_free_slab); + else __free_slab(s, page); } -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@xxxxxxxxx. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@xxxxxxxxx"> email@xxxxxxxxx </a>