mirror of
https://github.com/Fishwaldo/linux-bl808.git
synced 2025-06-17 20:25:19 +00:00
workqueue: reimplement workqueue freeze using max_active
Currently, workqueue freezing is implemented by marking the worker freezeable and calling try_to_freeze() from dispatch loop. Reimplement it using cwq->limit so that the workqueue is frozen instead of the worker. * workqueue_struct->saved_max_active is added which stores the specified max_active on initialization. * On freeze, all cwq->max_active's are quenched to zero. Freezing is complete when nr_active on all cwqs reach zero. * On thaw, all cwq->max_active's are restored to wq->saved_max_active and the worklist is repopulated. This new implementation allows having single shared pool of workers per cpu. Signed-off-by: Tejun Heo <tj@kernel.org>
This commit is contained in:
parent
1e19ffc63d
commit
a0a1a5fd4f
3 changed files with 179 additions and 12 deletions
|
@ -15,6 +15,7 @@
|
|||
#include <linux/syscalls.h>
|
||||
#include <linux/freezer.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/workqueue.h>
|
||||
|
||||
/*
|
||||
* Timeout for stopping processes
|
||||
|
@ -35,6 +36,7 @@ static int try_to_freeze_tasks(bool sig_only)
|
|||
struct task_struct *g, *p;
|
||||
unsigned long end_time;
|
||||
unsigned int todo;
|
||||
bool wq_busy = false;
|
||||
struct timeval start, end;
|
||||
u64 elapsed_csecs64;
|
||||
unsigned int elapsed_csecs;
|
||||
|
@ -42,6 +44,10 @@ static int try_to_freeze_tasks(bool sig_only)
|
|||
do_gettimeofday(&start);
|
||||
|
||||
end_time = jiffies + TIMEOUT;
|
||||
|
||||
if (!sig_only)
|
||||
freeze_workqueues_begin();
|
||||
|
||||
while (true) {
|
||||
todo = 0;
|
||||
read_lock(&tasklist_lock);
|
||||
|
@ -63,6 +69,12 @@ static int try_to_freeze_tasks(bool sig_only)
|
|||
todo++;
|
||||
} while_each_thread(g, p);
|
||||
read_unlock(&tasklist_lock);
|
||||
|
||||
if (!sig_only) {
|
||||
wq_busy = freeze_workqueues_busy();
|
||||
todo += wq_busy;
|
||||
}
|
||||
|
||||
if (!todo || time_after(jiffies, end_time))
|
||||
break;
|
||||
|
||||
|
@ -86,8 +98,12 @@ static int try_to_freeze_tasks(bool sig_only)
|
|||
*/
|
||||
printk("\n");
|
||||
printk(KERN_ERR "Freezing of tasks failed after %d.%02d seconds "
|
||||
"(%d tasks refusing to freeze):\n",
|
||||
elapsed_csecs / 100, elapsed_csecs % 100, todo);
|
||||
"(%d tasks refusing to freeze, wq_busy=%d):\n",
|
||||
elapsed_csecs / 100, elapsed_csecs % 100,
|
||||
todo - wq_busy, wq_busy);
|
||||
|
||||
thaw_workqueues();
|
||||
|
||||
read_lock(&tasklist_lock);
|
||||
do_each_thread(g, p) {
|
||||
task_lock(p);
|
||||
|
@ -157,6 +173,7 @@ void thaw_processes(void)
|
|||
oom_killer_enable();
|
||||
|
||||
printk("Restarting tasks ... ");
|
||||
thaw_workqueues();
|
||||
thaw_tasks(true);
|
||||
thaw_tasks(false);
|
||||
schedule();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue