diff mbox series

[RFC,1/2] mm: oom: expose expedite_reclaim to use oom_reaper outside of oom_kill.c

Message ID 20190411014353.113252-2-surenb@google.com (mailing list archive)
State New, archived
Headers show
Series opportunistic memory reclaim of a killed process | expand

Commit Message

Suren Baghdasaryan April 11, 2019, 1:43 a.m. UTC
Create an API to allow users outside of oom_kill.c to mark a victim and
wake up oom_reaper thread for expedited memory reclaim of the process being
killed.

Signed-off-by: Suren Baghdasaryan <surenb@google.com>
---
 include/linux/oom.h |  1 +
 mm/oom_kill.c       | 15 +++++++++++++++
 2 files changed, 16 insertions(+)

Comments

Tetsuo Handa April 25, 2019, 9:12 p.m. UTC | #1
On 2019/04/11 10:43, Suren Baghdasaryan wrote:
> diff --git a/mm/oom_kill.c b/mm/oom_kill.c
> index 3a2484884cfd..6449710c8a06 100644
> --- a/mm/oom_kill.c
> +++ b/mm/oom_kill.c
> @@ -1102,6 +1102,21 @@ bool out_of_memory(struct oom_control *oc)
>  	return !!oc->chosen;
>  }
>  
> +bool expedite_reclaim(struct task_struct *task)
> +{
> +	bool res = false;
> +
> +	task_lock(task);
> +	if (task_will_free_mem(task)) {

mark_oom_victim() needs to be called under oom_lock mutex after
checking that oom_killer_disabled == false. Since you are trying
to trigger this function from signal handler, you might want to
defer until e.g. WQ context.

> +		mark_oom_victim(task);
> +		wake_oom_reaper(task);
> +		res = true;
> +	}
> +	task_unlock(task);
> +
> +	return res;
> +}
> +
>  /*
>   * The pagefault handler calls here because it is out of memory, so kill a
>   * memory-hogging task. If oom_lock is held by somebody else, a parallel oom
>
Suren Baghdasaryan April 25, 2019, 9:56 p.m. UTC | #2
On Thu, Apr 25, 2019 at 2:13 PM Tetsuo Handa
<penguin-kernel@i-love.sakura.ne.jp> wrote:
>
> On 2019/04/11 10:43, Suren Baghdasaryan wrote:
> > diff --git a/mm/oom_kill.c b/mm/oom_kill.c
> > index 3a2484884cfd..6449710c8a06 100644
> > --- a/mm/oom_kill.c
> > +++ b/mm/oom_kill.c
> > @@ -1102,6 +1102,21 @@ bool out_of_memory(struct oom_control *oc)
> >       return !!oc->chosen;
> >  }
> >
> > +bool expedite_reclaim(struct task_struct *task)
> > +{
> > +     bool res = false;
> > +
> > +     task_lock(task);
> > +     if (task_will_free_mem(task)) {
>
> mark_oom_victim() needs to be called under oom_lock mutex after
> checking that oom_killer_disabled == false. Since you are trying
> to trigger this function from signal handler, you might want to
> defer until e.g. WQ context.

Thanks for the tip! I'll take this into account in the new design.
Just thinking out loud... AFAIU oom_lock is there to protect against
multiple concurrent out_of_memory calls from different contexts and
prevent overly-aggressive process killing. For my purposes when
reaping memory of a killed process we don't have this concern (we did
not initiate the killing, SIGKILL was explicitly requested). I'll
probably need some synchronization there but not for purposes of
preventing multiple concurrent reapers. In any case, thank you for the
feedback!

>
> > +             mark_oom_victim(task);
> > +             wake_oom_reaper(task);
> > +             res = true;
> > +     }
> > +     task_unlock(task);
> > +
> > +     return res;
> > +}
> > +
> >  /*
> >   * The pagefault handler calls here because it is out of memory, so kill a
> >   * memory-hogging task. If oom_lock is held by somebody else, a parallel oom
> >
diff mbox series

Patch

diff --git a/include/linux/oom.h b/include/linux/oom.h
index d07992009265..6c043c7518c1 100644
--- a/include/linux/oom.h
+++ b/include/linux/oom.h
@@ -112,6 +112,7 @@  extern unsigned long oom_badness(struct task_struct *p,
 		unsigned long totalpages);
 
 extern bool out_of_memory(struct oom_control *oc);
+extern bool expedite_reclaim(struct task_struct *task);
 
 extern void exit_oom_victim(void);
 
diff --git a/mm/oom_kill.c b/mm/oom_kill.c
index 3a2484884cfd..6449710c8a06 100644
--- a/mm/oom_kill.c
+++ b/mm/oom_kill.c
@@ -1102,6 +1102,21 @@  bool out_of_memory(struct oom_control *oc)
 	return !!oc->chosen;
 }
 
+bool expedite_reclaim(struct task_struct *task)
+{
+	bool res = false;
+
+	task_lock(task);
+	if (task_will_free_mem(task)) {
+		mark_oom_victim(task);
+		wake_oom_reaper(task);
+		res = true;
+	}
+	task_unlock(task);
+
+	return res;
+}
+
 /*
  * The pagefault handler calls here because it is out of memory, so kill a
  * memory-hogging task. If oom_lock is held by somebody else, a parallel oom