On 02/28/24 at 11:39am, Uladzislau Rezki wrote: > On Wed, Feb 28, 2024 at 05:48:53PM +0800, Baoquan He wrote: > > On 01/02/24 at 07:46pm, Uladzislau Rezki (Sony) wrote: > > .....snip... > > > +static void > > > +decay_va_pool_node(struct vmap_node *vn, bool full_decay) > > > +{ > > > + struct vmap_area *va, *nva; > > > + struct list_head decay_list; > > > + struct rb_root decay_root; > > > + unsigned long n_decay; > > > + int i; > > > + > > > + decay_root = RB_ROOT; > > > + INIT_LIST_HEAD(&decay_list); > > > + > > > + for (i = 0; i < MAX_VA_SIZE_PAGES; i++) { > > > + struct list_head tmp_list; > > > + > > > + if (list_empty(&vn->pool[i].head)) > > > + continue; > > > + > > > + INIT_LIST_HEAD(&tmp_list); > > > + > > > + /* Detach the pool, so no-one can access it. */ > > > + spin_lock(&vn->pool_lock); > > > + list_replace_init(&vn->pool[i].head, &tmp_list); > > > + spin_unlock(&vn->pool_lock); > > > + > > > + if (full_decay) > > > + WRITE_ONCE(vn->pool[i].len, 0); > > > + > > > + /* Decay a pool by ~25% out of left objects. */ > > > > This isn't true if the pool has less than 4 objects. If there are 3 > > objects, n_decay = 0. > > > This is expectable. > > > > + n_decay = vn->pool[i].len >> 2; > > > + > > > + list_for_each_entry_safe(va, nva, &tmp_list, list) { > > > + list_del_init(&va->list); > > > + merge_or_add_vmap_area(va, &decay_root, &decay_list); > > > + > > > + if (!full_decay) { > > > + WRITE_ONCE(vn->pool[i].len, vn->pool[i].len - 1); > > > + > > > + if (!--n_decay) > > > + break; > > > > Here, --n_decay will make n_decay 0xffffffffffffffff, > > then all left objects are reclaimed. > Right. Last three objects do not play a big game. See it now, thanks.