diff options
| author | Ajay Nandakumar <anandakumarm@nvidia.com> | 2013-12-16 19:11:53 +0530 |
|---|---|---|
| committer | Ajay Nandakumar <anandakumarm@nvidia.com> | 2013-12-16 19:11:53 +0530 |
| commit | 4186e42658f8f3e95fa4f87f917872e8a3431057 (patch) | |
| tree | 88d96f1893b395c38c246e79e75cbcf088678441 /kernel/workqueue.c | |
| parent | 6bbaea6ef1c82c1d4a94b655ecf2e2b08164545f (diff) | |
| parent | 05bcf8f867f4af11c93395d4a6dd1dd52d8904ea (diff) | |
Merge tag 'v3.10.24' into HEAD
This is the 3.10.24 stable release
Change-Id: Ibd2734f93d44385ab86867272a1359158635133b
Diffstat (limited to 'kernel/workqueue.c')
| -rw-r--r-- | kernel/workqueue.c | 24 |
1 files changed, 22 insertions, 2 deletions
diff --git a/kernel/workqueue.c b/kernel/workqueue.c index e52d002d3893..68086a34b8ef 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -295,6 +295,9 @@ static DEFINE_HASHTABLE(unbound_pool_hash, UNBOUND_POOL_HASH_ORDER); /* I: attributes used when instantiating standard unbound pools on demand */ static struct workqueue_attrs *unbound_std_wq_attrs[NR_STD_WORKER_POOLS]; +/* I: attributes used when instantiating ordered pools on demand */ +static struct workqueue_attrs *ordered_wq_attrs[NR_STD_WORKER_POOLS]; + struct workqueue_struct *system_wq __read_mostly; EXPORT_SYMBOL(system_wq); struct workqueue_struct *system_highpri_wq __read_mostly; @@ -4059,7 +4062,7 @@ out_unlock: static int alloc_and_link_pwqs(struct workqueue_struct *wq) { bool highpri = wq->flags & WQ_HIGHPRI; - int cpu; + int cpu, ret; if (!(wq->flags & WQ_UNBOUND)) { wq->cpu_pwqs = alloc_percpu(struct pool_workqueue); @@ -4079,6 +4082,13 @@ static int alloc_and_link_pwqs(struct workqueue_struct *wq) mutex_unlock(&wq->mutex); } return 0; + } else if (wq->flags & __WQ_ORDERED) { + ret = apply_workqueue_attrs(wq, ordered_wq_attrs[highpri]); + /* there should only be single pwq for ordering guarantee */ + WARN(!ret && (wq->pwqs.next != &wq->dfl_pwq->pwqs_node || + wq->pwqs.prev != &wq->dfl_pwq->pwqs_node), + "ordering guarantee broken for workqueue %s\n", wq->name); + return ret; } else { return apply_workqueue_attrs(wq, unbound_std_wq_attrs[highpri]); } @@ -4990,13 +5000,23 @@ static int __init init_workqueues(void) } } - /* create default unbound wq attrs */ + /* create default unbound and ordered wq attrs */ for (i = 0; i < NR_STD_WORKER_POOLS; i++) { struct workqueue_attrs *attrs; BUG_ON(!(attrs = alloc_workqueue_attrs(GFP_KERNEL))); attrs->nice = std_nice[i]; unbound_std_wq_attrs[i] = attrs; + + /* + * An ordered wq should have only one pwq as ordering is + * guaranteed by max_active which is enforced by pwqs. + * Turn off NUMA so that dfl_pwq is used for all nodes. + */ + BUG_ON(!(attrs = alloc_workqueue_attrs(GFP_KERNEL))); + attrs->nice = std_nice[i]; + attrs->no_numa = true; + ordered_wq_attrs[i] = attrs; } system_wq = alloc_workqueue("events", 0, 0); |
