[Devel] [PATCH 10/17] oom: boost dying tasks on global oom

Kirill Tkhai ktkhai at odin.com
Thu Sep 3 03:09:36 PDT 2015



On 14.08.2015 20:03, Vladimir Davydov wrote:
> If an oom victim process has a low prio (nice or via cpu cgroup), it may
> take it very long to complete, which is bad, because the system cannot
> make progress until it dies. To avoid that, this patch makes oom killer
> set victim task prio to the highest possible.
> 
> It might be worth submitting this patch upstream. I will probably try.
> 
> Signed-off-by: Vladimir Davydov <vdavydov at parallels.com>
> ---
>  mm/oom_kill.c | 17 +++++++++++++++--
>  1 file changed, 15 insertions(+), 2 deletions(-)
> 
> diff --git a/mm/oom_kill.c b/mm/oom_kill.c
> index 0e6f7535a565..ca765a82fa1a 100644
> --- a/mm/oom_kill.c
> +++ b/mm/oom_kill.c
> @@ -294,6 +294,15 @@ enum oom_scan_t oom_scan_process_thread(struct task_struct *task,
>  	return OOM_SCAN_OK;
>  }
>  
> +static void boost_dying_task(struct task_struct *p)
> +{
> +	/*
> +	 * Set the dying task scheduling priority to the highest possible so
> +	 * that it will die quickly irrespective of its scheduling policy.
> +	 */
> +	sched_boost_task(p, 0);
> +}
> +
>  /*
>   * Simple selection loop. We chose the process with the highest
>   * number of 'points'.
> @@ -321,6 +330,7 @@ static struct task_struct *select_bad_process(unsigned int *ppoints,
>  		case OOM_SCAN_CONTINUE:
>  			continue;
>  		case OOM_SCAN_ABORT:
> +			boost_dying_task(p);

This is potential livelock as you are holding at least try_set_zonelist_oom() bits locked
and concurrent thread may use GFP_NOFAIL in __alloc_pages_slowpath(). This case it will be
looping forever.

Furthermore, you manually do schedule_timeout_killable() in out_of_memory(), so this problem
is a problem of !PREEMPTIBLE kernel too.

You mustn't leave processor before you're cleared the bits.

>  			rcu_read_unlock();
>  			return ERR_PTR(-1UL);
>  		case OOM_SCAN_OK:
> @@ -426,8 +436,7 @@ void oom_kill_process(struct task_struct *p, gfp_t gfp_mask, int order,
>  	 */
>  	if (p->flags & PF_EXITING) {
>  		set_tsk_thread_flag(p, TIF_MEMDIE);
> -		put_task_struct(p);
> -		return;
> +		goto out;
>  	}
>  
>  	if (__ratelimit(&oom_rs))
> @@ -512,6 +521,9 @@ void oom_kill_process(struct task_struct *p, gfp_t gfp_mask, int order,
>  	set_tsk_thread_flag(victim, TIF_MEMDIE);
>  	do_send_sig_info(SIGKILL, SEND_SIG_FORCED, victim, true);
>  	mem_cgroup_note_oom_kill(memcg, victim);
> +out:
> +	if (!memcg)
> +		boost_dying_task(victim);
>  	put_task_struct(victim);
>  }
>  #undef K
> @@ -638,6 +650,7 @@ void out_of_memory(struct zonelist *zonelist, gfp_t gfp_mask,
>  	 */
>  	if (fatal_signal_pending(current) || current->flags & PF_EXITING) {
>  		set_thread_flag(TIF_MEMDIE);
> +		boost_dying_task(current);
>  		return;
>  	}
>  
> 



More information about the Devel mailing list