Skip to content

Commit 24f9cd1

Browse files
mairacanalakpm00
authored andcommitted
mm: shmem: override mTHP shmem default with a kernel parameter
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 Some GPUs may benefit from using huge pages. Since DRM GEM uses shmem to allocate anonymous pageable memory, it's essential to control the huge page allocation policy for the internal shmem mount. This control can be achieved through the ``transparent_hugepage_shmem=`` parameter. Beyond just setting the allocation policy, it's crucial to have granular control over the size of huge pages that can be allocated. The GPU may support only specific huge page sizes, and allocating pages larger/smaller than those sizes would be ineffective. Link: https://lkml.kernel.org/r/[email protected] Signed-off-by: Maíra Canal <[email protected]> Reviewed-by: Baolin Wang <[email protected]> Cc: Barry Song <[email protected]> Cc: David Hildenbrand <[email protected]> Cc: Hugh Dickins <[email protected]> Cc: Jonathan Corbet <[email protected]> Cc: Lance Yang <[email protected]> Cc: Ryan Roberts <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
1 parent 1c8d484 commit 24f9cd1

File tree

3 files changed

+131
-1
lines changed

3 files changed

+131
-1
lines changed

Documentation/admin-guide/kernel-parameters.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6700,6 +6700,16 @@
67006700
Force threading of all interrupt handlers except those
67016701
marked explicitly IRQF_NO_THREAD.
67026702

6703+
thp_shmem= [KNL]
6704+
Format: <size>[KMG],<size>[KMG]:<policy>;<size>[KMG]-<size>[KMG]:<policy>
6705+
Control the default policy of each hugepage size for the
6706+
internal shmem mount. <policy> is one of policies available
6707+
for the shmem mount ("always", "inherit", "never", "within_size",
6708+
and "advise").
6709+
It can be used multiple times for multiple shmem THP sizes.
6710+
See Documentation/admin-guide/mm/transhuge.rst for more
6711+
details.
6712+
67036713
topology= [S390,EARLY]
67046714
Format: {off | on}
67056715
Specify if the kernel should make use of the cpu

Documentation/admin-guide/mm/transhuge.rst

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,23 @@ allocation policy for the internal shmem mount by using the kernel parameter
332332
seven valid policies for shmem (``always``, ``within_size``, ``advise``,
333333
``never``, ``deny``, and ``force``).
334334

335+
In the same manner as ``thp_anon`` controls each supported anonymous THP
336+
size, ``thp_shmem`` controls each supported shmem THP size. ``thp_shmem``
337+
has the same format as ``thp_anon``, but also supports the policy
338+
``within_size``.
339+
340+
``thp_shmem=`` may be specified multiple times to configure all THP sizes
341+
as required. If ``thp_shmem=`` is specified at least once, any shmem THP
342+
sizes not explicitly configured on the command line are implicitly set to
343+
``never``.
344+
345+
``transparent_hugepage_shmem`` setting only affects the global toggle. If
346+
``thp_shmem`` is not specified, PMD_ORDER hugepage will default to
347+
``inherit``. However, if a valid ``thp_shmem`` setting is provided by the
348+
user, the PMD_ORDER hugepage policy will be overridden. If the policy for
349+
PMD_ORDER is not defined within a valid ``thp_shmem``, its policy will
350+
default to ``never``.
351+
335352
Hugepages in tmpfs/shmem
336353
========================
337354

mm/shmem.c

Lines changed: 104 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ static unsigned long huge_shmem_orders_always __read_mostly;
136136
static unsigned long huge_shmem_orders_madvise __read_mostly;
137137
static unsigned long huge_shmem_orders_inherit __read_mostly;
138138
static unsigned long huge_shmem_orders_within_size __read_mostly;
139+
static bool shmem_orders_configured __initdata;
139140
#endif
140141

141142
#ifdef CONFIG_TMPFS
@@ -5026,7 +5027,8 @@ void __init shmem_init(void)
50265027
* Default to setting PMD-sized THP to inherit the global setting and
50275028
* disable all other multi-size THPs.
50285029
*/
5029-
huge_shmem_orders_inherit = BIT(HPAGE_PMD_ORDER);
5030+
if (!shmem_orders_configured)
5031+
huge_shmem_orders_inherit = BIT(HPAGE_PMD_ORDER);
50305032
#endif
50315033
return;
50325034

@@ -5194,6 +5196,107 @@ static int __init setup_transparent_hugepage_shmem(char *str)
51945196
}
51955197
__setup("transparent_hugepage_shmem=", setup_transparent_hugepage_shmem);
51965198

5199+
static char str_dup[PAGE_SIZE] __initdata;
5200+
static int __init setup_thp_shmem(char *str)
5201+
{
5202+
char *token, *range, *policy, *subtoken;
5203+
unsigned long always, inherit, madvise, within_size;
5204+
char *start_size, *end_size;
5205+
int start, end, nr;
5206+
char *p;
5207+
5208+
if (!str || strlen(str) + 1 > PAGE_SIZE)
5209+
goto err;
5210+
strscpy(str_dup, str);
5211+
5212+
always = huge_shmem_orders_always;
5213+
inherit = huge_shmem_orders_inherit;
5214+
madvise = huge_shmem_orders_madvise;
5215+
within_size = huge_shmem_orders_within_size;
5216+
p = str_dup;
5217+
while ((token = strsep(&p, ";")) != NULL) {
5218+
range = strsep(&token, ":");
5219+
policy = token;
5220+
5221+
if (!policy)
5222+
goto err;
5223+
5224+
while ((subtoken = strsep(&range, ",")) != NULL) {
5225+
if (strchr(subtoken, '-')) {
5226+
start_size = strsep(&subtoken, "-");
5227+
end_size = subtoken;
5228+
5229+
start = get_order_from_str(start_size,
5230+
THP_ORDERS_ALL_FILE_DEFAULT);
5231+
end = get_order_from_str(end_size,
5232+
THP_ORDERS_ALL_FILE_DEFAULT);
5233+
} else {
5234+
start_size = end_size = subtoken;
5235+
start = end = get_order_from_str(subtoken,
5236+
THP_ORDERS_ALL_FILE_DEFAULT);
5237+
}
5238+
5239+
if (start == -EINVAL) {
5240+
pr_err("invalid size %s in thp_shmem boot parameter\n",
5241+
start_size);
5242+
goto err;
5243+
}
5244+
5245+
if (end == -EINVAL) {
5246+
pr_err("invalid size %s in thp_shmem boot parameter\n",
5247+
end_size);
5248+
goto err;
5249+
}
5250+
5251+
if (start < 0 || end < 0 || start > end)
5252+
goto err;
5253+
5254+
nr = end - start + 1;
5255+
if (!strcmp(policy, "always")) {
5256+
bitmap_set(&always, start, nr);
5257+
bitmap_clear(&inherit, start, nr);
5258+
bitmap_clear(&madvise, start, nr);
5259+
bitmap_clear(&within_size, start, nr);
5260+
} else if (!strcmp(policy, "advise")) {
5261+
bitmap_set(&madvise, start, nr);
5262+
bitmap_clear(&inherit, start, nr);
5263+
bitmap_clear(&always, start, nr);
5264+
bitmap_clear(&within_size, start, nr);
5265+
} else if (!strcmp(policy, "inherit")) {
5266+
bitmap_set(&inherit, start, nr);
5267+
bitmap_clear(&madvise, start, nr);
5268+
bitmap_clear(&always, start, nr);
5269+
bitmap_clear(&within_size, start, nr);
5270+
} else if (!strcmp(policy, "within_size")) {
5271+
bitmap_set(&within_size, start, nr);
5272+
bitmap_clear(&inherit, start, nr);
5273+
bitmap_clear(&madvise, start, nr);
5274+
bitmap_clear(&always, start, nr);
5275+
} else if (!strcmp(policy, "never")) {
5276+
bitmap_clear(&inherit, start, nr);
5277+
bitmap_clear(&madvise, start, nr);
5278+
bitmap_clear(&always, start, nr);
5279+
bitmap_clear(&within_size, start, nr);
5280+
} else {
5281+
pr_err("invalid policy %s in thp_shmem boot parameter\n", policy);
5282+
goto err;
5283+
}
5284+
}
5285+
}
5286+
5287+
huge_shmem_orders_always = always;
5288+
huge_shmem_orders_madvise = madvise;
5289+
huge_shmem_orders_inherit = inherit;
5290+
huge_shmem_orders_within_size = within_size;
5291+
shmem_orders_configured = true;
5292+
return 1;
5293+
5294+
err:
5295+
pr_warn("thp_shmem=%s: error parsing string, ignoring setting\n", str);
5296+
return 0;
5297+
}
5298+
__setup("thp_shmem=", setup_thp_shmem);
5299+
51975300
#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
51985301

51995302
#else /* !CONFIG_SHMEM */

0 commit comments

Comments
 (0)