1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Copyright (c) 2019 Red Hat, Inc.
4 */
5
6 #define TST_NO_DEFAULT_MAIN
7
8 #include "tst_test.h"
9 #include "tst_hugepage.h"
10
11 unsigned long tst_hugepages;
12 char *nr_opt;
13 char *Hopt;
14
tst_get_hugepage_size(void)15 size_t tst_get_hugepage_size(void)
16 {
17 if (access(PATH_HUGEPAGES, F_OK))
18 return 0;
19
20 return SAFE_READ_MEMINFO("Hugepagesize:") * 1024;
21 }
22
tst_reserve_hugepages(struct tst_hugepage * hp)23 unsigned long tst_reserve_hugepages(struct tst_hugepage *hp)
24 {
25 unsigned long val, max_hpages;
26 struct tst_path_val pvl = {
27 .path = PATH_NR_HPAGES,
28 .val = NULL,
29 .flags = TST_SR_SKIP_MISSING | TST_SR_TCONF_RO
30 };
31
32 if (access(PATH_HUGEPAGES, F_OK)) {
33 if (hp->policy == TST_NEEDS)
34 tst_brk(TCONF, "hugetlbfs is not supported");
35 tst_hugepages = 0;
36 goto out;
37 }
38
39 if (nr_opt)
40 tst_hugepages = SAFE_STRTOL(nr_opt, 1, LONG_MAX);
41 else
42 tst_hugepages = hp->number;
43
44 if (hp->number == TST_NO_HUGEPAGES) {
45 tst_hugepages = 0;
46 goto set_hugepages;
47 }
48
49 SAFE_FILE_PRINTF("/proc/sys/vm/drop_caches", "3");
50 if (hp->policy == TST_NEEDS) {
51 tst_hugepages += SAFE_READ_MEMINFO("HugePages_Total:");
52 goto set_hugepages;
53 }
54
55 max_hpages = SAFE_READ_MEMINFO("MemFree:") / SAFE_READ_MEMINFO("Hugepagesize:");
56 if (tst_hugepages > max_hpages) {
57 tst_res(TINFO, "Requested number(%lu) of hugepages is too large, "
58 "limiting to 80%% of the max hugepage count %lu",
59 tst_hugepages, max_hpages);
60 tst_hugepages = max_hpages * 0.8;
61
62 if (tst_hugepages < 1)
63 goto out;
64 }
65
66 set_hugepages:
67 tst_sys_conf_save(&pvl);
68 SAFE_FILE_PRINTF(PATH_NR_HPAGES, "%lu", tst_hugepages);
69 SAFE_FILE_SCANF(PATH_NR_HPAGES, "%lu", &val);
70 if (val != tst_hugepages)
71 tst_brk(TCONF, "nr_hugepages = %lu, but expect %lu. "
72 "Not enough hugepages for testing.",
73 val, tst_hugepages);
74
75 if (hp->policy == TST_NEEDS) {
76 unsigned long free_hpages = SAFE_READ_MEMINFO("HugePages_Free:");
77 if (hp->number > free_hpages)
78 tst_brk(TCONF, "free_hpages = %lu, but expect %lu. "
79 "Not enough hugepages for testing.",
80 free_hpages, hp->number);
81 }
82
83 tst_res(TINFO, "%lu hugepage(s) reserved", tst_hugepages);
84 out:
85 return tst_hugepages;
86 }
87