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. -- Uladzislau Rezki