| From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> |
| Date: Fri, 8 Nov 2019 12:55:47 +0100 |
| Subject: [PATCH] mm/compaction: Disable compact_unevictable_allowed on RT |
| |
| Since commit |
| 5bbe3547aa3ba ("mm: allow compaction of unevictable pages") |
| |
| it is allowed to examine mlocked pages and compact them by default. |
| On -RT even minor pagefaults are problematic because it may take a few |
| 100us to resolve them and until then the task is blocked. |
| |
| Make compact_unevictable_allowed = 0 default and issue a warning on RT |
| if it is changed. |
| |
| Link: https://lore.kernel.org/linux-mm/20190710144138.qyn4tuttdq6h7kqx@linutronix.de/ |
| Acked-by: Mel Gorman <mgorman@techsingularity.net> |
| Acked-by: Vlastimil Babka <vbabka@suse.cz> |
| Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> |
| --- |
| Documentation/admin-guide/sysctl/vm.rst | 3 +++ |
| kernel/sysctl.c | 29 ++++++++++++++++++++++++++++- |
| mm/compaction.c | 4 ++++ |
| 3 files changed, 35 insertions(+), 1 deletion(-) |
| |
| --- a/Documentation/admin-guide/sysctl/vm.rst |
| +++ b/Documentation/admin-guide/sysctl/vm.rst |
| @@ -128,6 +128,9 @@ allowed to examine the unevictable lru ( |
| This should be used on systems where stalls for minor page faults are an |
| acceptable trade for large contiguous free memory. Set to 0 to prevent |
| compaction from moving pages that are unevictable. Default value is 1. |
| +On CONFIG_PREEMPT_RT the default value is 0 in order to avoid a page fault, due |
| +to compaction, which would block the task from becomming active until the fault |
| +is resolved. |
| |
| |
| dirty_background_bytes |
| --- a/kernel/sysctl.c |
| +++ b/kernel/sysctl.c |
| @@ -212,6 +212,11 @@ static int proc_do_cad_pid(struct ctl_ta |
| void __user *buffer, size_t *lenp, loff_t *ppos); |
| static int proc_taint(struct ctl_table *table, int write, |
| void __user *buffer, size_t *lenp, loff_t *ppos); |
| +#ifdef CONFIG_COMPACTION |
| +static int proc_dointvec_minmax_warn_RT_change(struct ctl_table *table, |
| + int write, void __user *buffer, |
| + size_t *lenp, loff_t *ppos); |
| +#endif |
| #endif |
| |
| #ifdef CONFIG_PRINTK |
| @@ -1484,7 +1489,7 @@ static struct ctl_table vm_table[] = { |
| .data = &sysctl_compact_unevictable_allowed, |
| .maxlen = sizeof(int), |
| .mode = 0644, |
| - .proc_handler = proc_dointvec_minmax, |
| + .proc_handler = proc_dointvec_minmax_warn_RT_change, |
| .extra1 = SYSCTL_ZERO, |
| .extra2 = SYSCTL_ONE, |
| }, |
| @@ -2572,6 +2577,28 @@ int proc_dointvec(struct ctl_table *tabl |
| return do_proc_dointvec(table, write, buffer, lenp, ppos, NULL, NULL); |
| } |
| |
| +#ifdef CONFIG_COMPACTION |
| +static int proc_dointvec_minmax_warn_RT_change(struct ctl_table *table, |
| + int write, void __user *buffer, |
| + size_t *lenp, loff_t *ppos) |
| +{ |
| + int ret, old; |
| + |
| + if (!IS_ENABLED(CONFIG_PREEMPT_RT) || !write) |
| + return proc_dointvec_minmax(table, write, buffer, lenp, ppos); |
| + |
| + old = *(int *)table->data; |
| + ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos); |
| + if (ret) |
| + return ret; |
| + if (old != *(int *)table->data) |
| + pr_warn_once("sysctl attribute %s changed by %s[%d]\n", |
| + table->procname, current->comm, |
| + task_pid_nr(current)); |
| + return ret; |
| +} |
| +#endif |
| + |
| /** |
| * proc_douintvec - read a vector of unsigned integers |
| * @table: the sysctl table |
| --- a/mm/compaction.c |
| +++ b/mm/compaction.c |
| @@ -1590,7 +1590,11 @@ typedef enum { |
| * Allow userspace to control policy on scanning the unevictable LRU for |
| * compactable pages. |
| */ |
| +#ifdef CONFIG_PREEMPT_RT |
| +int sysctl_compact_unevictable_allowed __read_mostly = 0; |
| +#else |
| int sysctl_compact_unevictable_allowed __read_mostly = 1; |
| +#endif |
| |
| static inline void |
| update_fast_start_pfn(struct compact_control *cc, unsigned long pfn) |