diff options
Diffstat (limited to 'tools/testing/selftests/mm/compaction_test.c')
| -rw-r--r-- | tools/testing/selftests/mm/compaction_test.c | 91 | 
1 files changed, 63 insertions, 28 deletions
diff --git a/tools/testing/selftests/mm/compaction_test.c b/tools/testing/selftests/mm/compaction_test.c index 533999b6c284..e140558e6f53 100644 --- a/tools/testing/selftests/mm/compaction_test.c +++ b/tools/testing/selftests/mm/compaction_test.c @@ -82,12 +82,16 @@ int prereq(void)  	return -1;  } -int check_compaction(unsigned long mem_free, unsigned int hugepage_size) +int check_compaction(unsigned long mem_free, unsigned long hugepage_size, +		     unsigned long initial_nr_hugepages)  { +	unsigned long nr_hugepages_ul;  	int fd, ret = -1;  	int compaction_index = 0; -	char initial_nr_hugepages[10] = {0}; -	char nr_hugepages[10] = {0}; +	char nr_hugepages[20] = {0}; +	char init_nr_hugepages[20] = {0}; + +	sprintf(init_nr_hugepages, "%lu", initial_nr_hugepages);  	/* We want to test with 80% of available memory. Else, OOM killer comes  	   in to play */ @@ -101,21 +105,6 @@ int check_compaction(unsigned long mem_free, unsigned int hugepage_size)  		goto out;  	} -	if (read(fd, initial_nr_hugepages, sizeof(initial_nr_hugepages)) <= 0) { -		ksft_print_msg("Failed to read from /proc/sys/vm/nr_hugepages: %s\n", -			       strerror(errno)); -		goto close_fd; -	} - -	/* Start with the initial condition of 0 huge pages*/ -	if (write(fd, "0", sizeof(char)) != sizeof(char)) { -		ksft_print_msg("Failed to write 0 to /proc/sys/vm/nr_hugepages: %s\n", -			       strerror(errno)); -		goto close_fd; -	} - -	lseek(fd, 0, SEEK_SET); -  	/* Request a large number of huge pages. The Kernel will allocate  	   as much as it can */  	if (write(fd, "100000", (6*sizeof(char))) != (6*sizeof(char))) { @@ -134,22 +123,27 @@ int check_compaction(unsigned long mem_free, unsigned int hugepage_size)  	/* We should have been able to request at least 1/3 rd of the memory in  	   huge pages */ -	compaction_index = mem_free/(atoi(nr_hugepages) * hugepage_size); +	nr_hugepages_ul = strtoul(nr_hugepages, NULL, 10); +	if (!nr_hugepages_ul) { +		ksft_print_msg("ERROR: No memory is available as huge pages\n"); +		goto close_fd; +	} +	compaction_index = mem_free/(nr_hugepages_ul * hugepage_size);  	lseek(fd, 0, SEEK_SET); -	if (write(fd, initial_nr_hugepages, strlen(initial_nr_hugepages)) -	    != strlen(initial_nr_hugepages)) { +	if (write(fd, init_nr_hugepages, strlen(init_nr_hugepages)) +	    != strlen(init_nr_hugepages)) {  		ksft_print_msg("Failed to write value to /proc/sys/vm/nr_hugepages: %s\n",  			       strerror(errno));  		goto close_fd;  	} -	ksft_print_msg("Number of huge pages allocated = %d\n", -		       atoi(nr_hugepages)); +	ksft_print_msg("Number of huge pages allocated = %lu\n", +		       nr_hugepages_ul);  	if (compaction_index > 3) { -		ksft_print_msg("ERROR: Less that 1/%d of memory is available\n" +		ksft_print_msg("ERROR: Less than 1/%d of memory is available\n"  			       "as huge pages\n", compaction_index);  		goto close_fd;  	} @@ -163,6 +157,41 @@ int check_compaction(unsigned long mem_free, unsigned int hugepage_size)  	return ret;  } +int set_zero_hugepages(unsigned long *initial_nr_hugepages) +{ +	int fd, ret = -1; +	char nr_hugepages[20] = {0}; + +	fd = open("/proc/sys/vm/nr_hugepages", O_RDWR | O_NONBLOCK); +	if (fd < 0) { +		ksft_print_msg("Failed to open /proc/sys/vm/nr_hugepages: %s\n", +			       strerror(errno)); +		goto out; +	} +	if (read(fd, nr_hugepages, sizeof(nr_hugepages)) <= 0) { +		ksft_print_msg("Failed to read from /proc/sys/vm/nr_hugepages: %s\n", +			       strerror(errno)); +		goto close_fd; +	} + +	lseek(fd, 0, SEEK_SET); + +	/* Start with the initial condition of 0 huge pages */ +	if (write(fd, "0", sizeof(char)) != sizeof(char)) { +		ksft_print_msg("Failed to write 0 to /proc/sys/vm/nr_hugepages: %s\n", +			       strerror(errno)); +		goto close_fd; +	} + +	*initial_nr_hugepages = strtoul(nr_hugepages, NULL, 10); +	ret = 0; + + close_fd: +	close(fd); + + out: +	return ret; +}  int main(int argc, char **argv)  { @@ -173,14 +202,19 @@ int main(int argc, char **argv)  	unsigned long mem_free = 0;  	unsigned long hugepage_size = 0;  	long mem_fragmentable_MB = 0; +	unsigned long initial_nr_hugepages;  	ksft_print_header();  	if (prereq() || geteuid()) -		return ksft_exit_skip("Prerequisites unsatisfied\n"); +		ksft_exit_skip("Prerequisites unsatisfied\n");  	ksft_set_plan(1); +	/* Start the test without hugepages reducing mem_free */ +	if (set_zero_hugepages(&initial_nr_hugepages)) +		ksft_exit_fail(); +  	lim.rlim_cur = RLIM_INFINITY;  	lim.rlim_max = RLIM_INFINITY;  	if (setrlimit(RLIMIT_MEMLOCK, &lim)) @@ -224,8 +258,9 @@ int main(int argc, char **argv)  		entry = entry->next;  	} -	if (check_compaction(mem_free, hugepage_size) == 0) -		return ksft_exit_pass(); +	if (check_compaction(mem_free, hugepage_size, +			     initial_nr_hugepages) == 0) +		ksft_exit_pass(); -	return ksft_exit_fail(); +	ksft_exit_fail();  }  |