From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from out30-110.freemail.mail.aliyun.com (out30-110.freemail.mail.aliyun.com [115.124.30.110]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 435AE37997E for ; Tue, 31 Mar 2026 08:43:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=115.124.30.110 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774946594; cv=none; b=V+CGMOMXhtYx4LvXoJJdqROYA//xXfR42Xufw2VLdwnVxWPRDajr5/G4Nr1n5EcpKqeRUHFE5//diDEP/jVzYganuONfsHWTBluOo+f5HZ5Scp70GHM7iwgClLNP+u19u7FmgFC/qbS/puIC4+hHqi9/8W/71/MhZgAt/lIrn9Y= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774946594; c=relaxed/simple; bh=vDxitRe5XWxZ2YdNIDO+kdqznOWoQIhdQSWg1kdsvp8=; h=Message-ID:Date:MIME-Version:Subject:To:Cc:References:From: In-Reply-To:Content-Type; b=sgGpuUORObwG3aObIcq7js8Ei6iQy0H9cRUJVbVhJIyjCH/Odqtbl4Y8yjWX+wnf575EuduGDeSi0TJfudPKIPH0qgZe6VTjDL0CY0XGDuPUitOQN7TZMARiNOCkiHv3pB8jbeKWt9fp+uQWNTfqg6QtnMQygUAWDYZ1MPHvsX4= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.alibaba.com; spf=pass smtp.mailfrom=linux.alibaba.com; dkim=pass (1024-bit key) header.d=linux.alibaba.com header.i=@linux.alibaba.com header.b=oqNevXT9; arc=none smtp.client-ip=115.124.30.110 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.alibaba.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.alibaba.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.alibaba.com header.i=@linux.alibaba.com header.b="oqNevXT9" DKIM-Signature:v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.alibaba.com; s=default; t=1774946583; h=Message-ID:Date:MIME-Version:Subject:To:From:Content-Type; bh=mI5mJe1g+g7JAmX+8ag1GACYSXlhR+QhbwoWJOhaL+k=; b=oqNevXT9jAnvUcEQ2l9KvaSqDUO99/GDqATaccGwvLRjCqrpOWNjccmdQYUwVLa/NIa9tJmmFP6dMsz5smP0RolmQS1WOuxo1bdKfjTUBviGLlKZqicvtI2zjzgkGoD1+ZnYce8pbvzgHEYksX6lyArYja5ObXftLW6ratvfidU= X-Alimail-AntiSpam:AC=PASS;BC=-1|-1;BR=01201311R991e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=maildocker-contentspam011083073210;MF=baolin.wang@linux.alibaba.com;NM=1;PH=DS;RN=25;SR=0;TI=SMTPD_---0X03s4ZU_1774946580; Received: from 30.74.144.129(mailfrom:baolin.wang@linux.alibaba.com fp:SMTPD_---0X03s4ZU_1774946580 cluster:ay36) by smtp.aliyun-inc.com; Tue, 31 Mar 2026 16:43:01 +0800 Message-ID: Date: Tue, 31 Mar 2026 16:42:59 +0800 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [PATCH v2 08/12] mm/mglru: simplify and improve dirty writeback handling To: kasong@tencent.com, linux-mm@kvack.org Cc: Andrew Morton , Axel Rasmussen , Yuanchu Xie , Wei Xu , Johannes Weiner , David Hildenbrand , Michal Hocko , Qi Zheng , Shakeel Butt , Lorenzo Stoakes , Barry Song , David Stevens , Chen Ridong , Leno Hou , Yafang Shao , Yu Zhao , Zicheng Wang , Kalesh Singh , Suren Baghdasaryan , Chris Li , Vernon Yang , linux-kernel@vger.kernel.org, Qi Zheng References: <20260329-mglru-reclaim-v2-0-b53a3678513c@tencent.com> <20260329-mglru-reclaim-v2-8-b53a3678513c@tencent.com> From: Baolin Wang In-Reply-To: <20260329-mglru-reclaim-v2-8-b53a3678513c@tencent.com> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit On 3/29/26 3:52 AM, Kairui Song via B4 Relay wrote: > From: Kairui Song > > The current handling of dirty writeback folios is not working well for > file page heavy workloads: Dirty folios are protected and move to next > gen upon isolation of getting throttled or reactivation upon pageout > (shrink_folio_list). > > This might help to reduce the LRU lock contention slightly, but as a > result, the ping-pong effect of folios between head and tail of last two > gens is serious as the shrinker will run into protected dirty writeback > folios more frequently compared to activation. The dirty flush wakeup > condition is also much more passive compared to active/inactive LRU. > Active / inactve LRU wakes the flusher if one batch of folios passed to > shrink_folio_list is unevictable due to under writeback, but MGLRU > instead has to check this after the whole reclaim loop is done, and then > count the isolation protection number compared to the total reclaim > number. > > And we previously saw OOM problems with it, too, which were fixed but > still not perfect [1]. > > So instead, just drop the special handling for dirty writeback, just > re-activate it like active / inactive LRU. And also move the dirty flush > wake up check right after shrink_folio_list. This should improve both > throttling and performance. > > Test with YCSB workloadb showed a major performance improvement: > > Before this series: > Throughput(ops/sec): 61642.78008938203 > AverageLatency(us): 507.11127774145166 > pgpgin 158190589 > pgpgout 5880616 > workingset_refault 7262988 > > After this commit: > Throughput(ops/sec): 80216.04855744806 (+30.1%, higher is better) > AverageLatency(us): 388.17633477268913 (-23.5%, lower is better) > pgpgin 101871227 (-35.6%, lower is better) > pgpgout 5770028 > workingset_refault 3418186 (-52.9%, lower is better) > > The refault rate is ~50% lower, and throughput is ~30% higher, which > is a huge gain. We also observed significant performance gain for > other real-world workloads. > > We were concerned that the dirty flush could cause more wear for SSD: > that should not be the problem here, since the wakeup condition is when > the dirty folios have been pushed to the tail of LRU, which indicates > that memory pressure is so high that writeback is blocking the workload > already. > > Reviewed-by: Axel Rasmussen > Link: https://lore.kernel.org/linux-mm/20241026115714.1437435-1-jingxiangzeng.cas@gmail.com/ [1] > Signed-off-by: Kairui Song > --- > mm/vmscan.c | 57 ++++++++++++++++----------------------------------------- > 1 file changed, 16 insertions(+), 41 deletions(-) > > diff --git a/mm/vmscan.c b/mm/vmscan.c > index 8de5c8d5849e..17b5318fad39 100644 > --- a/mm/vmscan.c > +++ b/mm/vmscan.c > @@ -4583,7 +4583,6 @@ static bool sort_folio(struct lruvec *lruvec, struct folio *folio, struct scan_c > int tier_idx) > { > bool success; > - bool dirty, writeback; > int gen = folio_lru_gen(folio); > int type = folio_is_file_lru(folio); > int zone = folio_zonenum(folio); > @@ -4633,21 +4632,6 @@ static bool sort_folio(struct lruvec *lruvec, struct folio *folio, struct scan_c > return true; > } > > - dirty = folio_test_dirty(folio); > - writeback = folio_test_writeback(folio); > - if (type == LRU_GEN_FILE && dirty) { > - sc->nr.file_taken += delta; > - if (!writeback) > - sc->nr.unqueued_dirty += delta; > - } > - > - /* waiting for writeback */ > - if (writeback || (type == LRU_GEN_FILE && dirty)) { > - gen = folio_inc_gen(lruvec, folio, true); > - list_move(&folio->lru, &lrugen->folios[gen][type][zone]); > - return true; > - } I'm a bit concerned about the handling of dirty folios. In the original logic, if we encounter a dirty folio, we increment its generation counter by 1 and move it to the *second oldest generation*. However, with your patch, shrink_folio_list() will activate the dirty folio by calling folio_set_active(). Then, evict_folios() -> move_folios_to_lru() will put the dirty folio back into the MGLRU list. But because the folio_test_active() is true for this dirty folio, the dirty folio will now be placed into the *second youngest generation* (see lru_gen_folio_seq()). As a result, during the next eviction, these dirty folios won't be scanned again (because they are in the second youngest generation). Wouldn't this lead to a situation where the flusher cannot be woken up in time, making OOM more likely?