On Tue, 12 Jul 2022, Hyeonggon Yoo wrote: > @@ -3241,31 +3219,46 @@ slab_alloc_node(struct kmem_cache *cachep, gfp_t flags, int nodeid, size_t orig_ > } > > static __always_inline void * > -__do_cache_alloc(struct kmem_cache *cache, gfp_t flags) > +__do_cache_alloc(struct kmem_cache *cachep, gfp_t flags, int nodeid) > { > - void *objp; > + void *objp = NULL; > + int slab_node = numa_mem_id(); > > - if (current->mempolicy || cpuset_do_slab_mem_spread()) { > - objp = alternate_node_alloc(cache, flags); > - if (objp) > - goto out; > + if (nodeid == NUMA_NO_NODE) { > + if (current->mempolicy || cpuset_do_slab_mem_spread()) { > + objp = alternate_node_alloc(cachep, flags); > + if (objp) > + goto out; > + } > + /* > + * Use the locally cached objects if possible. > + * However ____cache_alloc does not allow fallback > + * to other nodes. It may fail while we still have > + * objects on other nodes available. > + */ > + objp = ____cache_alloc(cachep, flags); > + nodeid = slab_node; > + } else if (nodeid == slab_node) { > + objp = ____cache_alloc(cachep, flags); > + } else if (!get_node(cachep, nodeid)) { > + /* Node not bootstrapped yet */ > + objp = fallback_alloc(cachep, flags); > + goto out; > } > - objp = ____cache_alloc(cache, flags); > > /* > * We may just have run out of memory on the local node. > * ____cache_alloc_node() knows how to locate memory on other nodes > */ > if (!objp) > - objp = ____cache_alloc_node(cache, flags, numa_mem_id()); > - > + objp = ____cache_alloc_node(cachep, flags, nodeid); Does this preserve the original behavior? nodeid is the parameter passed to __do_cache_alloc(). numa_mem_id() is the nearest memory node.