Skip to content

Instantly share code, notes, and snippets.

@laoar
Created August 22, 2019 07:13
Show Gist options
  • Save laoar/2f534c470b08f3dd65164ea0b3678f49 to your computer and use it in GitHub Desktop.
Save laoar/2f534c470b08f3dd65164ea0b3678f49 to your computer and use it in GitHub Desktop.
patch for memcg socre_adj
--- a/include/linux/memcontrol.h
+++ b/include/linux/memcontrol.h
@@ -21,6 +21,7 @@
#include <linux/vmstat.h>
#include <linux/writeback.h>
#include <linux/page-flags.h>
+#include <linux/oom.h>
struct mem_cgroup;
struct page;
@@ -224,6 +225,7 @@ struct mem_cgroup {
* Should the OOM killer kill all belonging tasks, had it kill one?
*/
bool oom_group;
+ short oom_score_adj;
/* protected by memcg_oom_lock */
bool oom_lock;
@@ -538,6 +540,23 @@ static inline bool task_in_memcg_oom(struct task_struct *p)
return p->memcg_in_oom;
}
+static inline int mem_cgroup_score_adj(struct task_struct *p, int task_adj)
+{
+ struct mem_cgroup *memcg;
+ int adj = task_adj;
+
+ memcg = mem_cgroup_from_task(p);
+ if (memcg != root_mem_cgroup) {
+ adj += memcg->oom_score_adj;
+ if (adj < OOM_SCORE_ADJ_MIN)
+ adj = OOM_SCORE_ADJ_MIN;
+ else if (adj > OOM_SCORE_ADJ_MAX)
+ adj = OOM_SCORE_ADJ_MAX;
+ }
+
+ return adj;
+}
+
bool mem_cgroup_oom_synchronize(bool wait);
struct mem_cgroup *mem_cgroup_get_oom_group(struct task_struct *victim,
struct mem_cgroup *oom_domain);
@@ -987,6 +1006,11 @@ static inline bool task_in_memcg_oom(struct task_struct *p)
return false;
}
+static inline int mem_cgroup_score_adj(struct task_struct *p, int task_adj)
+{
+ return task_adj;
+}
+
static inline bool mem_cgroup_oom_synchronize(bool wait)
{
return false;
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 6f5c0c5..065285c 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -5856,6 +5856,38 @@ static ssize_t memory_oom_group_write(struct kernfs_open_file *of,
return nbytes;
}
+static int memory_oom_score_adj_show(struct seq_file *m, void *v)
+{
+ struct mem_cgroup *memcg = mem_cgroup_from_seq(m);
+
+ seq_printf(m, "%d\n", memcg->oom_score_adj);
+
+ return 0;
+}
+
+static ssize_t memory_oom_score_adj_write(struct kernfs_open_file *of,
+ char *buf, size_t nbytes, loff_t off)
+{
+ struct mem_cgroup *memcg = mem_cgroup_from_css(of_css(of));
+ int oom_score_adj;
+ int ret;
+
+ buf = strstrip(buf);
+ if (!buf)
+ return -EINVAL;
+
+ ret = kstrtoint(buf, 0, &oom_score_adj);
+ if (ret)
+ return ret;
+
+ if (oom_score_adj > 1000 || oom_score_adj < -1000)
+ return -EINVAL;
+
+ memcg->oom_score_adj = oom_score_adj;
+
+ return nbytes;
+}
+
static struct cftype memory_files[] = {
{
.name = "current",
@@ -5909,6 +5941,12 @@ static ssize_t memory_oom_group_write(struct kernfs_open_file *of,
.seq_show = memory_oom_group_show,
.write = memory_oom_group_write,
},
+ {
+ .name = "oom.score_adj",
+ .flags = CFTYPE_NOT_ON_ROOT | CFTYPE_NS_DELEGATABLE,
+ .seq_show = memory_oom_score_adj_show,
+ .write = memory_oom_score_adj_write,
+ },
{ } /* terminate */
};
diff --git a/mm/oom_kill.c b/mm/oom_kill.c
index eda2e2a..ca782a5 100644
--- a/mm/oom_kill.c
+++ b/mm/oom_kill.c
@@ -212,13 +212,7 @@ unsigned long oom_badness(struct task_struct *p, unsigned long totalpages)
* unkillable or have been already oom reaped or the are in
* the middle of vfork
*/
- adj = (long)p->signal->oom_score_adj;
- if (adj == OOM_SCORE_ADJ_MIN ||
- test_bit(MMF_OOM_SKIP, &p->mm->flags) ||
- in_vfork(p)) {
- task_unlock(p);
- return 0;
- }
+ adj = mem_cgroup_score_adj(p, p->signal->oom_score_adj);
/*
* The baseline for the badness score is the proportion of RAM that each
@@ -939,8 +933,8 @@ static void __oom_kill_process(struct task_struct *victim, const char *message)
*/
static int oom_kill_memcg_member(struct task_struct *task, void *message)
{
- if (task->signal->oom_score_adj != OOM_SCORE_ADJ_MIN &&
- !is_global_init(task)) {
+ if (mem_cgroup_score_adj(task, task->signal->oom_score_adj) !=
+ OOM_SCORE_ADJ_MIN && !is_global_init(task)) {
get_task_struct(task);
__oom_kill_process(task, message);
}
@@ -1085,7 +1079,8 @@ bool out_of_memory(struct oom_control *oc)
if (!is_memcg_oom(oc) && sysctl_oom_kill_allocating_task &&
current->mm && !oom_unkillable_task(current) &&
oom_cpuset_eligible(current, oc) &&
- current->signal->oom_score_adj != OOM_SCORE_ADJ_MIN) {
+ mem_cgroup_score_adj(current, current->signal->oom_score_adj) !=
+ OOM_SCORE_ADJ_MIN) {
get_task_struct(current);
oc->chosen = current;
oom_kill_process(oc, "Out of memory (oom_kill_allocating_task)");
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment