tools/testing/selftests/arm64/mte/check_ksm_options.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/arm64/mte/check_ksm_options.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/arm64/mte/check_ksm_options.c
Extension
.c
Size
4460 bytes
Lines
167
Domain
Support Tooling And Documentation
Bucket
tools
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

// SPDX-License-Identifier: GPL-2.0
// Copyright (C) 2020 ARM Limited

#define _GNU_SOURCE

#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ucontext.h>
#include <sys/mman.h>

#include "kselftest.h"
#include "mte_common_util.h"
#include "mte_def.h"

#define TEST_UNIT	10
#define PATH_KSM	"/sys/kernel/mm/ksm/"
#define MAX_LOOP	4

static size_t page_sz;
static unsigned long ksm_sysfs[5];

static unsigned long read_sysfs(char *str)
{
	FILE *f;
	unsigned long val = 0;

	f = fopen(str, "r");
	if (!f) {
		ksft_print_msg("ERR: missing %s\n", str);
		return 0;
	}
	if (fscanf(f, "%lu", &val) != 1) {
		ksft_print_msg("ERR: parsing %s\n", str);
		val = 0;
	}
	fclose(f);
	return val;
}

static void write_sysfs(char *str, unsigned long val)
{
	FILE *f;

	f = fopen(str, "w");
	if (!f) {
		ksft_print_msg("ERR: missing %s\n", str);
		return;
	}
	fprintf(f, "%lu", val);
	fclose(f);
}

static void mte_ksm_setup(void)
{
	ksm_sysfs[0] = read_sysfs(PATH_KSM "merge_across_nodes");
	write_sysfs(PATH_KSM "merge_across_nodes", 1);
	ksm_sysfs[1] = read_sysfs(PATH_KSM "sleep_millisecs");
	write_sysfs(PATH_KSM "sleep_millisecs", 0);
	ksm_sysfs[2] = read_sysfs(PATH_KSM "run");
	write_sysfs(PATH_KSM "run", 1);
	ksm_sysfs[3] = read_sysfs(PATH_KSM "max_page_sharing");
	write_sysfs(PATH_KSM "max_page_sharing", ksm_sysfs[3] + TEST_UNIT);
	ksm_sysfs[4] = read_sysfs(PATH_KSM "pages_to_scan");
	write_sysfs(PATH_KSM "pages_to_scan", ksm_sysfs[4] + TEST_UNIT);
}

static void mte_ksm_restore(void)
{
	write_sysfs(PATH_KSM "merge_across_nodes", ksm_sysfs[0]);
	write_sysfs(PATH_KSM "sleep_millisecs", ksm_sysfs[1]);
	write_sysfs(PATH_KSM "run", ksm_sysfs[2]);
	write_sysfs(PATH_KSM "max_page_sharing", ksm_sysfs[3]);
	write_sysfs(PATH_KSM "pages_to_scan", ksm_sysfs[4]);
}

static void mte_ksm_scan(void)
{
	int cur_count = read_sysfs(PATH_KSM "full_scans");
	int scan_count = cur_count + 1;
	int max_loop_count = MAX_LOOP;

	while ((cur_count < scan_count) && max_loop_count) {
		sleep(1);
		cur_count = read_sysfs(PATH_KSM "full_scans");
		max_loop_count--;
	}

Annotation

Implementation Notes