From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id C07E3C433F5 for ; Sat, 2 Apr 2022 07:21:38 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id F08D98D0001; Sat, 2 Apr 2022 03:21:27 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id EB8DF6B0072; Sat, 2 Apr 2022 03:21:27 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id DA8158D0001; Sat, 2 Apr 2022 03:21:27 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0244.hostedemail.com [216.40.44.244]) by kanga.kvack.org (Postfix) with ESMTP id C7FF46B0071 for ; Sat, 2 Apr 2022 03:21:27 -0400 (EDT) Received: from smtpin18.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay05.hostedemail.com (Postfix) with ESMTP id 7A7411831C2B6 for ; Sat, 2 Apr 2022 07:21:17 +0000 (UTC) X-FDA: 79311092994.18.67211C9 Received: from mail3-163.sinamail.sina.com.cn (mail3-163.sinamail.sina.com.cn [202.108.3.163]) by imf10.hostedemail.com (Postfix) with SMTP id 9DF87C001C for ; Sat, 2 Apr 2022 07:21:15 +0000 (UTC) Received: from unknown (HELO localhost.localdomain)([114.249.57.134]) by sina.com (172.16.97.27) with ESMTP id 6247F9660001CA72; Sat, 2 Apr 2022 15:21:12 +0800 (CST) X-Sender: hdanton@sina.com X-Auth-ID: hdanton@sina.com X-SMAIL-MID: 85567449283376 From: Hillf Danton To: MM Cc: Matthew Wilcox , Dave Chinner , Mel Gorman , Stephen Brennan , Yu Zhao , David Hildenbrand , LKML Subject: [RFC] mm/vmscan: add periodic slab shrinker Date: Sat, 2 Apr 2022 15:21:03 +0800 Message-Id: <20220402072103.5140-1-hdanton@sina.com> MIME-Version: 1.0 X-Stat-Signature: uw7rzfawnhce4do7cxheau1ieqhkw9bt Authentication-Results: imf10.hostedemail.com; dkim=none; spf=pass (imf10.hostedemail.com: domain of hdanton@sina.com designates 202.108.3.163 as permitted sender) smtp.mailfrom=hdanton@sina.com; dmarc=none X-Rspam-User: X-Rspamd-Server: rspam08 X-Rspamd-Queue-Id: 9DF87C001C X-HE-Tag: 1648884075-976798 Content-Transfer-Encoding: quoted-printable X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: To mitigate the pain of having "several millions" of negative dentries in a single directory [1] for example, add the periodic slab shrinker that runs independent of direct and background reclaimers in bid to recycle th= e slab objects that haven been cold for more than 30 seconds. Q, Why is it needed? A, Kswapd may take a nap as long as 30 minutes. Add periodic flag to shrink control to let cache owners know this is the periodic shrinker that equals to the regular one running at the lowest recalim priority, and feel free to take no action without one-off objects piling up. Only for thoughts now. Hillf [1] https://lore.kernel.org/linux-fsdevel/20220209231406.187668-1-stephen= .s.brennan@oracle.com/ --- x/include/linux/shrinker.h +++ y/include/linux/shrinker.h @@ -14,6 +14,7 @@ struct shrink_control { =20 /* current node being shrunk (for NUMA aware shrinkers) */ int nid; + int periodic; =20 /* * How many objects scan_objects should scan and try to reclaim. --- x/mm/vmscan.c +++ y/mm/vmscan.c @@ -781,6 +781,8 @@ static unsigned long do_shrink_slab(stru scanned +=3D shrinkctl->nr_scanned; =20 cond_resched(); + if (shrinkctl->periodic) + break; } =20 /* @@ -906,7 +908,8 @@ static unsigned long shrink_slab_memcg(g */ static unsigned long shrink_slab(gfp_t gfp_mask, int nid, struct mem_cgroup *memcg, - int priority) + int priority, + int periodic) { unsigned long ret, freed =3D 0; struct shrinker *shrinker; @@ -929,6 +932,7 @@ static unsigned long shrink_slab(gfp_t g .gfp_mask =3D gfp_mask, .nid =3D nid, .memcg =3D memcg, + .periodic =3D periodic, }; =20 ret =3D do_shrink_slab(&sc, shrinker, priority); @@ -952,7 +956,7 @@ out: return freed; } =20 -static void drop_slab_node(int nid) +static void drop_slab_node(int nid, int periodic) { unsigned long freed; int shift =3D 0; @@ -966,19 +970,31 @@ static void drop_slab_node(int nid) freed =3D 0; memcg =3D mem_cgroup_iter(NULL, NULL, NULL); do { - freed +=3D shrink_slab(GFP_KERNEL, nid, memcg, 0); + freed +=3D shrink_slab(GFP_KERNEL, nid, memcg, 0, periodic); } while ((memcg =3D mem_cgroup_iter(NULL, memcg, NULL)) !=3D NULL); } while ((freed >> shift++) > 1); } =20 -void drop_slab(void) +static void __drop_slab(int periodic) { int nid; =20 for_each_online_node(nid) - drop_slab_node(nid); + drop_slab_node(nid, periodic); +} + +void drop_slab(void) +{ + __drop_slab(0); } =20 +static void periodic_slab_shrinker_workfn(struct work_struct *work) +{ + __drop_slab(1); + queue_delayed_work(system_unbound_wq, to_delayed_work(work), 30*HZ); +} +static DECLARE_DELAYED_WORK(periodic_slab_shrinker, periodic_slab_shrink= er_workfn); + static inline int is_page_cache_freeable(struct folio *folio) { /* @@ -3098,7 +3114,7 @@ static void shrink_node_memcgs(pg_data_t shrink_lruvec(lruvec, sc); =20 shrink_slab(sc->gfp_mask, pgdat->node_id, memcg, - sc->priority); + sc->priority, 0); =20 /* Record the group's reclaim efficiency */ vmpressure(sc->gfp_mask, memcg, false, @@ -4354,8 +4370,11 @@ static void kswapd_try_to_sleep(pg_data_ */ set_pgdat_percpu_threshold(pgdat, calculate_normal_threshold); =20 - if (!kthread_should_stop()) + if (!kthread_should_stop()) { + queue_delayed_work(system_unbound_wq, + &periodic_slab_shrinker, 60*HZ); schedule(); + } =20 set_pgdat_percpu_threshold(pgdat, calculate_pressure_threshold); } else { --