diff options
-rw-r--r-- | mm/slub.c | 25 |
1 files changed, 14 insertions, 11 deletions
diff --git a/mm/slub.c b/mm/slub.c index d9650f2ca776..90010407d17a 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -2836,22 +2836,25 @@ out: set_freepointer(s, tail, prior); slab->freelist = head; - /* Do we need to remove the slab from full or partial list? */ + /* + * If the slab is empty, and node's partial list is full, + * it should be discarded anyway no matter it's on full or + * partial list. + */ + if (slab->inuse == 0 && n->nr_partial >= s->min_partial) + slab_free = slab; + if (!prior) { + /* was on full list */ remove_full(s, n, slab); - } else if (slab->inuse == 0 && - n->nr_partial >= s->min_partial) { + if (!slab_free) { + add_partial(n, slab, DEACTIVATE_TO_TAIL); + stat(s, FREE_ADD_PARTIAL); + } + } else if (slab_free) { remove_partial(n, slab); stat(s, FREE_REMOVE_PARTIAL); } - - /* Do we need to discard the slab or add to partial list? */ - if (slab->inuse == 0 && n->nr_partial >= s->min_partial) { - slab_free = slab; - } else if (!prior) { - add_partial(n, slab, DEACTIVATE_TO_TAIL); - stat(s, FREE_ADD_PARTIAL); - } } if (slab_free) { |