1// SPDX-License-Identifier: LGPL-2.1-or-later 2/* 3 * Copyright (C) 2005-2006 IBM Corporation. 4 * Author: Mel Gorman 5 */ 6 7/*\ 8 * [Description] 9 * 10 * readahead() on some kernels can cause the reservation counter to get 11 * corrupted. The problem is that the pages are allocated for the 12 * reservation but not faulted in at the time of allocation. The 13 * counters do not get updated and effectively "leak". This test 14 * identifies whether the kernel is vulnerable to the problem or not. 15 * It's fixed in kernel by commit f2deae9d4e70. 16 */ 17 18#define _GNU_SOURCE 19#include "hugetlb.h" 20 21#define MNTPOINT "hugetlbfs/" 22static long hpage_size; 23static int fd = -1; 24 25static void run_test(void) 26{ 27 void *p; 28 unsigned long initial_rsvd, map_rsvd, readahead_rsvd, end_rsvd; 29 30 fd = tst_creat_unlinked(MNTPOINT, 0); 31 initial_rsvd = SAFE_READ_MEMINFO(MEMINFO_HPAGE_RSVD); 32 33 p = SAFE_MMAP(NULL, hpage_size, PROT_READ|PROT_WRITE, MAP_SHARED, 34 fd, 0); 35 map_rsvd = SAFE_READ_MEMINFO(MEMINFO_HPAGE_RSVD); 36 tst_res(TINFO, "map_rsvd: %lu", map_rsvd); 37 38 readahead(fd, 0, hpage_size); 39 readahead_rsvd = SAFE_READ_MEMINFO(MEMINFO_HPAGE_RSVD); 40 tst_res(TINFO, "readahead_rsvd: %lu", readahead_rsvd); 41 42 memset(p, 1, hpage_size); 43 44 SAFE_MUNMAP(p, hpage_size); 45 SAFE_CLOSE(fd); 46 end_rsvd = SAFE_READ_MEMINFO(MEMINFO_HPAGE_RSVD); 47 48 TST_EXP_EQ_LU(end_rsvd, initial_rsvd); 49} 50 51static void setup(void) 52{ 53 hpage_size = tst_get_hugepage_size(); 54} 55 56static void cleanup(void) 57{ 58 if (fd >= 0) 59 SAFE_CLOSE(fd); 60} 61 62static struct tst_test test = { 63 .tags = (struct tst_tag[]) { 64 {"linux-git", "f2deae9d4e70"}, 65 {} 66 }, 67 .needs_root = 1, 68 .mntpoint = MNTPOINT, 69 .needs_hugetlbfs = 1, 70 .needs_tmpdir = 1, 71 .setup = setup, 72 .cleanup = cleanup, 73 .test_all = run_test, 74 .hugepages = {1, TST_NEEDS}, 75}; 76