Fix alternate_node_alloc() on RT kernel
PATCH 1/1 Fix alternate_node_alloc() on RT kernel
__do_cache_allow/alternate_node_alloc() need to pass the this_cpu variable from the caller to cache_grow(); otherwise the slab lock for the wrong CPU can be released when a task switches CPUs inside cache_grow().
Signed-off-by Andi Kleen <[email protected]>
mm/slab.c +7 -6
@@ -1070,7 +1070,7 @@ cache_free_alien(struct kmem_cache *cach }static inline void *alternate_node_alloc (struct kmem_cache *cachep, -gfp_t flags) +gfp_t flags,int *this_cpu) {return NULL ; }
@@ -1085,7 +1085,7 @@ static inline void *____cache_alloc_nodestatic void *____cache_alloc_node (struct kmem_cache *cachep,gfp_t flags,int nodeid,int *this_cpu); -static void *alternate_node_alloc (struct kmem_cache *,gfp_t ); +static void *alternate_node_alloc (struct kmem_cache *,gfp_t ,int *);static struct array_cache **alloc_alien_cache (int node,int limit) {
@@ -3308,9 +3308,10 @@ ____cache_alloc(struct kmem_cache *cache* If we are in_interrupt, then process context, including cpusets and * mempolicy, may not apply and should not be used for allocation policy. */ -static void *alternate_node_alloc (struct kmem_cache *cachep,gfp_t flags) +static void *alternate_node_alloc (struct kmem_cache *cachep,gfp_t flags, +int *this_cpu) { -int nid_alloc, nid_here, this_cpu =raw_smp_processor_id (); +int nid_alloc, nid_here;if (in_interrupt () || (flags & __GFP_THISNODE))return NULL ;
@@ -3320,7 +3321,7 @@ static void *alternate_node_alloc(structelse if (current->mempolicy) nid_alloc =slab_node (current->mempolicy);if (nid_alloc != nid_here) -return ____cache_alloc_node (cachep, flags, nid_alloc, &this_cpu); +return ____cache_alloc_node (cachep, flags, nid_alloc, this_cpu);return NULL ; }
@@ -3533,7 +3534,7 @@ __do_cache_alloc(struct kmem_cache *cachvoid *objp;if (unlikely (current->flags & (PF_SPREAD_SLAB |PF_MEMPOLICY ))) { - objp =alternate_node_alloc (cache, flags); + objp =alternate_node_alloc (cache, flags, this_cpu);if (objp) goto out; }