On Sat, Mar 19, 2022 at 4:14 AM Barry Song <21cnbao@xxxxxxxxx> wrote: > > > +static void inc_max_seq(struct lruvec *lruvec, unsigned long max_seq) > > +{ > > + int prev, next; > > + int type, zone; > > + struct lru_gen_struct *lrugen = &lruvec->lrugen; > > + > > + spin_lock_irq(&lruvec->lru_lock); > > + > > + VM_BUG_ON(!seq_is_valid(lruvec)); > > + > > + if (max_seq != lrugen->max_seq) > > + goto unlock; > > + > > + inc_min_seq(lruvec); > > + > > + /* update the active/inactive LRU sizes for compatibility */ > > + prev = lru_gen_from_seq(lrugen->max_seq - 1); > > + next = lru_gen_from_seq(lrugen->max_seq + 1); > > + > > + for (type = 0; type < ANON_AND_FILE; type++) { > > + for (zone = 0; zone < MAX_NR_ZONES; zone++) { > > + enum lru_list lru = type * LRU_INACTIVE_FILE; > > + long delta = lrugen->nr_pages[prev][type][zone] - > > + lrugen->nr_pages[next][type][zone]; > > this is confusing to me. does lrugen->nr_pages[next][type][zone] have a > chance to be none-zero even before max_seq is increased? some pages > can be in the next generation before the generation is born? Yes. > isn't it a bug if(lrugen->nr_pages[next][type][zone] > 0)? shouldn't it be? > > delta = lrugen->nr_pages[prev][type][zone]; No. The gen counter in page flags can be updated locklessly (lru_lock). Later a batched update of nr_pages[] will account for the change made. If the gen counter is updated to a stale max_seq, and this stale max_seq is less than min_seq, then this page will be in a generation yet to be born. Extremely unlikely, but still possible. This is not a bug because pages might be misplaced but they won't be lost. IOW, nr_pages[] is always balanced across all *possible* generations. For the same reason, reset_batch_size() and drain_evictable() use for_each_gen_type_zone() to go through all possible generations rather than only those between[max_seq, min_seq]. I'll add a comment here. Sounds good?