From: Feng Tang <feng.tang@intel.com>
To: Michal Hocko <mhocko@suse.com>
Cc: Muchun Song <songmuchun@bytedance.com>,
"akpm@linux-foundation.org" <akpm@linux-foundation.org>,
"bwidawsk@kernel.org" <bwidawsk@kernel.org>,
"dave.hansen@linux.intel.com" <dave.hansen@linux.intel.com>,
"linux-mm@kvack.org" <linux-mm@kvack.org>,
"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
Mike Kravetz <mike.kravetz@oracle.com>
Subject: Re: [PATCH] mm: mempolicy: fix policy_nodemask() for MPOL_PREFERRED_MANY case
Date: Thu, 4 Aug 2022 01:14:32 +0800 [thread overview]
Message-ID: <Yuqs+BTpfh9/PjtP@feng-clx> (raw)
In-Reply-To: <YuolieBmdaIzoS3t@dhcp22.suse.cz>
On Wed, Aug 03, 2022 at 03:36:41PM +0800, Michal Hocko wrote:
> On Wed 03-08-22 14:41:20, Feng Tang wrote:
> > On Tue, Aug 02, 2022 at 05:02:37PM +0800, Michal Hocko wrote:
> > > Please make sure to CC Mike on hugetlb related changes.
> >
> > OK.
> >
> > > I didn't really get to grasp your proposed solution but it feels goind
> > > sideways. The real issue is that hugetlb uses a dedicated allocation
> > > scheme which is not fully MPOL_PREFERRED_MANY aware AFAICS. I do not
> > > think we should be tricking that by providing some fake nodemasks and
> > > what not.
> > >
> > > The good news is that allocation from the pool is MPOL_PREFERRED_MANY
> > > aware because it first tries to allocation from the preffered node mask
> > > and then fall back to the full nodemask (dequeue_huge_page_vma).
> > > If the existing pools cannot really satisfy that allocation then it
> > > tries to allocate a new hugetlb page (alloc_fresh_huge_page) which also
> > > performs 2 stage allocation with the node mask and no node masks. But
> > > both of them might fail.
> > >
> > > The bad news is that other allocation functions - including those that
> > > allocate to the pool are not fully MPOL_PREFERRED_MANY aware. E.g.
> > > __nr_hugepages_store_common paths which use the allocating process
> > > policy to fill up the pool so the pool could be under provisioned if
> > > that context is using MPOL_PREFERRED_MANY.
> >
> > Thanks for the check!
> >
> > So you mean if the prferred nodes don't have enough pages, we should
> > also fallback to all like dequeue_huge_page_vma() does?
> >
> > Or we can user a policy API which return nodemask for MPOL_BIND and
> > NULL for all other policies, like allowed_mems_nr() needs.
> >
> > --- a/include/linux/mempolicy.h
> > +++ b/include/linux/mempolicy.h
> > @@ -158,6 +158,18 @@ static inline nodemask_t *policy_nodemask_current(gfp_t gfp)
> > return policy_nodemask(gfp, mpol);
> > }
> >
> > +#ifdef CONFIG_HUGETLB_FS
> > +static inline nodemask_t *strict_policy_nodemask_current(void)
> > +{
> > + struct mempolicy *mpol = get_task_policy(current);
> > +
> > + if (mpol->mode == MPOL_BIND)
> > + return &mpol->nodes;
> > +
> > + return NULL;
> > +}
> > +#endif
>
> Yes something like this, except that I would also move this into hugetlb
> proper because this doesn't seem generally useful.
Ok, I change it as below:
---
mm/hugetlb.c | 28 +++++++++++++++++++++++-----
1 file changed, 23 insertions(+), 5 deletions(-)
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index 14be38822cf8..ef1d4ffa733f 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -91,6 +91,24 @@ struct mutex *hugetlb_fault_mutex_table ____cacheline_aligned_in_smp;
/* Forward declaration */
static int hugetlb_acct_memory(struct hstate *h, long delta);
+/*
+ * Return nodemask of what is allowed by current process' memory
+ * policy, as MPOL_BIND is the only 'strict' policy, return NULL
+ * for all other policies
+ */
+static inline nodemask_t *allowed_policy_nodemask_current(void)
+{
+#ifdef CONFIG_NUMA
+ struct mempolicy *mpol = get_task_policy(current);
+
+ if (mpol->mode == MPOL_BIND)
+ return &mpol->nodes;
+ return NULL;
+#else
+ return NULL;
+#endif
+}
+
static inline bool subpool_is_free(struct hugepage_subpool *spool)
{
if (spool->count)
@@ -3556,7 +3574,7 @@ static ssize_t __nr_hugepages_store_common(bool obey_mempolicy,
unsigned long count, size_t len)
{
int err;
- nodemask_t nodes_allowed, *n_mask;
+ nodemask_t nodes_allowed, *n_mask = NULL;
if (hstate_is_gigantic(h) && !gigantic_page_runtime_supported())
return -EINVAL;
@@ -3565,11 +3583,11 @@ static ssize_t __nr_hugepages_store_common(bool obey_mempolicy,
/*
* global hstate attribute
*/
- if (!(obey_mempolicy &&
- init_nodemask_of_mempolicy(&nodes_allowed)))
+ if (obey_mempolicy)
+ n_mask = allowed_policy_nodemask_current();
+
+ if (!n_mask)
n_mask = &node_states[N_MEMORY];
- else
- n_mask = &nodes_allowed;
} else {
/*
* Node specific request. count adjustment happens in
--
2.27.0
> > > Wrt. allowed_mems_nr (i.e. hugetlb_acct_memory) this is a reservation
> > > code and I have to admit I do not really remember details there. This is
> > > a subtle code and my best guess would be that policy_nodemask_current
> > > should be hugetlb specific and only care about MPOL_BIND.
> >
> > The API needed by allowed_mem_nr() is a little different as it has gfp
> > flag and cpuset config to consider.
>
> Why would gfp mask matter?
I'm not very familiar with the old semantics (will check more), from current
code, it checks both the gfp flags and cpuset limit.
Thanks,
Feng
> --
> Michal Hocko
> SUSE Labs
next prev parent reply other threads:[~2022-08-03 9:16 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-08-01 8:42 [PATCH] mm: mempolicy: fix policy_nodemask() for MPOL_PREFERRED_MANY case Muchun Song
2022-08-01 9:06 ` Michal Hocko
2022-08-01 9:26 ` Feng Tang
2022-08-02 3:42 ` Muchun Song
2022-08-02 5:52 ` Feng Tang
2022-08-02 6:40 ` Muchun Song
2022-08-02 7:39 ` Feng Tang
2022-08-02 9:02 ` Michal Hocko
2022-08-03 6:41 ` Feng Tang
2022-08-03 7:36 ` Michal Hocko
2022-08-03 17:14 ` Feng Tang [this message]
2022-08-03 11:28 ` Michal Hocko
2022-08-03 20:43 ` Feng Tang
2022-08-03 12:56 ` Michal Hocko
2022-08-03 21:08 ` Feng Tang
2022-08-03 13:21 ` Michal Hocko
2022-08-04 8:27 ` Feng Tang
2022-08-04 10:43 ` Michal Hocko
2022-08-04 13:03 ` [PATCH] mm/hugetlb: add dedicated func to get 'allowed' nodemask for current process Feng Tang
2022-08-04 13:36 ` Michal Hocko
2022-08-04 22:37 ` Andrew Morton
2022-08-05 0:06 ` Feng Tang
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=Yuqs+BTpfh9/PjtP@feng-clx \
--to=feng.tang@intel.com \
--cc=akpm@linux-foundation.org \
--cc=bwidawsk@kernel.org \
--cc=dave.hansen@linux.intel.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=mhocko@suse.com \
--cc=mike.kravetz@oracle.com \
--cc=songmuchun@bytedance.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.