From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751545AbaHIAq4 (ORCPT ); Fri, 8 Aug 2014 20:46:56 -0400 Received: from mail-pd0-f172.google.com ([209.85.192.172]:39980 "EHLO mail-pd0-f172.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750764AbaHIAqy (ORCPT ); Fri, 8 Aug 2014 20:46:54 -0400 From: Cong Wang To: linux-kernel@vger.kernel.org Cc: David Rientjes , Michal Hocko , "Rafael J. Wysocki" , Tejun Heo , Andrew Morton , Cong Wang Subject: [Patch] freezer: check OOM kill signal while being frozen Date: Fri, 8 Aug 2014 17:46:38 -0700 Message-Id: <1407545198-9009-1-git-send-email-xiyou.wangcong@gmail.com> X-Mailer: git-send-email 1.8.3.1 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org There is a race condition between OOM killer and freezer when they try to operate on the same process, something like below: Process A Process B Process C trigger oom B=oom_scan_process_thread() cgroup_freezer_freeze(B) ... try_to_freeze() stay in D state oom_kill_process(B) In this case, process A triggers OOM and kernel selects process B as the victim, right before being killed process B was frozen by process C therefore went to D state, then kernel sent SIGKILL but it is already too late as process B will never care about pending signals any more. Fix this straightly by checking fatal pending signal from OOM killer, so that the frozen process will recover itself and then be killed finally. Cc: David Rientjes Cc: Michal Hocko Cc: "Rafael J. Wysocki" Cc: Tejun Heo Cc: Andrew Morton Signed-off-by: Cong Wang --- diff --git a/kernel/freezer.c b/kernel/freezer.c index aa6a8aa..c6d189d 100644 --- a/kernel/freezer.c +++ b/kernel/freezer.c @@ -68,7 +68,9 @@ bool __refrigerator(bool check_kthr_stop) spin_lock_irq(&freezer_lock); current->flags |= PF_FROZEN; if (!freezing(current) || - (check_kthr_stop && kthread_should_stop())) + (check_kthr_stop && kthread_should_stop()) || + (test_tsk_thread_flag(current, TIF_MEMDIE) && + fatal_signal_pending(current))) current->flags &= ~PF_FROZEN; spin_unlock_irq(&freezer_lock);