Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 365527
b: refs/heads/master
c: 7dbc725
h: refs/heads/master
i:
  365525: 0db8151
  365523: c0da3ba
  365519: 0bc4787
v: v3
  • Loading branch information
Tejun Heo committed Mar 19, 2013
1 parent 4659bea commit 96dfe00
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 6 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: a9ab775bcadf122d91e1a201eb66ae2eec90365a
refs/heads/master: 7dbc725e4749d822eb6dc962526049af1586f041
52 changes: 47 additions & 5 deletions trunk/kernel/workqueue.c
Original file line number Diff line number Diff line change
Expand Up @@ -4131,6 +4131,39 @@ static void rebind_workers(struct worker_pool *pool)
spin_unlock_irq(&pool->lock);
}

/**
* restore_unbound_workers_cpumask - restore cpumask of unbound workers
* @pool: unbound pool of interest
* @cpu: the CPU which is coming up
*
* An unbound pool may end up with a cpumask which doesn't have any online
* CPUs. When a worker of such pool get scheduled, the scheduler resets
* its cpus_allowed. If @cpu is in @pool's cpumask which didn't have any
* online CPU before, cpus_allowed of all its workers should be restored.
*/
static void restore_unbound_workers_cpumask(struct worker_pool *pool, int cpu)
{
static cpumask_t cpumask;
struct worker *worker;
int wi;

lockdep_assert_held(&pool->manager_mutex);

/* is @cpu allowed for @pool? */
if (!cpumask_test_cpu(cpu, pool->attrs->cpumask))
return;

/* is @cpu the only online CPU? */
cpumask_and(&cpumask, pool->attrs->cpumask, cpu_online_mask);
if (cpumask_weight(&cpumask) != 1)
return;

/* as we're called from CPU_ONLINE, the following shouldn't fail */
for_each_pool_worker(worker, wi, pool)
WARN_ON_ONCE(set_cpus_allowed_ptr(worker->task,
pool->attrs->cpumask) < 0);
}

/*
* Workqueues should be brought up before normal priority CPU notifiers.
* This will be registered high priority CPU notifier.
Expand All @@ -4141,6 +4174,7 @@ static int __cpuinit workqueue_cpu_up_callback(struct notifier_block *nfb,
{
int cpu = (unsigned long)hcpu;
struct worker_pool *pool;
int pi;

switch (action & ~CPU_TASKS_FROZEN) {
case CPU_UP_PREPARE:
Expand All @@ -4154,17 +4188,25 @@ static int __cpuinit workqueue_cpu_up_callback(struct notifier_block *nfb,

case CPU_DOWN_FAILED:
case CPU_ONLINE:
for_each_cpu_worker_pool(pool, cpu) {
mutex_lock(&wq_mutex);

for_each_pool(pool, pi) {
mutex_lock(&pool->manager_mutex);

spin_lock_irq(&pool->lock);
pool->flags &= ~POOL_DISASSOCIATED;
spin_unlock_irq(&pool->lock);
if (pool->cpu == cpu) {
spin_lock_irq(&pool->lock);
pool->flags &= ~POOL_DISASSOCIATED;
spin_unlock_irq(&pool->lock);

rebind_workers(pool);
rebind_workers(pool);
} else if (pool->cpu < 0) {
restore_unbound_workers_cpumask(pool, cpu);
}

mutex_unlock(&pool->manager_mutex);
}

mutex_unlock(&wq_mutex);
break;
}
return NOTIFY_OK;
Expand Down

0 comments on commit 96dfe00

Please sign in to comment.