From: David Hildenbrand <david@redhat.com>
To: "Maíra Canal" <mcanal@igalia.com>,
"Jonathan Corbet" <corbet@lwn.net>,
"Andrew Morton" <akpm@linux-foundation.org>,
"Hugh Dickins" <hughd@google.com>,
"Barry Song" <baohua@kernel.org>,
"Ryan Roberts" <ryan.roberts@arm.com>,
"Baolin Wang" <baolin.wang@linux.alibaba.com>,
"Lance Yang" <ioworker0@gmail.com>
Cc: linux-mm@kvack.org, linux-doc@vger.kernel.org,
linux-kernel@vger.kernel.org, kernel-dev@igalia.com
Subject: Re: [PATCH v3 3/4] mm: shmem: override mTHP shmem default with a kernel parameter
Date: Thu, 31 Oct 2024 13:37:13 +0100 [thread overview]
Message-ID: <2c507326-3267-431e-936a-23e2ab6a3baf@redhat.com> (raw)
In-Reply-To: <20241030130308.1066299-4-mcanal@igalia.com>
On 30.10.24 13:58, Maíra Canal wrote:
> Add the ``thp_shmem=`` kernel command line to allow specifying the
> default policy of each supported shmem hugepage size. The kernel parameter
> accepts the following format:
>
> thp_shmem=<size>[KMG],<size>[KMG]:<policy>;<size>[KMG]-<size>[KMG]:<policy>
>
> For example,
>
> thp_shmem=16K-64K:always;128K,512K:inherit;256K:advise;1M-2M:never;4M-8M:within_size
>
> By configuring the default policy of several shmem hugepages, the user
> can take advantage of mTHP before it's been configured through sysfs.
>
> Signed-off-by: Maíra Canal <mcanal@igalia.com>
> ---
> .../admin-guide/kernel-parameters.txt | 10 ++
> Documentation/admin-guide/mm/transhuge.rst | 17 +++
> mm/shmem.c | 109 +++++++++++++++++-
> 3 files changed, 135 insertions(+), 1 deletion(-)
>
> diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
> index acabb04d0dd4..b48d744d99b0 100644
> --- a/Documentation/admin-guide/kernel-parameters.txt
> +++ b/Documentation/admin-guide/kernel-parameters.txt
> @@ -6700,6 +6700,16 @@
> Force threading of all interrupt handlers except those
> marked explicitly IRQF_NO_THREAD.
>
> + thp_shmem= [KNL]
> + Format: <size>[KMG],<size>[KMG]:<policy>;<size>[KMG]-<size>[KMG]:<policy>
> + Control the default policy of each hugepage size for the
> + internal shmem mount. <policy> is one of policies available
> + for the shmem mount ("always", "inherit", "never", "within_size",
> + and "advise").
> + It can be used multiple times for multiple shmem THP sizes.
> + See Documentation/admin-guide/mm/transhuge.rst for more
> + details.
> +
> topology= [S390,EARLY]
> Format: {off | on}
> Specify if the kernel should make use of the cpu
> diff --git a/Documentation/admin-guide/mm/transhuge.rst b/Documentation/admin-guide/mm/transhuge.rst
> index 9b5b02c4d1ab..47e7fc30e22d 100644
> --- a/Documentation/admin-guide/mm/transhuge.rst
> +++ b/Documentation/admin-guide/mm/transhuge.rst
> @@ -332,6 +332,23 @@ allocation policy for the internal shmem mount by using the kernel parameter
> seven valid policies for shmem (``always``, ``within_size``, ``advise``,
> ``never``, ``deny``, and ``force``).
>
> +In the same manner as ``thp_anon`` controls each supported anonymous THP
> +size, ``thp_shmem`` controls each supported shmem THP size. ``thp_shmem``
> +has the same format as ``thp_anon``, but also supports the policy
> +``within_size``.
> +
> +``thp_shmem=`` may be specified multiple times to configure all THP sizes
> +as required. If ``thp_shmem=`` is specified at least once, any shmem THP
> +sizes not explicitly configured on the command line are implicitly set to
> +``never``.
> +
> +``transparent_hugepage_shmem`` setting only affects the global toggle. If
> +``thp_shmem`` is not specified, PMD_ORDER hugepage will default to
> +``inherit``. However, if a valid ``thp_shmem`` setting is provided by the
> +user, the PMD_ORDER hugepage policy will be overridden. If the policy for
> +PMD_ORDER is not defined within a valid ``thp_shmem``, its policy will
> +default to ``never``.
> +
> Hugepages in tmpfs/shmem
> ========================
>
> diff --git a/mm/shmem.c b/mm/shmem.c
> index dfcc88ec6e34..c2299fa0b345 100644
> --- a/mm/shmem.c
> +++ b/mm/shmem.c
> @@ -136,6 +136,7 @@ static unsigned long huge_shmem_orders_always __read_mostly;
> static unsigned long huge_shmem_orders_madvise __read_mostly;
> static unsigned long huge_shmem_orders_inherit __read_mostly;
> static unsigned long huge_shmem_orders_within_size __read_mostly;
> +static bool shmem_orders_configured __initdata;
> #endif
>
> #ifdef CONFIG_TMPFS
> @@ -5027,7 +5028,8 @@ void __init shmem_init(void)
> * Default to setting PMD-sized THP to inherit the global setting and
> * disable all other multi-size THPs.
> */
> - huge_shmem_orders_inherit = BIT(HPAGE_PMD_ORDER);
> + if (!shmem_orders_configured)
> + huge_shmem_orders_inherit = BIT(HPAGE_PMD_ORDER);
> #endif
> return;
>
> @@ -5180,6 +5182,26 @@ struct kobj_attribute thpsize_shmem_enabled_attr =
>
> #if defined(CONFIG_TRANSPARENT_HUGEPAGE)
>
> +static inline int get_order_from_str(const char *size_str)
> +{
> + unsigned long size;
> + char *endptr;
> + int order;
> +
> + size = memparse(size_str, &endptr);
> +
> + if (!is_power_of_2(size))
> + goto err;
> + order = get_order(size);
> + if (BIT(order) & ~THP_ORDERS_ALL_FILE_DEFAULT)
> + goto err;
> +
> + return order;
> +err:
> + pr_err("invalid size %s in thp_shmem boot parameter\n", size_str);
> + return -EINVAL;
> +}
Hm, mostly copy and paste. You could reuse existing get_order_from_str()
simply by passing in the supported orders and moving error reporting to
the caller.
static inline int get_order_from_str(const char *size_str,
int valid_orders)
{
...
if (!is_power_of_2(size))
return -EINVAL;
order = get_order(size);
if (BIT(order) & ~valid_orders)
return -EINVAL;
return order;
}
> +
> static int __init setup_transparent_hugepage_shmem(char *str)
> {
> int huge;
> @@ -5195,6 +5217,91 @@ static int __init setup_transparent_hugepage_shmem(char *str)
> }
> __setup("transparent_hugepage_shmem=", setup_transparent_hugepage_shmem);
>
> +static char str_dup[PAGE_SIZE] __initdata;
> +static int __init setup_thp_shmem(char *str)
> +{
> + char *token, *range, *policy, *subtoken;
> + unsigned long always, inherit, madvise, within_size;
> + char *start_size, *end_size;
> + int start, end, nr;
> + char *p;
> +
> + if (!str || strlen(str) + 1 > PAGE_SIZE)
> + goto err;
> + strscpy(str_dup, str);
> +
> + always = huge_shmem_orders_always;
> + inherit = huge_shmem_orders_inherit;
> + madvise = huge_shmem_orders_madvise;
> + within_size = huge_shmem_orders_within_size;
> + p = str_dup;
> + while ((token = strsep(&p, ";")) != NULL) {
> + range = strsep(&token, ":");
> + policy = token;
> +
> + if (!policy)
> + goto err;
> +
> + while ((subtoken = strsep(&range, ",")) != NULL) {
> + if (strchr(subtoken, '-')) {
> + start_size = strsep(&subtoken, "-");
> + end_size = subtoken;
> +
> + start = get_order_from_str(start_size);
> + end = get_order_from_str(end_size);
> + } else {
> + start = end = get_order_from_str(subtoken);
> + }
> +
> + if (start < 0 || end < 0 || start > end)
> + goto err;
> +
> + nr = end - start + 1;
> + if (!strcmp(policy, "always")) {
> + bitmap_set(&always, start, nr);
> + bitmap_clear(&inherit, start, nr);
> + bitmap_clear(&madvise, start, nr);
> + bitmap_clear(&within_size, start, nr);
> + } else if (!strcmp(policy, "advise")) {
> + bitmap_set(&madvise, start, nr);
> + bitmap_clear(&inherit, start, nr);
> + bitmap_clear(&always, start, nr);
> + bitmap_clear(&within_size, start, nr);
> + } else if (!strcmp(policy, "inherit")) {
> + bitmap_set(&inherit, start, nr);
> + bitmap_clear(&madvise, start, nr);
> + bitmap_clear(&always, start, nr);
> + bitmap_clear(&within_size, start, nr);
> + } else if (!strcmp(policy, "within_size")) {
> + bitmap_set(&within_size, start, nr);
> + bitmap_clear(&inherit, start, nr);
> + bitmap_clear(&madvise, start, nr);
> + bitmap_clear(&always, start, nr);
> + } else if (!strcmp(policy, "never")) {
> + bitmap_clear(&inherit, start, nr);
> + bitmap_clear(&madvise, start, nr);
> + bitmap_clear(&always, start, nr);
> + bitmap_clear(&within_size, start, nr);
> + } else {
> + pr_err("invalid policy %s in thp_shmem boot parameter\n", policy);
> + goto err;
> + }
> + }
> + }
Similarly, copy-paste. But not that easy to abstract :) So maybe we'll
have to keep that as is for now.
--
Cheers,
David / dhildenb
next prev parent reply other threads:[~2024-10-31 12:37 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-10-30 12:58 [PATCH v3 0/4] mm: add more kernel parameters to control mTHP Maíra Canal
2024-10-30 12:58 ` [PATCH v3 1/4] mm: fix docs for the kernel parameter ``thp_anon=`` Maíra Canal
2024-10-30 12:58 ` [PATCH v3 2/4] mm: shmem: control THP support through the kernel command line Maíra Canal
2024-10-31 3:53 ` Baolin Wang
2024-10-31 12:32 ` David Hildenbrand
2024-10-30 12:58 ` [PATCH v3 3/4] mm: shmem: override mTHP shmem default with a kernel parameter Maíra Canal
2024-10-31 12:37 ` David Hildenbrand [this message]
2024-10-31 12:51 ` Maíra Canal
2024-10-31 12:57 ` David Hildenbrand
2024-10-31 13:24 ` Maíra Canal
2024-10-31 13:33 ` David Hildenbrand
2024-10-31 14:19 ` Maíra Canal
2024-10-31 21:12 ` Barry Song
2024-10-31 21:12 ` Barry Song
2024-10-31 21:39 ` David Hildenbrand
2024-10-31 22:16 ` Barry Song
2024-10-30 12:58 ` [PATCH v3 4/4] mm: huge_memory: Use strscpy() instead of strcpy() Maíra Canal
2024-10-30 23:07 ` Barry Song
2024-10-31 10:55 ` Maíra Canal
2024-10-31 12:01 ` Barry Song
2024-10-31 12:11 ` Maíra Canal
2024-10-31 20:27 ` Barry Song
2024-10-31 20:31 ` Barry Song
2024-10-31 1:39 ` Lance Yang
2024-10-30 22:50 ` [PATCH v3 0/4] mm: add more kernel parameters to control mTHP Andrew Morton
2024-10-31 11:04 ` Maíra Canal
2024-11-01 1:12 ` Andrew Morton
2024-11-01 16:34 ` Maíra Canal
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=2c507326-3267-431e-936a-23e2ab6a3baf@redhat.com \
--to=david@redhat.com \
--cc=akpm@linux-foundation.org \
--cc=baohua@kernel.org \
--cc=baolin.wang@linux.alibaba.com \
--cc=corbet@lwn.net \
--cc=hughd@google.com \
--cc=ioworker0@gmail.com \
--cc=kernel-dev@igalia.com \
--cc=linux-doc@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=mcanal@igalia.com \
--cc=ryan.roberts@arm.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.