Hello, Jann. 2020년 12월 23일 (수) 오후 9:52, Jann Horn <jannh@xxxxxxxxxx>님이 작성: > > The commit message of commit 7ced371971966 ("slub: Acquire_slab() > avoid loop") claims: > > > Avoid the loop in acquire slab and simply fail if there is a conflict. > > > > This will cause the next page on the list to be considered. > > However, get_partial_node() looks like this: > > static void *get_partial_node(struct kmem_cache *s, struct kmem_cache_node *n, > struct kmem_cache_cpu *c, gfp_t flags) > { > struct page *page, *page2; > void *object = NULL; > unsigned int available = 0; > int objects; > [...] > spin_lock(&n->list_lock); > list_for_each_entry_safe(page, page2, &n->partial, slab_list) { > void *t; > [...] > t = acquire_slab(s, n, page, object == NULL, &objects); > if (!t) > break; > [...] > } > spin_unlock(&n->list_lock); > return object; > } > > So actually, if the cmpxchg() fails, we'll entirely bail out of > get_partial_node() and might, if the system isn't NUMA, fall back to > allocating more memory with new_slab()? That seems to me like it might > cause fragmented slabs to slowly use more memory than they should over > time. Nice catch! I think you are right. > Should the loop in get_partial_node() be using "continue" instead of > "break" in that case, so that the rest of the partial list will be > considered as the commit message claims? Please send the patch. Thanks.