Skip to content

Commit

Permalink
mm: slub: be more careful about the double cmpxchg of freelist
Browse files Browse the repository at this point in the history
commit 5076190 upstream.

This is just a cleanup addition to Jann's fix to properly update the
transaction ID for the slub slowpath in commit fd4d9c7 ("mm: slub:
add missing TID bump..").

The transaction ID is what protects us against any concurrent accesses,
but we should really also make sure to make the 'freelist' comparison
itself always use the same freelist value that we then used as the new
next free pointer.

Jann points out that if we do all of this carefully, we could skip the
transaction ID update for all the paths that only remove entries from
the lists, and only update the TID when adding entries (to avoid the ABA
issue with cmpxchg and list handling re-adding a previously seen value).

But this patch just does the "make sure to cmpxchg the same value we
used" rather than then try to be clever.

Acked-by: Jann Horn <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
  • Loading branch information
torvalds authored and gregkh committed Apr 2, 2020
1 parent 62628b8 commit e663542
Showing 1 changed file with 4 additions and 2 deletions.
6 changes: 4 additions & 2 deletions mm/slub.c
Original file line number Diff line number Diff line change
Expand Up @@ -2935,11 +2935,13 @@ static __always_inline void do_slab_free(struct kmem_cache *s,
barrier();

if (likely(page == c->page)) {
set_freepointer(s, tail_obj, c->freelist);
void **freelist = READ_ONCE(c->freelist);

set_freepointer(s, tail_obj, freelist);

if (unlikely(!this_cpu_cmpxchg_double(
s->cpu_slab->freelist, s->cpu_slab->tid,
c->freelist, tid,
freelist, tid,
head, next_tid(tid)))) {

note_cmpxchg_failure("slab_free", s, tid);
Expand Down

0 comments on commit e663542

Please sign in to comment.