diff mbox

mm,oom: Do not unfreeze OOM victim thread.

Message ID 1522334218-4268-1-git-send-email-penguin-kernel@I-love.SAKURA.ne.jp (mailing list archive)
State Not Applicable, archived
Headers show

Commit Message

Tetsuo Handa March 29, 2018, 2:36 p.m. UTC
Currently, mark_oom_victim() calls __thaw_task() on the OOM victim
threads and freezing_slow_path() unfreezes the OOM victim thread.
But I think this exceptional behavior makes little sense nowadays.

The OOM killer kills only userspace processes. All userspace processes
except current thread which calls oom_killer_disable() and !TIF_MEMDIE
threads are already frozen by the time oom_killer_disable() is called.
If the freezer does not unfreeze TIF_MEMDIE threads, oom_killer_disable()
does not need to wait for TIF_MEMDIE threads.

Since CONFIG_MMU=y kernels have the OOM reaper, we can reclaim memory
without unfreezing TIF_MEMDIE threads. Even if memory cannot be
reclaimed (e.g. CONFIG_MMU=n), as long as freeze operation is using
timeout, OOM livelock will disappear eventually.

I think that nobody is testing situations where oom_killer_disable()
needs to wait for TIF_MEMDIE threads to call exit_oom_victim().
Therefore, by relying on timeout for freeze operation, this patch
stops unfreezing TIF_MEMDIE threads.

Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Cc: Rafael J. Wysocki <rjw@rjwysocki.net>
Cc: Pavel Machek <pavel@ucw.cz>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Michal Hocko <mhocko@suse.com>
---
 include/linux/oom.h |  2 +-
 kernel/freezer.c    |  3 ---
 mm/oom_kill.c       | 32 +-------------------------------
 3 files changed, 2 insertions(+), 35 deletions(-)

Comments

Michal Hocko March 29, 2018, 2:50 p.m. UTC | #1
On Thu 29-03-18 23:36:58, Tetsuo Handa wrote:
> Currently, mark_oom_victim() calls __thaw_task() on the OOM victim
> threads and freezing_slow_path() unfreezes the OOM victim thread.
> But I think this exceptional behavior makes little sense nowadays.

Well, I would like to see this happen because it would allow more
changes on top. E.g. get rid of TIF_MEMDIE finally. But I am not really
sure we are there yet. OOM reaper is useful tool but it still cannot
help in some cases (shared memory, a lot of metadata allocated on behalf
of the process etc...). Considering that the freezing can be an
unprivileged operation (think cgroup freezer) then I am worried that
one container can cause the global oom killer and hide oom victims to
the fridge and spill over to other containers. Maybe I am overly
paranoid and this scenario is not even all that interesting but I would
like to hear a better justification which explains all these cases
rather than "we have oom reaper so we are good to go" rationale.
Tetsuo Handa March 29, 2018, 3:52 p.m. UTC | #2
Michal Hocko wrote:
> On Thu 29-03-18 23:36:58, Tetsuo Handa wrote:
> > Currently, mark_oom_victim() calls __thaw_task() on the OOM victim
> > threads and freezing_slow_path() unfreezes the OOM victim thread.
> > But I think this exceptional behavior makes little sense nowadays.
> 
> Well, I would like to see this happen because it would allow more
> changes on top. E.g. get rid of TIF_MEMDIE finally.

I'm planning to change mark_oom_victim(tsk) to set TIF_MEMDIE only if
tsk == current. That is, "do not set TIF_MEMDIE on remote thread", for
setting TIF_MEMDIE on a thread which might not be doing memory allocation
is not helpful. Setting TIF_MEMDIE on current thread via
task_will_free_mem(current) in out_of_memory() path is always helpful
because current thread is exactly doing memory allocation.

>                                                     But I am not really
> sure we are there yet. OOM reaper is useful tool but it still cannot
> help in some cases (shared memory, a lot of metadata allocated on behalf
> of the process etc...).

I consider the OOM reaper as a useful tool for give up waiting for the OOM
victims after 1 second. Reclaiming memory is optional.

>                         Considering that the freezing can be an
> unprivileged operation (think cgroup freezer) then I am worried that
> one container can cause the global oom killer and hide oom victims to
> the fridge and spill over to other containers.

The OOM reaper will give up after 1 second. What is wrong with keeping
TIF_MEMDIE threads frozen? How does that differ from TIF_MEMDIE threads
being stuck at unkillable waits (e.g. i_mmap_lock_write()).

My understanding is that frozen threads are not holding locks. In this
aspect, frozen TIF_MEMDIE threads are less painful than TIF_MEMDIE threads
being stuck at unkillable waits.

>                                                Maybe I am overly
> paranoid and this scenario is not even all that interesting but I would
> like to hear a better justification which explains all these cases
> rather than "we have oom reaper so we are good to go" rationale.

I'm trying to simplify situations where oom_killer_disable() is called.
You are worrying about situations where oom_killer_disable() is not
called, aren't you?
kernel test robot March 30, 2018, 3:16 p.m. UTC | #3
Hi Tetsuo,

I love your patch! Yet something to improve:

[auto build test ERROR on linus/master]
[also build test ERROR on v4.16-rc7 next-20180329]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Tetsuo-Handa/mm-oom-Do-not-unfreeze-OOM-victim-thread/20180330-215548
config: x86_64-acpi-redef (attached as .config)
compiler: gcc-7 (Debian 7.3.0-1) 7.3.0
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

All errors (new ones prefixed by >>):

   kernel/power/process.c: In function 'freeze_processes':
>> kernel/power/process.c:154:17: error: too many arguments to function 'oom_killer_disable'
     if (!error && !oom_killer_disable(msecs_to_jiffies(freeze_timeout_msecs)))
                    ^~~~~~~~~~~~~~~~~~
   In file included from kernel/power/process.c:13:0:
   include/linux/oom.h:109:13: note: declared here
    extern bool oom_killer_disable(void);
                ^~~~~~~~~~~~~~~~~~

vim +/oom_killer_disable +154 kernel/power/process.c

6161b2ce8 Pavel Machek      2005-09-03  115  
11b2ce2ba Rafael J. Wysocki 2006-12-06  116  /**
2aede851d Rafael J. Wysocki 2011-09-26  117   * freeze_processes - Signal user space processes to enter the refrigerator.
2b44c4db2 Colin Cross       2013-07-24  118   * The current thread will not be frozen.  The same process that calls
2b44c4db2 Colin Cross       2013-07-24  119   * freeze_processes must later call thaw_processes.
03afed8bc Tejun Heo         2011-11-21  120   *
03afed8bc Tejun Heo         2011-11-21  121   * On success, returns 0.  On failure, -errno and system is fully thawed.
11b2ce2ba Rafael J. Wysocki 2006-12-06  122   */
11b2ce2ba Rafael J. Wysocki 2006-12-06  123  int freeze_processes(void)
11b2ce2ba Rafael J. Wysocki 2006-12-06  124  {
e7cd8a722 Rafael J. Wysocki 2007-07-19  125  	int error;
11b2ce2ba Rafael J. Wysocki 2006-12-06  126  
247bc0374 Rafael J. Wysocki 2012-03-28  127  	error = __usermodehelper_disable(UMH_FREEZING);
1e73203cd Rafael J. Wysocki 2012-03-28  128  	if (error)
1e73203cd Rafael J. Wysocki 2012-03-28  129  		return error;
1e73203cd Rafael J. Wysocki 2012-03-28  130  
2b44c4db2 Colin Cross       2013-07-24  131  	/* Make sure this task doesn't get frozen */
2b44c4db2 Colin Cross       2013-07-24  132  	current->flags |= PF_SUSPEND_TASK;
2b44c4db2 Colin Cross       2013-07-24  133  
a3201227f Tejun Heo         2011-11-21  134  	if (!pm_freezing)
a3201227f Tejun Heo         2011-11-21  135  		atomic_inc(&system_freezing_cnt);
a3201227f Tejun Heo         2011-11-21  136  
33e4f80ee Rafael J. Wysocki 2017-06-12  137  	pm_wakeup_clear(true);
35536ae17 Michal Hocko      2015-02-11  138  	pr_info("Freezing user space processes ... ");
a3201227f Tejun Heo         2011-11-21  139  	pm_freezing = true;
ebb12db51 Rafael J. Wysocki 2008-06-11  140  	error = try_to_freeze_tasks(true);
2aede851d Rafael J. Wysocki 2011-09-26  141  	if (!error) {
247bc0374 Rafael J. Wysocki 2012-03-28  142  		__usermodehelper_set_disable_depth(UMH_DISABLED);
35536ae17 Michal Hocko      2015-02-11  143  		pr_cont("done.");
2aede851d Rafael J. Wysocki 2011-09-26  144  	}
35536ae17 Michal Hocko      2015-02-11  145  	pr_cont("\n");
2aede851d Rafael J. Wysocki 2011-09-26  146  	BUG_ON(in_atomic());
2aede851d Rafael J. Wysocki 2011-09-26  147  
c32b3cbe0 Michal Hocko      2015-02-11  148  	/*
c32b3cbe0 Michal Hocko      2015-02-11  149  	 * Now that the whole userspace is frozen we need to disbale
c32b3cbe0 Michal Hocko      2015-02-11  150  	 * the OOM killer to disallow any further interference with
7d2e7a22c Michal Hocko      2016-10-07  151  	 * killable tasks. There is no guarantee oom victims will
7d2e7a22c Michal Hocko      2016-10-07  152  	 * ever reach a point they go away we have to wait with a timeout.
c32b3cbe0 Michal Hocko      2015-02-11  153  	 */
7d2e7a22c Michal Hocko      2016-10-07 @154  	if (!error && !oom_killer_disable(msecs_to_jiffies(freeze_timeout_msecs)))
c32b3cbe0 Michal Hocko      2015-02-11  155  		error = -EBUSY;
c32b3cbe0 Michal Hocko      2015-02-11  156  
03afed8bc Tejun Heo         2011-11-21  157  	if (error)
03afed8bc Tejun Heo         2011-11-21  158  		thaw_processes();
2aede851d Rafael J. Wysocki 2011-09-26  159  	return error;
2aede851d Rafael J. Wysocki 2011-09-26  160  }
2aede851d Rafael J. Wysocki 2011-09-26  161  

:::::: The code at line 154 was first introduced by commit
:::::: 7d2e7a22cf27e7569e6816ccc05dd74248048b30 oom, suspend: fix oom_killer_disable vs. pm suspend properly

:::::: TO: Michal Hocko <mhocko@suse.com>
:::::: CC: Linus Torvalds <torvalds@linux-foundation.org>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
kernel test robot March 30, 2018, 3:43 p.m. UTC | #4
Hi Tetsuo,

I love your patch! Perhaps something to improve:

[auto build test WARNING on linus/master]
[also build test WARNING on v4.16-rc7 next-20180329]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Tetsuo-Handa/mm-oom-Do-not-unfreeze-OOM-victim-thread/20180330-215548
reproduce:
        # apt-get install sparse
        make ARCH=x86_64 allmodconfig
        make C=1 CF=-D__CHECK_ENDIAN__


sparse warnings: (new ones prefixed by >>)

>> kernel/power/process.c:154:42: sparse: too many arguments for function oom_killer_disable
   kernel/power/process.c: In function 'freeze_processes':
   kernel/power/process.c:154:17: error: too many arguments to function 'oom_killer_disable'
     if (!error && !oom_killer_disable(msecs_to_jiffies(freeze_timeout_msecs)))
                    ^~~~~~~~~~~~~~~~~~
   In file included from kernel/power/process.c:13:0:
   include/linux/oom.h:109:13: note: declared here
    extern bool oom_killer_disable(void);
                ^~~~~~~~~~~~~~~~~~

vim +154 kernel/power/process.c

6161b2ce8 Pavel Machek      2005-09-03  115  
11b2ce2ba Rafael J. Wysocki 2006-12-06  116  /**
2aede851d Rafael J. Wysocki 2011-09-26  117   * freeze_processes - Signal user space processes to enter the refrigerator.
2b44c4db2 Colin Cross       2013-07-24  118   * The current thread will not be frozen.  The same process that calls
2b44c4db2 Colin Cross       2013-07-24  119   * freeze_processes must later call thaw_processes.
03afed8bc Tejun Heo         2011-11-21  120   *
03afed8bc Tejun Heo         2011-11-21  121   * On success, returns 0.  On failure, -errno and system is fully thawed.
11b2ce2ba Rafael J. Wysocki 2006-12-06  122   */
11b2ce2ba Rafael J. Wysocki 2006-12-06  123  int freeze_processes(void)
11b2ce2ba Rafael J. Wysocki 2006-12-06  124  {
e7cd8a722 Rafael J. Wysocki 2007-07-19  125  	int error;
11b2ce2ba Rafael J. Wysocki 2006-12-06  126  
247bc0374 Rafael J. Wysocki 2012-03-28  127  	error = __usermodehelper_disable(UMH_FREEZING);
1e73203cd Rafael J. Wysocki 2012-03-28  128  	if (error)
1e73203cd Rafael J. Wysocki 2012-03-28  129  		return error;
1e73203cd Rafael J. Wysocki 2012-03-28  130  
2b44c4db2 Colin Cross       2013-07-24  131  	/* Make sure this task doesn't get frozen */
2b44c4db2 Colin Cross       2013-07-24  132  	current->flags |= PF_SUSPEND_TASK;
2b44c4db2 Colin Cross       2013-07-24  133  
a3201227f Tejun Heo         2011-11-21  134  	if (!pm_freezing)
a3201227f Tejun Heo         2011-11-21  135  		atomic_inc(&system_freezing_cnt);
a3201227f Tejun Heo         2011-11-21  136  
33e4f80ee Rafael J. Wysocki 2017-06-12  137  	pm_wakeup_clear(true);
35536ae17 Michal Hocko      2015-02-11  138  	pr_info("Freezing user space processes ... ");
a3201227f Tejun Heo         2011-11-21  139  	pm_freezing = true;
ebb12db51 Rafael J. Wysocki 2008-06-11  140  	error = try_to_freeze_tasks(true);
2aede851d Rafael J. Wysocki 2011-09-26  141  	if (!error) {
247bc0374 Rafael J. Wysocki 2012-03-28  142  		__usermodehelper_set_disable_depth(UMH_DISABLED);
35536ae17 Michal Hocko      2015-02-11  143  		pr_cont("done.");
2aede851d Rafael J. Wysocki 2011-09-26  144  	}
35536ae17 Michal Hocko      2015-02-11  145  	pr_cont("\n");
2aede851d Rafael J. Wysocki 2011-09-26  146  	BUG_ON(in_atomic());
2aede851d Rafael J. Wysocki 2011-09-26  147  
c32b3cbe0 Michal Hocko      2015-02-11  148  	/*
c32b3cbe0 Michal Hocko      2015-02-11  149  	 * Now that the whole userspace is frozen we need to disbale
c32b3cbe0 Michal Hocko      2015-02-11  150  	 * the OOM killer to disallow any further interference with
7d2e7a22c Michal Hocko      2016-10-07  151  	 * killable tasks. There is no guarantee oom victims will
7d2e7a22c Michal Hocko      2016-10-07  152  	 * ever reach a point they go away we have to wait with a timeout.
c32b3cbe0 Michal Hocko      2015-02-11  153  	 */
7d2e7a22c Michal Hocko      2016-10-07 @154  	if (!error && !oom_killer_disable(msecs_to_jiffies(freeze_timeout_msecs)))
c32b3cbe0 Michal Hocko      2015-02-11  155  		error = -EBUSY;
c32b3cbe0 Michal Hocko      2015-02-11  156  
03afed8bc Tejun Heo         2011-11-21  157  	if (error)
03afed8bc Tejun Heo         2011-11-21  158  		thaw_processes();
2aede851d Rafael J. Wysocki 2011-09-26  159  	return error;
2aede851d Rafael J. Wysocki 2011-09-26  160  }
2aede851d Rafael J. Wysocki 2011-09-26  161  

:::::: The code at line 154 was first introduced by commit
:::::: 7d2e7a22cf27e7569e6816ccc05dd74248048b30 oom, suspend: fix oom_killer_disable vs. pm suspend properly

:::::: TO: Michal Hocko <mhocko@suse.com>
:::::: CC: Linus Torvalds <torvalds@linux-foundation.org>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
kernel test robot March 30, 2018, 3:44 p.m. UTC | #5
Hi Tetsuo,

I love your patch! Perhaps something to improve:

[auto build test WARNING on linus/master]
[also build test WARNING on v4.16-rc7 next-20180329]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Tetsuo-Handa/mm-oom-Do-not-unfreeze-OOM-victim-thread/20180330-215548
config: i386-randconfig-s1-201812 (attached as .config)
compiler: gcc-6 (Debian 6.4.0-9) 6.4.0 20171026
reproduce:
        # save the attached .config to linux build tree
        make ARCH=i386 

All warnings (new ones prefixed by >>):

   In file included from include/linux/kernel.h:10:0,
                    from include/linux/interrupt.h:6,
                    from kernel/power/process.c:12:
   kernel/power/process.c: In function 'freeze_processes':
   kernel/power/process.c:154:17: error: too many arguments to function 'oom_killer_disable'
     if (!error && !oom_killer_disable(msecs_to_jiffies(freeze_timeout_msecs)))
                    ^
   include/linux/compiler.h:58:30: note: in definition of macro '__trace_if'
     if (__builtin_constant_p(!!(cond)) ? !!(cond) :   \
                                 ^~~~
>> kernel/power/process.c:154:2: note: in expansion of macro 'if'
     if (!error && !oom_killer_disable(msecs_to_jiffies(freeze_timeout_msecs)))
     ^~
   In file included from kernel/power/process.c:13:0:
   include/linux/oom.h:109:13: note: declared here
    extern bool oom_killer_disable(void);
                ^~~~~~~~~~~~~~~~~~
   In file included from include/linux/kernel.h:10:0,
                    from include/linux/interrupt.h:6,
                    from kernel/power/process.c:12:
   kernel/power/process.c:154:17: error: too many arguments to function 'oom_killer_disable'
     if (!error && !oom_killer_disable(msecs_to_jiffies(freeze_timeout_msecs)))
                    ^
   include/linux/compiler.h:58:42: note: in definition of macro '__trace_if'
     if (__builtin_constant_p(!!(cond)) ? !!(cond) :   \
                                             ^~~~
>> kernel/power/process.c:154:2: note: in expansion of macro 'if'
     if (!error && !oom_killer_disable(msecs_to_jiffies(freeze_timeout_msecs)))
     ^~
   In file included from kernel/power/process.c:13:0:
   include/linux/oom.h:109:13: note: declared here
    extern bool oom_killer_disable(void);
                ^~~~~~~~~~~~~~~~~~
   In file included from include/linux/kernel.h:10:0,
                    from include/linux/interrupt.h:6,
                    from kernel/power/process.c:12:
   kernel/power/process.c:154:17: error: too many arguments to function 'oom_killer_disable'
     if (!error && !oom_killer_disable(msecs_to_jiffies(freeze_timeout_msecs)))
                    ^
   include/linux/compiler.h:69:16: note: in definition of macro '__trace_if'
      ______r = !!(cond);     \
                   ^~~~
>> kernel/power/process.c:154:2: note: in expansion of macro 'if'
     if (!error && !oom_killer_disable(msecs_to_jiffies(freeze_timeout_msecs)))
     ^~
   In file included from kernel/power/process.c:13:0:
   include/linux/oom.h:109:13: note: declared here
    extern bool oom_killer_disable(void);
                ^~~~~~~~~~~~~~~~~~

vim +/if +154 kernel/power/process.c

^1da177e4c Linus Torvalds    2005-04-16   11  
^1da177e4c Linus Torvalds    2005-04-16  @12  #include <linux/interrupt.h>
1a8670a29b Alexey Dobriyan   2009-09-21   13  #include <linux/oom.h>
^1da177e4c Linus Torvalds    2005-04-16   14  #include <linux/suspend.h>
^1da177e4c Linus Torvalds    2005-04-16   15  #include <linux/module.h>
b17b01533b Ingo Molnar       2017-02-08   16  #include <linux/sched/debug.h>
299300258d Ingo Molnar       2017-02-08   17  #include <linux/sched/task.h>
02aaeb9b95 Rafael J. Wysocki 2006-03-23   18  #include <linux/syscalls.h>
7dfb71030f Nigel Cunningham  2006-12-06   19  #include <linux/freezer.h>
be404f0212 Tejun Heo         2009-10-08   20  #include <linux/delay.h>
a0a1a5fd4f Tejun Heo         2010-06-29   21  #include <linux/workqueue.h>
1e73203cd1 Rafael J. Wysocki 2012-03-28   22  #include <linux/kmod.h>
bb3632c610 Todd E Brandt     2014-06-06   23  #include <trace/events/power.h>
50e7663233 Peter Zijlstra    2017-09-07   24  #include <linux/cpuset.h>
^1da177e4c Linus Torvalds    2005-04-16   25  
^1da177e4c Linus Torvalds    2005-04-16   26  /*
^1da177e4c Linus Torvalds    2005-04-16   27   * Timeout for stopping processes
^1da177e4c Linus Torvalds    2005-04-16   28   */
957d1282bb Li Fei            2013-02-01   29  unsigned int __read_mostly freeze_timeout_msecs = 20 * MSEC_PER_SEC;
^1da177e4c Linus Torvalds    2005-04-16   30  
839e3407d9 Tejun Heo         2011-11-21   31  static int try_to_freeze_tasks(bool user_only)
^1da177e4c Linus Torvalds    2005-04-16   32  {
^1da177e4c Linus Torvalds    2005-04-16   33  	struct task_struct *g, *p;
11b2ce2ba9 Rafael J. Wysocki 2006-12-06   34  	unsigned long end_time;
11b2ce2ba9 Rafael J. Wysocki 2006-12-06   35  	unsigned int todo;
a0a1a5fd4f Tejun Heo         2010-06-29   36  	bool wq_busy = false;
f7b382b988 Abhilash Jindal   2016-01-31   37  	ktime_t start, end, elapsed;
18ad0c6297 Colin Cross       2013-05-06   38  	unsigned int elapsed_msecs;
dbeeec5fe8 Rafael J. Wysocki 2010-10-04   39  	bool wakeup = false;
18ad0c6297 Colin Cross       2013-05-06   40  	int sleep_usecs = USEC_PER_MSEC;
438e2ce68d Rafael J. Wysocki 2007-10-18   41  
f7b382b988 Abhilash Jindal   2016-01-31   42  	start = ktime_get_boottime();
^1da177e4c Linus Torvalds    2005-04-16   43  
957d1282bb Li Fei            2013-02-01   44  	end_time = jiffies + msecs_to_jiffies(freeze_timeout_msecs);
a0a1a5fd4f Tejun Heo         2010-06-29   45  
839e3407d9 Tejun Heo         2011-11-21   46  	if (!user_only)
a0a1a5fd4f Tejun Heo         2010-06-29   47  		freeze_workqueues_begin();
a0a1a5fd4f Tejun Heo         2010-06-29   48  
be404f0212 Tejun Heo         2009-10-08   49  	while (true) {
11b2ce2ba9 Rafael J. Wysocki 2006-12-06   50  		todo = 0;
^1da177e4c Linus Torvalds    2005-04-16   51  		read_lock(&tasklist_lock);
a28e785a9f Michal Hocko      2014-10-21   52  		for_each_process_thread(g, p) {
839e3407d9 Tejun Heo         2011-11-21   53  			if (p == current || !freeze_task(p))
11b2ce2ba9 Rafael J. Wysocki 2006-12-06   54  				continue;
d5d8c5976d Rafael J. Wysocki 2007-10-18   55  
5d8f72b55c Oleg Nesterov     2012-10-26   56  			if (!freezer_should_skip(p))
11b2ce2ba9 Rafael J. Wysocki 2006-12-06   57  				todo++;
a28e785a9f Michal Hocko      2014-10-21   58  		}
^1da177e4c Linus Torvalds    2005-04-16   59  		read_unlock(&tasklist_lock);
a0a1a5fd4f Tejun Heo         2010-06-29   60  
839e3407d9 Tejun Heo         2011-11-21   61  		if (!user_only) {
a0a1a5fd4f Tejun Heo         2010-06-29   62  			wq_busy = freeze_workqueues_busy();
a0a1a5fd4f Tejun Heo         2010-06-29   63  			todo += wq_busy;
a0a1a5fd4f Tejun Heo         2010-06-29   64  		}
a0a1a5fd4f Tejun Heo         2010-06-29   65  
be404f0212 Tejun Heo         2009-10-08   66  		if (!todo || time_after(jiffies, end_time))
6161b2ce81 Pavel Machek      2005-09-03   67  			break;
be404f0212 Tejun Heo         2009-10-08   68  
a2867e08c8 Rafael J. Wysocki 2010-12-03   69  		if (pm_wakeup_pending()) {
dbeeec5fe8 Rafael J. Wysocki 2010-10-04   70  			wakeup = true;
dbeeec5fe8 Rafael J. Wysocki 2010-10-04   71  			break;
dbeeec5fe8 Rafael J. Wysocki 2010-10-04   72  		}
dbeeec5fe8 Rafael J. Wysocki 2010-10-04   73  
be404f0212 Tejun Heo         2009-10-08   74  		/*
be404f0212 Tejun Heo         2009-10-08   75  		 * We need to retry, but first give the freezing tasks some
18ad0c6297 Colin Cross       2013-05-06   76  		 * time to enter the refrigerator.  Start with an initial
18ad0c6297 Colin Cross       2013-05-06   77  		 * 1 ms sleep followed by exponential backoff until 8 ms.
be404f0212 Tejun Heo         2009-10-08   78  		 */
18ad0c6297 Colin Cross       2013-05-06   79  		usleep_range(sleep_usecs / 2, sleep_usecs);
18ad0c6297 Colin Cross       2013-05-06   80  		if (sleep_usecs < 8 * USEC_PER_MSEC)
18ad0c6297 Colin Cross       2013-05-06   81  			sleep_usecs *= 2;
be404f0212 Tejun Heo         2009-10-08   82  	}
^1da177e4c Linus Torvalds    2005-04-16   83  
f7b382b988 Abhilash Jindal   2016-01-31   84  	end = ktime_get_boottime();
f7b382b988 Abhilash Jindal   2016-01-31   85  	elapsed = ktime_sub(end, start);
f7b382b988 Abhilash Jindal   2016-01-31   86  	elapsed_msecs = ktime_to_ms(elapsed);
438e2ce68d Rafael J. Wysocki 2007-10-18   87  
11b2ce2ba9 Rafael J. Wysocki 2006-12-06   88  	if (todo) {
35536ae170 Michal Hocko      2015-02-11   89  		pr_cont("\n");
35536ae170 Michal Hocko      2015-02-11   90  		pr_err("Freezing of tasks %s after %d.%03d seconds "
a0a1a5fd4f Tejun Heo         2010-06-29   91  		       "(%d tasks refusing to freeze, wq_busy=%d):\n",
dbeeec5fe8 Rafael J. Wysocki 2010-10-04   92  		       wakeup ? "aborted" : "failed",
18ad0c6297 Colin Cross       2013-05-06   93  		       elapsed_msecs / 1000, elapsed_msecs % 1000,
a0a1a5fd4f Tejun Heo         2010-06-29   94  		       todo - wq_busy, wq_busy);
a0a1a5fd4f Tejun Heo         2010-06-29   95  
7b776af66d Roger Lu          2016-07-01   96  		if (wq_busy)
7b776af66d Roger Lu          2016-07-01   97  			show_workqueue_state();
7b776af66d Roger Lu          2016-07-01   98  
6c83b4818d Rafael J. Wysocki 2012-02-11   99  		if (!wakeup) {
6161b2ce81 Pavel Machek      2005-09-03  100  			read_lock(&tasklist_lock);
a28e785a9f Michal Hocko      2014-10-21  101  			for_each_process_thread(g, p) {
6c83b4818d Rafael J. Wysocki 2012-02-11  102  				if (p != current && !freezer_should_skip(p)
6c83b4818d Rafael J. Wysocki 2012-02-11  103  				    && freezing(p) && !frozen(p))
4f598458ea Xiaotian Feng     2010-03-10  104  					sched_show_task(p);
a28e785a9f Michal Hocko      2014-10-21  105  			}
6161b2ce81 Pavel Machek      2005-09-03  106  			read_unlock(&tasklist_lock);
6c83b4818d Rafael J. Wysocki 2012-02-11  107  		}
438e2ce68d Rafael J. Wysocki 2007-10-18  108  	} else {
35536ae170 Michal Hocko      2015-02-11  109  		pr_cont("(elapsed %d.%03d seconds) ", elapsed_msecs / 1000,
18ad0c6297 Colin Cross       2013-05-06  110  			elapsed_msecs % 1000);
11b2ce2ba9 Rafael J. Wysocki 2006-12-06  111  	}
11b2ce2ba9 Rafael J. Wysocki 2006-12-06  112  
e7cd8a7227 Rafael J. Wysocki 2007-07-19  113  	return todo ? -EBUSY : 0;
6161b2ce81 Pavel Machek      2005-09-03  114  }
6161b2ce81 Pavel Machek      2005-09-03  115  
11b2ce2ba9 Rafael J. Wysocki 2006-12-06  116  /**
2aede851dd Rafael J. Wysocki 2011-09-26  117   * freeze_processes - Signal user space processes to enter the refrigerator.
2b44c4db2e Colin Cross       2013-07-24  118   * The current thread will not be frozen.  The same process that calls
2b44c4db2e Colin Cross       2013-07-24  119   * freeze_processes must later call thaw_processes.
03afed8bc2 Tejun Heo         2011-11-21  120   *
03afed8bc2 Tejun Heo         2011-11-21  121   * On success, returns 0.  On failure, -errno and system is fully thawed.
11b2ce2ba9 Rafael J. Wysocki 2006-12-06  122   */
11b2ce2ba9 Rafael J. Wysocki 2006-12-06  123  int freeze_processes(void)
11b2ce2ba9 Rafael J. Wysocki 2006-12-06  124  {
e7cd8a7227 Rafael J. Wysocki 2007-07-19  125  	int error;
11b2ce2ba9 Rafael J. Wysocki 2006-12-06  126  
247bc03742 Rafael J. Wysocki 2012-03-28  127  	error = __usermodehelper_disable(UMH_FREEZING);
1e73203cd1 Rafael J. Wysocki 2012-03-28  128  	if (error)
1e73203cd1 Rafael J. Wysocki 2012-03-28  129  		return error;
1e73203cd1 Rafael J. Wysocki 2012-03-28  130  
2b44c4db2e Colin Cross       2013-07-24  131  	/* Make sure this task doesn't get frozen */
2b44c4db2e Colin Cross       2013-07-24  132  	current->flags |= PF_SUSPEND_TASK;
2b44c4db2e Colin Cross       2013-07-24  133  
a3201227f8 Tejun Heo         2011-11-21  134  	if (!pm_freezing)
a3201227f8 Tejun Heo         2011-11-21  135  		atomic_inc(&system_freezing_cnt);
a3201227f8 Tejun Heo         2011-11-21  136  
33e4f80ee6 Rafael J. Wysocki 2017-06-12  137  	pm_wakeup_clear(true);
35536ae170 Michal Hocko      2015-02-11  138  	pr_info("Freezing user space processes ... ");
a3201227f8 Tejun Heo         2011-11-21  139  	pm_freezing = true;
ebb12db51f Rafael J. Wysocki 2008-06-11  140  	error = try_to_freeze_tasks(true);
2aede851dd Rafael J. Wysocki 2011-09-26  141  	if (!error) {
247bc03742 Rafael J. Wysocki 2012-03-28  142  		__usermodehelper_set_disable_depth(UMH_DISABLED);
35536ae170 Michal Hocko      2015-02-11  143  		pr_cont("done.");
2aede851dd Rafael J. Wysocki 2011-09-26  144  	}
35536ae170 Michal Hocko      2015-02-11  145  	pr_cont("\n");
2aede851dd Rafael J. Wysocki 2011-09-26  146  	BUG_ON(in_atomic());
2aede851dd Rafael J. Wysocki 2011-09-26  147  
c32b3cbe0d Michal Hocko      2015-02-11  148  	/*
c32b3cbe0d Michal Hocko      2015-02-11  149  	 * Now that the whole userspace is frozen we need to disbale
c32b3cbe0d Michal Hocko      2015-02-11  150  	 * the OOM killer to disallow any further interference with
7d2e7a22cf Michal Hocko      2016-10-07  151  	 * killable tasks. There is no guarantee oom victims will
7d2e7a22cf Michal Hocko      2016-10-07  152  	 * ever reach a point they go away we have to wait with a timeout.
c32b3cbe0d Michal Hocko      2015-02-11  153  	 */
7d2e7a22cf Michal Hocko      2016-10-07 @154  	if (!error && !oom_killer_disable(msecs_to_jiffies(freeze_timeout_msecs)))
c32b3cbe0d Michal Hocko      2015-02-11  155  		error = -EBUSY;
c32b3cbe0d Michal Hocko      2015-02-11  156  
03afed8bc2 Tejun Heo         2011-11-21  157  	if (error)
03afed8bc2 Tejun Heo         2011-11-21  158  		thaw_processes();
2aede851dd Rafael J. Wysocki 2011-09-26  159  	return error;
2aede851dd Rafael J. Wysocki 2011-09-26  160  }
2aede851dd Rafael J. Wysocki 2011-09-26  161  

:::::: The code at line 154 was first introduced by commit
:::::: 7d2e7a22cf27e7569e6816ccc05dd74248048b30 oom, suspend: fix oom_killer_disable vs. pm suspend properly

:::::: TO: Michal Hocko <mhocko@suse.com>
:::::: CC: Linus Torvalds <torvalds@linux-foundation.org>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
diff mbox

Patch

diff --git a/include/linux/oom.h b/include/linux/oom.h
index d4d41c0..a9ac384 100644
--- a/include/linux/oom.h
+++ b/include/linux/oom.h
@@ -114,7 +114,7 @@  extern unsigned long oom_badness(struct task_struct *p,
 extern int register_oom_notifier(struct notifier_block *nb);
 extern int unregister_oom_notifier(struct notifier_block *nb);
 
-extern bool oom_killer_disable(signed long timeout);
+extern bool oom_killer_disable(void);
 extern void oom_killer_enable(void);
 
 extern struct task_struct *find_lock_task_mm(struct task_struct *p);
diff --git a/kernel/freezer.c b/kernel/freezer.c
index 6f56a9e..969cae4 100644
--- a/kernel/freezer.c
+++ b/kernel/freezer.c
@@ -42,9 +42,6 @@  bool freezing_slow_path(struct task_struct *p)
 	if (p->flags & (PF_NOFREEZE | PF_SUSPEND_TASK))
 		return false;
 
-	if (test_tsk_thread_flag(p, TIF_MEMDIE))
-		return false;
-
 	if (pm_nosig_freezing || cgroup_freezing(p))
 		return true;
 
diff --git a/mm/oom_kill.c b/mm/oom_kill.c
index dfd3705..ebb7d75 100644
--- a/mm/oom_kill.c
+++ b/mm/oom_kill.c
@@ -441,12 +441,6 @@  static void dump_header(struct oom_control *oc, struct task_struct *p)
 		dump_tasks(oc->memcg, oc->nodemask);
 }
 
-/*
- * Number of OOM victims in flight
- */
-static atomic_t oom_victims = ATOMIC_INIT(0);
-static DECLARE_WAIT_QUEUE_HEAD(oom_victims_wait);
-
 static bool oom_killer_disabled __read_mostly;
 
 #define K(x) ((x) << (PAGE_SHIFT-10))
@@ -674,7 +668,6 @@  static void mark_oom_victim(struct task_struct *tsk)
 {
 	struct mm_struct *mm = tsk->mm;
 
-	WARN_ON(oom_killer_disabled);
 	/* OOM killer might race with memcg OOM */
 	if (test_and_set_tsk_thread_flag(tsk, TIF_MEMDIE))
 		return;
@@ -685,14 +678,6 @@  static void mark_oom_victim(struct task_struct *tsk)
 		set_bit(MMF_OOM_VICTIM, &mm->flags);
 	}
 
-	/*
-	 * Make sure that the task is woken up from uninterruptible sleep
-	 * if it is frozen because OOM killer wouldn't be able to free
-	 * any memory and livelock. freezing_slow_path will tell the freezer
-	 * that TIF_MEMDIE tasks should be ignored.
-	 */
-	__thaw_task(tsk);
-	atomic_inc(&oom_victims);
 	trace_mark_victim(tsk->pid);
 }
 
@@ -702,9 +687,6 @@  static void mark_oom_victim(struct task_struct *tsk)
 void exit_oom_victim(void)
 {
 	clear_thread_flag(TIF_MEMDIE);
-
-	if (!atomic_dec_return(&oom_victims))
-		wake_up_all(&oom_victims_wait);
 }
 
 /**
@@ -721,8 +703,6 @@  void oom_killer_enable(void)
  * @timeout: maximum timeout to wait for oom victims in jiffies
  *
  * Forces all page allocations to fail rather than trigger OOM killer.
- * Will block and wait until all OOM victims are killed or the given
- * timeout expires.
  *
  * The function cannot be called when there are runnable user tasks because
  * the userspace would see unexpected allocation failures as a result. Any
@@ -731,10 +711,8 @@  void oom_killer_enable(void)
  * Returns true if successful and false if the OOM killer cannot be
  * disabled.
  */
-bool oom_killer_disable(signed long timeout)
+bool oom_killer_disable(void)
 {
-	signed long ret;
-
 	/*
 	 * Make sure to not race with an ongoing OOM killer. Check that the
 	 * current is not killed (possibly due to sharing the victim's memory).
@@ -743,15 +721,7 @@  bool oom_killer_disable(signed long timeout)
 		return false;
 	oom_killer_disabled = true;
 	mutex_unlock(&oom_lock);
-
-	ret = wait_event_interruptible_timeout(oom_victims_wait,
-			!atomic_read(&oom_victims), timeout);
-	if (ret <= 0) {
-		oom_killer_enable();
-		return false;
-	}
 	pr_info("OOM killer disabled.\n");
-
 	return true;
 }