Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 05d778c2 authored by Charan Teja Reddy's avatar Charan Teja Reddy
Browse files

lowmemorykiller: use oom reaper to free pages of task killed by lmk



Free the pages parallely for a task that is LMK killed using the
oom_reaper. This freeing of pages will help to give the pages to
buddy system well advance there by we may achieve less number of
killings by LMK.

Change-Id: I5e1ed183437ab243f12cbbf3ae10d9ca5211fc06
Signed-off-by: default avatarCharan Teja Reddy <charante@codeaurora.org>
parent 84a47e8c
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -48,6 +48,7 @@
#include <linux/fs.h>
#include <linux/cpuset.h>
#include <linux/vmpressure.h>
#include <linux/freezer.h>

#define CREATE_TRACE_POINTS
#include <trace/events/almk.h>
@@ -116,6 +117,10 @@ module_param_named(enable_adaptive_lmk, enable_adaptive_lmk, int, 0644);
static int vmpressure_file_min;
module_param_named(vmpressure_file_min, vmpressure_file_min, int, 0644);

/* User knob to enable/disable oom reaping feature */
static int oom_reaper;
module_param_named(oom_reaper, oom_reaper, int, 0644);

enum {
	VMPRESSURE_NO_ADJUST = 0,
	VMPRESSURE_ADJUST_ENCROACH,
@@ -406,6 +411,14 @@ void tune_lmk_param(int *other_free, int *other_file, struct shrink_control *sc)
	}
}

static void mark_lmk_victim(struct task_struct *tsk)
{
	struct mm_struct *mm = tsk->mm;

	if (!cmpxchg(&tsk->signal->oom_mm, NULL, mm))
		atomic_inc(&tsk->signal->oom_mm->mm_count);
}

static unsigned long lowmem_scan(struct shrinker *s, struct shrink_control *sc)
{
	struct task_struct *tsk;
@@ -524,7 +537,11 @@ static unsigned long lowmem_scan(struct shrinker *s, struct shrink_control *sc)
		send_sig(SIGKILL, selected, 0);
		if (selected->mm)
			task_set_lmk_waiting(selected);
		if (oom_reaper)
			mark_lmk_victim(selected);
		task_unlock(selected);
		if (oom_reaper)
			wake_oom_reaper(selected);
		trace_lowmemory_kill(selected, cache_size, cache_limit, free);
		lowmem_print(1, "Killing '%s' (%d) (tgid %d), adj %hd,\n"
			"to free %ldkB on behalf of '%s' (%d) because\n"
+2 −0
Original line number Diff line number Diff line
@@ -82,6 +82,8 @@ extern struct task_struct *find_lock_task_mm(struct task_struct *p);
extern void dump_tasks(struct mem_cgroup *memcg,
		const nodemask_t *nodemask);

extern void wake_oom_reaper(struct task_struct *tsk);

/* sysctls */
extern int sysctl_oom_dump_tasks;
extern int sysctl_oom_kill_allocating_task;
+8 −3
Original line number Diff line number Diff line
@@ -608,18 +608,23 @@ static int oom_reaper(void *unused)
	return 0;
}

static void wake_oom_reaper(struct task_struct *tsk)
void wake_oom_reaper(struct task_struct *tsk)
{
	if (!oom_reaper_th)
		return;

	/* move the lock here to avoid scenario of queuing
	 * the same task by both OOM killer and LMK.
	 */
	spin_lock(&oom_reaper_lock);
	/* tsk is already queued? */
	if (tsk == oom_reaper_list || tsk->oom_reaper_list)
	if (tsk == oom_reaper_list || tsk->oom_reaper_list) {
		spin_unlock(&oom_reaper_lock);
		return;
	}

	get_task_struct(tsk);

	spin_lock(&oom_reaper_lock);
	tsk->oom_reaper_list = oom_reaper_list;
	oom_reaper_list = tsk;
	spin_unlock(&oom_reaper_lock);