From 2e8b5219fffde42b8074bffe9a9714fe39443b86 Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Wed, 23 Jan 2013 21:45:48 +0000 Subject: [PATCH] --- yaml --- r: 373739 b: refs/heads/master c: 7cccd80b4397699902aced1ad3d692d384aaab77 h: refs/heads/master i: 373737: adcea39214d1f97fe4deea6bfeb04b6e3b33d7ff 373735: 67e950c0a152115c08c41722aaee2377c19b4e95 v: v3 --- [refs] | 2 +- trunk/mm/slub.c | 12 +++++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/[refs] b/[refs] index 69882772f6e9..eeda2f8fc69a 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 4d7868e6475d478172581828021bd8a356726679 +refs/heads/master: 7cccd80b4397699902aced1ad3d692d384aaab77 diff --git a/trunk/mm/slub.c b/trunk/mm/slub.c index 8b1b99d399cb..4df2c0c337fb 100644 --- a/trunk/mm/slub.c +++ b/trunk/mm/slub.c @@ -2332,13 +2332,18 @@ static __always_inline void *slab_alloc_node(struct kmem_cache *s, s = memcg_kmem_get_cache(s, gfpflags); redo: - /* * Must read kmem_cache cpu data via this cpu ptr. Preemption is * enabled. We may switch back and forth between cpus while * reading from one cpu area. That does not matter as long * as we end up on the original cpu again when doing the cmpxchg. + * + * Preemption is disabled for the retrieval of the tid because that + * must occur from the current processor. We cannot allow rescheduling + * on a different processor between the determination of the pointer + * and the retrieval of the tid. */ + preempt_disable(); c = __this_cpu_ptr(s->cpu_slab); /* @@ -2348,7 +2353,7 @@ static __always_inline void *slab_alloc_node(struct kmem_cache *s, * linked list in between. */ tid = c->tid; - barrier(); + preempt_enable(); object = c->freelist; page = c->page; @@ -2595,10 +2600,11 @@ static __always_inline void slab_free(struct kmem_cache *s, * data is retrieved via this pointer. If we are on the same cpu * during the cmpxchg then the free will succedd. */ + preempt_disable(); c = __this_cpu_ptr(s->cpu_slab); tid = c->tid; - barrier(); + preempt_enable(); if (likely(page == c->page)) { set_freepointer(s, object, c->freelist);