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 BBA93C67871 for ; Thu, 27 Oct 2022 05:14:39 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id B48A58E0002; Thu, 27 Oct 2022 01:14:38 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id AD22B8E0001; Thu, 27 Oct 2022 01:14:38 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 972F28E0002; Thu, 27 Oct 2022 01:14:38 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0011.hostedemail.com [216.40.44.11]) by kanga.kvack.org (Postfix) with ESMTP id 8768A8E0001 for ; Thu, 27 Oct 2022 01:14:38 -0400 (EDT) Received: from smtpin25.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay02.hostedemail.com (Postfix) with ESMTP id 53D92120343 for ; Thu, 27 Oct 2022 05:14:38 +0000 (UTC) X-FDA: 80065564236.25.CDF3CD8 Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by imf29.hostedemail.com (Postfix) with ESMTP id 58FAE120019 for ; Thu, 27 Oct 2022 05:14:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1666847677; x=1698383677; h=from:to:cc:subject:references:date:in-reply-to: message-id:mime-version; bh=9d3aFGAFLQAxiFqVF47lE8CevVy7cGqVqRyit2lkJRE=; b=ZYnNbkpIYxIFLpUzb8L3S63lkb5LySmXKUVldpqaaeJh9B5dfqHL/eE7 KOJCQL6mdT+6CZE0Y9jBc3hKdkFAnTXOnGvNMCH6Q4l2R8hAqmhmsumaj oGJyVt6SJb4FH2M0FTYOKOrK8ohMjxD16SJB/s2Og4BNrEzU/azLEhj1u jINeDuWZ9NhoX+SG19OqW5lxokVpI2ceu0BkB76TtnqYKj23qpyuWlmcm wF+Zizu44npVNplvN4AyoZ6dJLSJEJXt35iZqhPjSuzcX9aTtncnhhWrQ XWlH3tv2BXAoUQ3oMX6Yuwgm1On3bOXnZDH3qD7QZvyTSz9tHBo+Fa+G+ g==; X-IronPort-AV: E=McAfee;i="6500,9779,10512"; a="306861375" X-IronPort-AV: E=Sophos;i="5.95,215,1661842800"; d="scan'208";a="306861375" Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 26 Oct 2022 22:14:18 -0700 X-IronPort-AV: E=McAfee;i="6500,9779,10512"; a="774858075" X-IronPort-AV: E=Sophos;i="5.95,215,1661842800"; d="scan'208";a="774858075" Received: from yhuang6-desk2.sh.intel.com (HELO yhuang6-desk2.ccr.corp.intel.com) ([10.238.208.55]) by fmsmga001-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 26 Oct 2022 22:14:15 -0700 From: "Huang, Ying" To: Feng Tang Cc: Andrew Morton , Johannes Weiner , Michal Hocko , Tejun Heo , Zefan Li , Waiman Long , , , , , , , Subject: Re: [PATCH] mm/vmscan: respect cpuset policy during page demotion References: <20221026074343.6517-1-feng.tang@intel.com> Date: Thu, 27 Oct 2022 13:13:30 +0800 In-Reply-To: <20221026074343.6517-1-feng.tang@intel.com> (Feng Tang's message of "Wed, 26 Oct 2022 15:43:43 +0800") Message-ID: <878rl1luh1.fsf@yhuang6-desk2.ccr.corp.intel.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.1 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=ascii ARC-Authentication-Results: i=1; imf29.hostedemail.com; dkim=none ("invalid DKIM record") header.d=intel.com header.s=Intel header.b=ZYnNbkpI; spf=pass (imf29.hostedemail.com: domain of ying.huang@intel.com designates 192.55.52.120 as permitted sender) smtp.mailfrom=ying.huang@intel.com; dmarc=pass (policy=none) header.from=intel.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1666847678; a=rsa-sha256; cv=none; b=CTCP59Se43I291CHK3kvw+DiehouDtCNIDAcDObfjTrFwCLqJ7AnEnT196O8pMs3QCdtVB vUrVL9lRWrZfhs9+L4AZSXTSLghNH2pf/JH3OmRA0C583yojrgEBj4X30lrwvZmeYYSuVo jocH3ra7IaYJKPgxK5D7kIxtNyOlYEc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1666847678; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=nJRL2cmgHmmv+sljsCgIovMUFaYPDpecHNI9sWGV83o=; b=yd1pyRxbwOyKsVdc3M8Wqkm7z2OZvQntabNjfc9D3Ut1EP28d43WGdv+2Qa+JDpvcKOBHf 4mlzUvC1CVFG1QzQGJquVbsKSDTa7H2KCQ2pSqBgNPHXvTASvN7kZyTdlBFW3IrbeHpym1 +TGGxI/5BwOi+frq5zoe2ldz/4U8XOw= X-Rspamd-Queue-Id: 58FAE120019 Authentication-Results: imf29.hostedemail.com; dkim=none ("invalid DKIM record") header.d=intel.com header.s=Intel header.b=ZYnNbkpI; spf=pass (imf29.hostedemail.com: domain of ying.huang@intel.com designates 192.55.52.120 as permitted sender) smtp.mailfrom=ying.huang@intel.com; dmarc=pass (policy=none) header.from=intel.com X-Rspamd-Server: rspam02 X-Rspam-User: X-Stat-Signature: hgmunnteftu7y1yjifckd8tgipo6fm11 X-HE-Tag: 1666847677-806536 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: Feng Tang writes: > In page reclaim path, memory could be demoted from faster memory tier > to slower memory tier. Currently, there is no check about cpuset's > memory policy, that even if the target demotion node is not allowd > by cpuset, the demotion will still happen, which breaks the cpuset > semantics. > > So add cpuset policy check in the demotion path and skip demotion > if the demotion targets are not allowed by cpuset. > > Signed-off-by: Feng Tang > --- > Hi reviewers, > > For easy bisectable, I combined the cpuset change and mm change > in one patch, if you prefer to separate them, I can turn it into > 2 patches. > > Thanks, > Feng > > include/linux/cpuset.h | 6 ++++++ > kernel/cgroup/cpuset.c | 29 +++++++++++++++++++++++++++++ > mm/vmscan.c | 35 ++++++++++++++++++++++++++++++++--- > 3 files changed, 67 insertions(+), 3 deletions(-) > > diff --git a/include/linux/cpuset.h b/include/linux/cpuset.h > index d58e0476ee8e..6fcce2bd2631 100644 > --- a/include/linux/cpuset.h > +++ b/include/linux/cpuset.h > @@ -178,6 +178,8 @@ static inline void set_mems_allowed(nodemask_t nodemask) > task_unlock(current); > } > > +extern void cpuset_get_allowed_mem_nodes(struct cgroup *cgroup, > + nodemask_t *nmask); > #else /* !CONFIG_CPUSETS */ > > static inline bool cpusets_enabled(void) { return false; } > @@ -299,6 +301,10 @@ static inline bool read_mems_allowed_retry(unsigned int seq) > return false; > } > > +static inline void cpuset_get_allowed_mem_nodes(struct cgroup *cgroup, > + nodemask_t *nmask) > +{ > +} > #endif /* !CONFIG_CPUSETS */ > > #endif /* _LINUX_CPUSET_H */ > diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c > index 3ea2e836e93e..cbb118c0502f 100644 > --- a/kernel/cgroup/cpuset.c > +++ b/kernel/cgroup/cpuset.c > @@ -3750,6 +3750,35 @@ nodemask_t cpuset_mems_allowed(struct task_struct *tsk) > return mask; > } > > +/* > + * Retrieve the allowed memory nodemask for a cgroup. > + * > + * Set *nmask to cpuset's effective allowed nodemask for cgroup v2, > + * and NODE_MASK_ALL (means no constraint) for cgroup v1 where there > + * is no guaranteed association from a cgroup to a cpuset. > + */ > +void cpuset_get_allowed_mem_nodes(struct cgroup *cgroup, nodemask_t *nmask) > +{ > + struct cgroup_subsys_state *css; > + struct cpuset *cs; > + > + if (!is_in_v2_mode()) { > + *nmask = NODE_MASK_ALL; > + return; > + } > + > + rcu_read_lock(); > + css = cgroup_e_css(cgroup, &cpuset_cgrp_subsys); > + if (css) { > + css_get(css); > + cs = css_cs(css); > + *nmask = cs->effective_mems; > + css_put(css); > + } > + > + rcu_read_unlock(); > +} > + > /** > * cpuset_nodemask_valid_mems_allowed - check nodemask vs. current mems_allowed > * @nodemask: the nodemask to be checked > diff --git a/mm/vmscan.c b/mm/vmscan.c > index 18f6497994ec..c205d98283bc 100644 > --- a/mm/vmscan.c > +++ b/mm/vmscan.c > @@ -1537,9 +1537,21 @@ static struct page *alloc_demote_page(struct page *page, unsigned long private) > { > struct page *target_page; > nodemask_t *allowed_mask; > - struct migration_target_control *mtc; > + struct migration_target_control *mtc = (void *)private; > > - mtc = (struct migration_target_control *)private; I think we should avoid (void *) conversion here. > +#if IS_ENABLED(CONFIG_MEMCG) && IS_ENABLED(CONFIG_CPUSETS) > + struct mem_cgroup *memcg; > + nodemask_t cpuset_nmask; > + > + memcg = page_memcg(page); > + cpuset_get_allowed_mem_nodes(memcg->css.cgroup, &cpuset_nmask); > + > + if (!node_isset(mtc->nid, cpuset_nmask)) { > + if (mtc->nmask) > + nodes_and(*mtc->nmask, *mtc->nmask, cpuset_nmask); > + return alloc_migration_target(page, (unsigned long)mtc); > + } If node_isset(mtc->nid, cpuset_nmask) == true, we should keep the original 2 steps allocation and apply nodes_and() on node mask. > +#endif > > allowed_mask = mtc->nmask; > /* > @@ -1649,6 +1661,7 @@ static unsigned int shrink_folio_list(struct list_head *folio_list, > enum folio_references references = FOLIOREF_RECLAIM; > bool dirty, writeback; > unsigned int nr_pages; > + bool skip_this_demotion = false; > > cond_resched(); > > @@ -1658,6 +1671,22 @@ static unsigned int shrink_folio_list(struct list_head *folio_list, > if (!folio_trylock(folio)) > goto keep; > > +#if IS_ENABLED(CONFIG_MEMCG) && IS_ENABLED(CONFIG_CPUSETS) > + if (do_demote_pass) { > + struct mem_cgroup *memcg; > + nodemask_t nmask, nmask1; > + > + node_get_allowed_targets(pgdat, &nmask); pgdat will not change in the loop, so we can move this out of the loop? > + memcg = folio_memcg(folio); > + if (memcg) > + cpuset_get_allowed_mem_nodes(memcg->css.cgroup, > + &nmask1); > + > + if (!nodes_intersects(nmask, nmask1)) > + skip_this_demotion = true; > + } If nodes_intersects() == true, we will call cpuset_get_allowed_mem_nodes() twice. Better to pass the intersecting mask to demote_folio_list()? > +#endif > + > VM_BUG_ON_FOLIO(folio_test_active(folio), folio); > > nr_pages = folio_nr_pages(folio); > @@ -1799,7 +1828,7 @@ static unsigned int shrink_folio_list(struct list_head *folio_list, > * Before reclaiming the folio, try to relocate > * its contents to another node. > */ > - if (do_demote_pass && > + if (do_demote_pass && !skip_this_demotion && > (thp_migration_supported() || !folio_test_large(folio))) { > list_add(&folio->lru, &demote_folios); > folio_unlock(folio); Best Regards, Huang, Ying