提交 2525d04c 编写于 作者: M Ma Wupeng 提交者: Wang Wensheng

mm: Introduce proc interface to disable memory reliable features

hulk inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I4SK3S
CVE: NA

--------------------------------

reliable_debug is used to disable memory reliable features.

Four bits are used to represent the following features
- bit 0: memory reliable feature
- bit 1: reliable fallback feature
- bit 2: tmpfs use reliable memory feature
- bit 3: pagecache use reliable memory feature

Bit 1~3 are valid if and only if the bit 0 is 1. If the first bit is 0, all
other features will be closed no matter other bits's status.

For example, you can disable all features by

	$ echo 0 > /proc/sys/vm/reliable_debug
Signed-off-by: NMa Wupeng <mawupeng1@huawei.com>
Reviewed-by: NKefeng Wang <wangkefeng.wang@huawei.com>
上级 3f5ebb1c
......@@ -11,6 +11,14 @@
#define PAGES_TO_B(n_pages) ((n_pages) << PAGE_SHIFT)
enum mem_reliable_types {
MEM_RELIABLE_ALL,
MEM_RELIABLE_FALLBACK,
MEM_RELIABLE_SHMEM,
MEM_RELIABLE_PAGECACHE,
MEM_RELIABLE_MAX
};
DEFINE_STATIC_KEY_FALSE(mem_reliable);
EXPORT_SYMBOL_GPL(mem_reliable);
......@@ -193,6 +201,7 @@ void reliable_report_meminfo(struct seq_file *m)
}
}
#ifdef CONFIG_SYSCTL
static int reliable_limit_handler(struct ctl_table *table, int write,
void __user *buffer, size_t *length,
loff_t *ppos)
......@@ -232,6 +241,81 @@ static int reliable_pagecache_max_bytes_write(struct ctl_table *table,
return ret;
}
static void mem_reliable_feature_disable(int idx);
#define CTRL_BITS_SHIFT MEM_RELIABLE_MAX
#define CTRL_BITS_MASK ((1 << CTRL_BITS_SHIFT) - 1)
static unsigned long mem_reliable_ctrl_bits = CTRL_BITS_MASK;
static void mem_reliable_ctrl_bit_disable(int idx)
{
clear_bit(idx, &mem_reliable_ctrl_bits);
}
static bool mem_reliable_ctrl_bit_is_enabled(int idx)
{
return !!test_bit(idx, &mem_reliable_ctrl_bits);
}
static void mem_reliable_parse_ctrl_bits(unsigned long ctrl_bits)
{
bool status;
int i;
for (i = MEM_RELIABLE_FALLBACK; i < MEM_RELIABLE_MAX; i++) {
status = !!test_bit(i, &ctrl_bits);
if (mem_reliable_ctrl_bit_is_enabled(i) && !status)
mem_reliable_feature_disable(i);
}
}
static void mem_reliable_disable_all(void)
{
mem_reliable_ctrl_bits = 0;
reliable_allow_fallback = false;
shmem_reliable = false;
pagecache_use_reliable_mem = false;
static_branch_disable(&mem_reliable);
pr_info("memory reliable feature disabled.\n");
}
static int reliable_debug_handler(struct ctl_table *table, int write,
void __user *buffer, size_t *length,
loff_t *ppos)
{
unsigned long old_ctrl_bits, new_ctrl_bits;
static DEFINE_MUTEX(reliable_debug_mutex);
int ret;
mutex_lock(&reliable_debug_mutex);
old_ctrl_bits = mem_reliable_ctrl_bits;
ret = proc_doulongvec_minmax(table, write, buffer, length, ppos);
if (ret == 0 && write) {
if (!mem_reliable_is_enabled() ||
(mem_reliable_ctrl_bits > (1 << CTRL_BITS_SHIFT) - 1)) {
mem_reliable_ctrl_bits = old_ctrl_bits;
mutex_unlock(&reliable_debug_mutex);
return -EINVAL;
}
new_ctrl_bits = mem_reliable_ctrl_bits;
mem_reliable_ctrl_bits = old_ctrl_bits;
if (!!test_bit(MEM_RELIABLE_ALL, &new_ctrl_bits))
mem_reliable_parse_ctrl_bits(new_ctrl_bits);
else
mem_reliable_disable_all();
}
mutex_unlock(&reliable_debug_mutex);
return ret;
}
#ifdef CONFIG_SHMEM
static unsigned long sysctl_shmem_reliable_bytes_limit = ULONG_MAX;
......@@ -281,6 +365,13 @@ static struct ctl_table reliable_ctl_table[] = {
.proc_handler = reliable_shmem_bytes_limit_handler,
},
#endif
{
.procname = "reliable_debug",
.data = &mem_reliable_ctrl_bits,
.maxlen = sizeof(mem_reliable_ctrl_bits),
.mode = 0600,
.proc_handler = reliable_debug_handler,
},
{}
};
......@@ -310,6 +401,35 @@ static int __init reliable_sysctl_init(void)
return 0;
}
arch_initcall(reliable_sysctl_init);
#else
static void mem_reliable_ctrl_bit_disabled(int idx) {}
#endif
static void mem_reliable_feature_disable(int idx)
{
char *str = NULL;
switch (idx) {
case MEM_RELIABLE_FALLBACK:
reliable_allow_fallback = false;
str = "fallback";
break;
case MEM_RELIABLE_SHMEM:
shmem_reliable = false;
str = "shmem";
break;
case MEM_RELIABLE_PAGECACHE:
pagecache_use_reliable_mem = false;
str = "pagecache";
break;
default:
pr_err("unknown index: %d", idx);
return;
}
mem_reliable_ctrl_bit_disable(idx);
pr_info("%s is disabled\n", str);
}
void mem_reliable_out_of_memory(gfp_t gfp, unsigned int order,
int preferred_nid, nodemask_t *nodemask)
......@@ -342,16 +462,13 @@ static int __init setup_reliable_debug(char *str)
for (; *str && *str != ','; str++) {
switch (*str) {
case 'F':
reliable_allow_fallback = false;
pr_info("disable memory reliable fallback\n");
mem_reliable_feature_disable(MEM_RELIABLE_FALLBACK);
break;
case 'S':
shmem_reliable = false;
pr_info("disable shmem use reliable memory\n");
mem_reliable_feature_disable(MEM_RELIABLE_SHMEM);
break;
case 'P':
pagecache_use_reliable_mem = false;
pr_info("disable page cache use reliable memory\n");
mem_reliable_feature_disable(MEM_RELIABLE_PAGECACHE);
break;
default:
pr_err("reliable_debug option '%c' unknown. skipped\n",
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册