diff options
author | Kirill Tkhai <ktkhai@virtuozzo.com> | 2018-03-19 11:32:10 -0400 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2018-03-19 12:38:50 -0400 |
commit | f52ba1fef7b92e74d58efef8eae7b6f48c6d218d (patch) | |
tree | be3bfd5e52ea11827506db4397dcd29e9dd6a83e | |
parent | 71546d100422bcc2c543dadeb9328728997cd23a (diff) |
mm: Allow to kill tasks doing pcpu_alloc() and waiting for pcpu_balance_workfn()
In case of memory deficit and low percpu memory pages,
pcpu_balance_workfn() takes pcpu_alloc_mutex for a long
time (as it makes memory allocations itself and waits
for memory reclaim). If tasks doing pcpu_alloc() are
choosen by OOM killer, they can't exit, because they
are waiting for the mutex.
The patch makes pcpu_alloc() to care about killing signal
and use mutex_lock_killable(), when it's allowed by GFP
flags. This guarantees, a task does not miss SIGKILL
from OOM killer.
Signed-off-by: Kirill Tkhai <ktkhai@virtuozzo.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
-rw-r--r-- | mm/percpu.c | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/mm/percpu.c b/mm/percpu.c index 15a398c00791..9297098519a6 100644 --- a/mm/percpu.c +++ b/mm/percpu.c | |||
@@ -1373,8 +1373,17 @@ static void __percpu *pcpu_alloc(size_t size, size_t align, bool reserved, | |||
1373 | return NULL; | 1373 | return NULL; |
1374 | } | 1374 | } |
1375 | 1375 | ||
1376 | if (!is_atomic) | 1376 | if (!is_atomic) { |
1377 | mutex_lock(&pcpu_alloc_mutex); | 1377 | /* |
1378 | * pcpu_balance_workfn() allocates memory under this mutex, | ||
1379 | * and it may wait for memory reclaim. Allow current task | ||
1380 | * to become OOM victim, in case of memory pressure. | ||
1381 | */ | ||
1382 | if (gfp & __GFP_NOFAIL) | ||
1383 | mutex_lock(&pcpu_alloc_mutex); | ||
1384 | else if (mutex_lock_killable(&pcpu_alloc_mutex)) | ||
1385 | return NULL; | ||
1386 | } | ||
1378 | 1387 | ||
1379 | spin_lock_irqsave(&pcpu_lock, flags); | 1388 | spin_lock_irqsave(&pcpu_lock, flags); |
1380 | 1389 | ||