On Thu, Sep 3, 2009 at 8:59 PM, Eric Dumazet<eric.dumazet@xxxxxxxxx> wrote: > Christoph Lameter a écrit : >> On Thu, 3 Sep 2009, Eric Dumazet wrote: >> >>> Point is we cannot deal with RCU quietness before disposing the slab cache, >>> (if SLAB_DESTROY_BY_RCU was set on the cache) since this disposing *will* >>> make call_rcu() calls when a full slab is freed/purged. >> >> There is no need to do call_rcu calls for frees at that point since >> objects are no longer in use. We could simply disable SLAB_DESTROY_BY_RCU >> for the final clearing of caches. >> >>> And when RCU grace period is elapsed, the callback *will* need access to >>> the cache we want to dismantle. Better to not have kfreed()/poisoned it... >> >> But going through the RCU period is pointless since no user of the cache >> remains. >> >>> I believe you mix two RCU uses here. >>> >>> 1) The one we all know, is use normal caches (!SLAB_DESTROY_BY_RCU) >>> (or kmalloc()), and use call_rcu(... kfree_something) >>> >>> In this case, you are 100% right that the subsystem itself has >>> to call rcu_barrier() (or respect whatever self-synchro) itself, >>> before calling kmem_cache_destroy() >>> >>> 2) The SLAB_DESTROY_BY_RCU one. >>> >>> Part of cache dismantle needs to call rcu_barrier() itself. >>> Caller doesnt have to use rcu_barrier(). It would be a waste of time, >>> as kmem_cache_destroy() will refill rcu wait queues with its own stuff. >> >> The dismantling does not need RCU since there are no operations on the >> objects in progress. So simply switch DESTROY_BY_RCU off for close. >> >> >> --- >> mm/slub.c | 4 ++-- >> 1 file changed, 2 insertions(+), 2 deletions(-) >> >> Index: linux-2.6/mm/slub.c >> =================================================================== >> --- linux-2.6.orig/mm/slub.c 2009-09-03 10:14:51.000000000 -0500 >> +++ linux-2.6/mm/slub.c 2009-09-03 10:18:32.000000000 -0500 >> @@ -2594,9 +2594,9 @@ static inline int kmem_cache_close(struc >> */ >> void kmem_cache_destroy(struct kmem_cache *s) >> { >> - if (s->flags & SLAB_DESTROY_BY_RCU) >> - rcu_barrier(); >> down_write(&slub_lock); >> + /* Stop deferring frees so that we can immediately free structures */ >> + s->flags &= ~SLAB_DESTROY_BY_RCU; >> s->refcount--; >> if (!s->refcount) { >> list_del(&s->list); > > It seems very smart, but needs review of all callers to make sure no slabs > are waiting for final freeing in call_rcu queue on some cpu. > > I suspect most of them will then have to use rcu_barrier() before calling > kmem_cache_destroy(), so why not factorizing code in one place ? [snip] Can someone please explain what's the upside in Christoph's approach? Performance? Correctness? Something else entirely? We're looking at a tested bug fix here and I don't understand why I shouldn't just go ahead and merge it. Hmm? Pekka -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html