aboutsummaryrefslogtreecommitdiff
path: root/lib/tst_hugepage.c
blob: 728a8c3ecc6667a7f67667c39689526d03c8bd4f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Copyright (c) 2019 Red Hat, Inc.
 */

#define TST_NO_DEFAULT_MAIN

#include "tst_test.h"
#include "tst_hugepage.h"

unsigned long tst_hugepages;
char *nr_opt;
char *Hopt;

size_t tst_get_hugepage_size(void)
{
	if (access(PATH_HUGEPAGES, F_OK))
		return 0;

	return SAFE_READ_MEMINFO("Hugepagesize:") * 1024;
}

unsigned long tst_reserve_hugepages(struct tst_hugepage *hp)
{
	unsigned long val, max_hpages;
	struct tst_path_val pvl = {
		.path = PATH_NR_HPAGES,
		.val = NULL,
		.flags = TST_SR_SKIP_MISSING | TST_SR_TCONF_RO
	};

	if (access(PATH_HUGEPAGES, F_OK)) {
		if (hp->policy == TST_NEEDS)
			tst_brk(TCONF, "hugetlbfs is not supported");
		tst_hugepages = 0;
		goto out;
	}

	if (nr_opt)
		tst_hugepages = SAFE_STRTOL(nr_opt, 1, LONG_MAX);
	else
		tst_hugepages = hp->number;

	if (hp->number == TST_NO_HUGEPAGES) {
		tst_hugepages = 0;
		goto set_hugepages;
	}

	SAFE_FILE_PRINTF("/proc/sys/vm/drop_caches", "3");
	if (hp->policy == TST_NEEDS) {
		tst_hugepages += SAFE_READ_MEMINFO("HugePages_Total:");
		goto set_hugepages;
	}

	max_hpages = SAFE_READ_MEMINFO("MemFree:") / SAFE_READ_MEMINFO("Hugepagesize:");
	if (tst_hugepages > max_hpages) {
		tst_res(TINFO, "Requested number(%lu) of hugepages is too large, "
				"limiting to 80%% of the max hugepage count %lu",
				tst_hugepages, max_hpages);
		tst_hugepages = max_hpages * 0.8;

		if (tst_hugepages < 1)
			goto out;
	}

set_hugepages:
	tst_sys_conf_save(&pvl);
	SAFE_FILE_PRINTF(PATH_NR_HPAGES, "%lu", tst_hugepages);
	SAFE_FILE_SCANF(PATH_NR_HPAGES, "%lu", &val);
	if (val != tst_hugepages)
		tst_brk(TCONF, "nr_hugepages = %lu, but expect %lu. "
				"Not enough hugepages for testing.",
				val, tst_hugepages);

	if (hp->policy == TST_NEEDS) {
		unsigned long free_hpages = SAFE_READ_MEMINFO("HugePages_Free:");
		if (hp->number > free_hpages)
			tst_brk(TCONF, "free_hpages = %lu, but expect %lu. "
				"Not enough hugepages for testing.",
				free_hpages, hp->number);
	}

	tst_res(TINFO, "%lu hugepage(s) reserved", tst_hugepages);
out:
	return tst_hugepages;
}