summaryrefslogtreecommitdiff
path: root/kernel/workqueue.c
diff options
context:
space:
mode:
authorAlex Shi <alex.shi@linaro.org>2016-03-14 15:16:14 +0800
committerAlex Shi <alex.shi@linaro.org>2016-03-14 15:16:14 +0800
commit258181e60ef13001b0ae05cb58079fd79ed86a46 (patch)
tree47f570c84bf6b67d18b300812173f2782ee32379 /kernel/workqueue.c
parent12a08707dec7ff067688710aee0d4698f6da98a6 (diff)
parent62e21959dc6f25c5fce0c1a0934e4a9d982bf99b (diff)
Merge tag 'v4.4.5' into linux-linaro-lsk-v4.4
This is the 4.4.5 stable release
Diffstat (limited to 'kernel/workqueue.c')
-rw-r--r--kernel/workqueue.c18
1 files changed, 14 insertions, 4 deletions
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index c579dbab2e36..450c21fd0e6e 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -568,6 +568,16 @@ static struct pool_workqueue *unbound_pwq_by_node(struct workqueue_struct *wq,
int node)
{
assert_rcu_or_wq_mutex_or_pool_mutex(wq);
+
+ /*
+ * XXX: @node can be NUMA_NO_NODE if CPU goes offline while a
+ * delayed item is pending. The plan is to keep CPU -> NODE
+ * mapping valid and stable across CPU on/offlines. Once that
+ * happens, this workaround can be removed.
+ */
+ if (unlikely(node == NUMA_NO_NODE))
+ return wq->dfl_pwq;
+
return rcu_dereference_raw(wq->numa_pwq_tbl[node]);
}
@@ -1458,13 +1468,13 @@ static void __queue_delayed_work(int cpu, struct workqueue_struct *wq,
timer_stats_timer_set_start_info(&dwork->timer);
dwork->wq = wq;
- /* timer isn't guaranteed to run in this cpu, record earlier */
- if (cpu == WORK_CPU_UNBOUND)
- cpu = raw_smp_processor_id();
dwork->cpu = cpu;
timer->expires = jiffies + delay;
- add_timer_on(timer, cpu);
+ if (unlikely(cpu != WORK_CPU_UNBOUND))
+ add_timer_on(timer, cpu);
+ else
+ add_timer(timer);
}
/**