Skip to content

Commit 51cd2d2

Browse files
Lai Jiangshanhtejun
authored andcommitted
workqueue: Process extra works in rescuer on memory pressure
Make the rescuer process more work on the last pwq when there are no more to rescue for the whole workqueue to help the regular workers in case it is a temporary memory pressure relief and to reduce relapse. Signed-off-by: Lai Jiangshan <[email protected]> Signed-off-by: Tejun Heo <[email protected]>
1 parent e5a30c3 commit 51cd2d2

1 file changed

Lines changed: 29 additions & 2 deletions

File tree

kernel/workqueue.c

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3461,10 +3461,37 @@ static bool assign_rescuer_work(struct pool_workqueue *pwq, struct worker *rescu
34613461
struct work_struct *cursor = &pwq->mayday_cursor;
34623462
struct work_struct *work, *n;
34633463

3464-
/* need rescue? */
3465-
if (!pwq->nr_active || !need_to_create_worker(pool))
3464+
/* have work items to rescue? */
3465+
if (!pwq->nr_active)
34663466
return false;
34673467

3468+
/* need rescue? */
3469+
if (!need_to_create_worker(pool)) {
3470+
/*
3471+
* The pool has idle workers and doesn't need the rescuer, so it
3472+
* could simply return false here.
3473+
*
3474+
* However, the memory pressure might not be fully relieved.
3475+
* In PERCPU pool with concurrency enabled, having idle workers
3476+
* does not necessarily mean memory pressure is gone; it may
3477+
* simply mean regular workers have woken up, completed their
3478+
* work, and gone idle again due to concurrency limits.
3479+
*
3480+
* In this case, those working workers may later sleep again,
3481+
* the pool may run out of idle workers, and it will have to
3482+
* allocate new ones and wait for the timer to send mayday,
3483+
* causing unnecessary delay - especially if memory pressure
3484+
* was never resolved throughout.
3485+
*
3486+
* Do more work if memory pressure is still on to reduce
3487+
* relapse, using (pool->flags & POOL_MANAGER_ACTIVE), though
3488+
* not precisely, unless there are other PWQs needing help.
3489+
*/
3490+
if (!(pool->flags & POOL_MANAGER_ACTIVE) ||
3491+
!list_empty(&pwq->wq->maydays))
3492+
return false;
3493+
}
3494+
34683495
/* search from the start or cursor if available */
34693496
if (list_empty(&cursor->entry))
34703497
work = list_first_entry(&pool->worklist, struct work_struct, entry);

0 commit comments

Comments
 (0)