On Tue, Jul 12, 2022 at 04:29:10PM +0200, Christoph Lameter wrote: > 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. Yes it does preserve the original behavior. nodeid equals to value of numa_mem_id() when nodeid was NUMA_NO_NODE and ____cache_alloc() failed to allocate.