Skip to content

Commit

Permalink
slub: drop lock at the end of free_debug_processing
Browse files Browse the repository at this point in the history
This series takes the suggestion of Christoph Lameter and only focuses
on optimizing the slow path where the debug processing runs.  The two
main optimizations in this series are letting the consistency checks be
skipped and relaxing the cmpxchg restrictions when we are not doing
consistency checks.  With hackbench -g 20 -l 1000 averaged over 100
runs:

Before slub_debug=P
  mean 15.607
  variance .086
  stdev .294

After slub_debug=P
  mean 10.836
  variance .155
  stdev .394

This still isn't as fast as what is in grsecurity unfortunately so there's
still work to be done.  Profiling ___slab_alloc shows that 25-50% of time
is spent in deactivate_slab.  I haven't looked too closely to see if this
is something that can be optimized.  My plan for now is to focus on
getting all of this merged (if appropriate) before digging in to another
task.

This patch (of 4):

Currently, free_debug_processing has a comment "Keep node_lock to preserve
integrity until the object is actually freed".  In actuallity, the lock is
dropped immediately in __slab_free.  Rather than wait until __slab_free
and potentially throw off the unlikely marking, just drop the lock in
__slab_free.  This also lets free_debug_processing take its own copy of
the spinlock flags rather than trying to share the ones from __slab_free.
Since there is no use for the node afterwards, change the return type of
free_debug_processing to return an int like alloc_debug_processing.

Credit to Mathias Krause for the original work which inspired this series

[[email protected]: fix build]
Signed-off-by: Laura Abbott <[email protected]>
Acked-by: Christoph Lameter <[email protected]>
Cc: Pekka Enberg <[email protected]>
Cc: David Rientjes <[email protected]>
Cc: Joonsoo Kim <[email protected]>
Cc: Kees Cook <[email protected]>
Cc: Mathias Krause <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
labbott authored and torvalds committed Mar 15, 2016
1 parent f68f8dd commit 282acb4
Showing 1 changed file with 11 additions and 14 deletions.
25 changes: 11 additions & 14 deletions mm/slub.c
Original file line number Diff line number Diff line change
Expand Up @@ -1044,16 +1044,17 @@ static noinline int alloc_debug_processing(struct kmem_cache *s,
}

/* Supports checking bulk free of a constructed freelist */
static noinline struct kmem_cache_node *free_debug_processing(
static noinline int free_debug_processing(
struct kmem_cache *s, struct page *page,
void *head, void *tail, int bulk_cnt,
unsigned long addr, unsigned long *flags)
unsigned long addr)
{
struct kmem_cache_node *n = get_node(s, page_to_nid(page));
void *object = head;
int cnt = 0;
unsigned long uninitialized_var(flags);

spin_lock_irqsave(&n->list_lock, *flags);
spin_lock_irqsave(&n->list_lock, flags);
slab_lock(page);

if (!check_slab(s, page))
Expand Down Expand Up @@ -1106,17 +1107,14 @@ static noinline struct kmem_cache_node *free_debug_processing(
bulk_cnt, cnt);

slab_unlock(page);
/*
* Keep node_lock to preserve integrity
* until the object is actually freed
*/
return n;
spin_unlock_irqrestore(&n->list_lock, flags);
return 1;

fail:
slab_unlock(page);
spin_unlock_irqrestore(&n->list_lock, *flags);
spin_unlock_irqrestore(&n->list_lock, flags);
slab_fix(s, "Object at 0x%p not freed", object);
return NULL;
return 0;
}

static int __init setup_slub_debug(char *str)
Expand Down Expand Up @@ -1207,10 +1205,10 @@ static inline void setup_object_debug(struct kmem_cache *s,
static inline int alloc_debug_processing(struct kmem_cache *s,
struct page *page, void *object, unsigned long addr) { return 0; }

static inline struct kmem_cache_node *free_debug_processing(
static inline int free_debug_processing(
struct kmem_cache *s, struct page *page,
void *head, void *tail, int bulk_cnt,
unsigned long addr, unsigned long *flags) { return NULL; }
unsigned long addr) { return 0; }

static inline int slab_pad_check(struct kmem_cache *s, struct page *page)
{ return 1; }
Expand Down Expand Up @@ -2588,8 +2586,7 @@ static void __slab_free(struct kmem_cache *s, struct page *page,
stat(s, FREE_SLOWPATH);

if (kmem_cache_debug(s) &&
!(n = free_debug_processing(s, page, head, tail, cnt,
addr, &flags)))
!free_debug_processing(s, page, head, tail, cnt, addr))
return;

do {
Expand Down

0 comments on commit 282acb4

Please sign in to comment.