tools/testing/selftests/mm/memory-failure.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/mm/memory-failure.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/mm/memory-failure.c
Extension
.c
Size
8408 bytes
Lines
359
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
/*
 * Memory-failure functional tests.
 *
 * Author(s): Miaohe Lin <linmiaohe@huawei.com>
 */

#include "../kselftest_harness.h"

#include <sys/mman.h>
#include <linux/mman.h>
#include <linux/string.h>
#include <unistd.h>
#include <signal.h>
#include <setjmp.h>
#include <fcntl.h>
#include <sys/vfs.h>
#include <linux/magic.h>
#include <errno.h>

#include "vm_util.h"

enum inject_type {
	MADV_HARD,
	MADV_SOFT,
};

enum result_type {
	MADV_HARD_ANON,
	MADV_HARD_CLEAN_PAGECACHE,
	MADV_HARD_DIRTY_PAGECACHE,
	MADV_SOFT_ANON,
	MADV_SOFT_CLEAN_PAGECACHE,
	MADV_SOFT_DIRTY_PAGECACHE,
};

static jmp_buf signal_jmp_buf;
static siginfo_t siginfo;
const char *pagemap_proc = "/proc/self/pagemap";
const char *kpageflags_proc = "/proc/kpageflags";

FIXTURE(memory_failure)
{
	unsigned long page_size;
	unsigned long corrupted_size;
	unsigned long pfn;
	int pagemap_fd;
	int kpageflags_fd;
	bool triggered;
};

FIXTURE_VARIANT(memory_failure)
{
	enum inject_type type;
	int (*inject)(FIXTURE_DATA(memory_failure) * self, void *vaddr);
};

static int madv_hard_inject(FIXTURE_DATA(memory_failure) * self, void *vaddr)
{
	return madvise(vaddr, self->page_size, MADV_HWPOISON);
}

FIXTURE_VARIANT_ADD(memory_failure, madv_hard)
{
	.type = MADV_HARD,
	.inject = madv_hard_inject,
};

static int madv_soft_inject(FIXTURE_DATA(memory_failure) * self, void *vaddr)
{
	return madvise(vaddr, self->page_size, MADV_SOFT_OFFLINE);
}

FIXTURE_VARIANT_ADD(memory_failure, madv_soft)
{
	.type = MADV_SOFT,
	.inject = madv_soft_inject,
};

static void sigbus_action(int signo, siginfo_t *si, void *args)
{
	memcpy(&siginfo, si, sizeof(siginfo_t));
	siglongjmp(signal_jmp_buf, 1);
}

static int setup_sighandler(void)
{
	struct sigaction sa = {
		.sa_sigaction = sigbus_action,
		.sa_flags = SA_SIGINFO,

Annotation

Implementation Notes