aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/padata.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/padata.c')
-rw-r--r--kernel/padata.c57
1 files changed, 23 insertions, 34 deletions
diff --git a/kernel/padata.c b/kernel/padata.c
index b45259931512..89fe3d1b9efb 100644
--- a/kernel/padata.c
+++ b/kernel/padata.c
@@ -1,6 +1,8 @@
1/* 1/*
2 * padata.c - generic interface to process data streams in parallel 2 * padata.c - generic interface to process data streams in parallel
3 * 3 *
4 * See Documentation/padata.txt for an api documentation.
5 *
4 * Copyright (C) 2008, 2009 secunet Security Networks AG 6 * Copyright (C) 2008, 2009 secunet Security Networks AG
5 * Copyright (C) 2008, 2009 Steffen Klassert <steffen.klassert@secunet.com> 7 * Copyright (C) 2008, 2009 Steffen Klassert <steffen.klassert@secunet.com>
6 * 8 *
@@ -29,7 +31,6 @@
29#include <linux/sysfs.h> 31#include <linux/sysfs.h>
30#include <linux/rcupdate.h> 32#include <linux/rcupdate.h>
31 33
32#define MAX_SEQ_NR (INT_MAX - NR_CPUS)
33#define MAX_OBJ_NUM 1000 34#define MAX_OBJ_NUM 1000
34 35
35static int padata_index_to_cpu(struct parallel_data *pd, int cpu_index) 36static int padata_index_to_cpu(struct parallel_data *pd, int cpu_index)
@@ -43,18 +44,19 @@ static int padata_index_to_cpu(struct parallel_data *pd, int cpu_index)
43 return target_cpu; 44 return target_cpu;
44} 45}
45 46
46static int padata_cpu_hash(struct padata_priv *padata) 47static int padata_cpu_hash(struct parallel_data *pd)
47{ 48{
48 int cpu_index; 49 int cpu_index;
49 struct parallel_data *pd;
50
51 pd = padata->pd;
52 50
53 /* 51 /*
54 * Hash the sequence numbers to the cpus by taking 52 * Hash the sequence numbers to the cpus by taking
55 * seq_nr mod. number of cpus in use. 53 * seq_nr mod. number of cpus in use.
56 */ 54 */
57 cpu_index = padata->seq_nr % cpumask_weight(pd->cpumask.pcpu); 55
56 spin_lock(&pd->seq_lock);
57 cpu_index = pd->seq_nr % cpumask_weight(pd->cpumask.pcpu);
58 pd->seq_nr++;
59 spin_unlock(&pd->seq_lock);
58 60
59 return padata_index_to_cpu(pd, cpu_index); 61 return padata_index_to_cpu(pd, cpu_index);
60} 62}
@@ -132,12 +134,7 @@ int padata_do_parallel(struct padata_instance *pinst,
132 padata->pd = pd; 134 padata->pd = pd;
133 padata->cb_cpu = cb_cpu; 135 padata->cb_cpu = cb_cpu;
134 136
135 if (unlikely(atomic_read(&pd->seq_nr) == pd->max_seq_nr)) 137 target_cpu = padata_cpu_hash(pd);
136 atomic_set(&pd->seq_nr, -1);
137
138 padata->seq_nr = atomic_inc_return(&pd->seq_nr);
139
140 target_cpu = padata_cpu_hash(padata);
141 queue = per_cpu_ptr(pd->pqueue, target_cpu); 138 queue = per_cpu_ptr(pd->pqueue, target_cpu);
142 139
143 spin_lock(&queue->parallel.lock); 140 spin_lock(&queue->parallel.lock);
@@ -173,7 +170,7 @@ EXPORT_SYMBOL(padata_do_parallel);
173static struct padata_priv *padata_get_next(struct parallel_data *pd) 170static struct padata_priv *padata_get_next(struct parallel_data *pd)
174{ 171{
175 int cpu, num_cpus; 172 int cpu, num_cpus;
176 int next_nr, next_index; 173 unsigned int next_nr, next_index;
177 struct padata_parallel_queue *queue, *next_queue; 174 struct padata_parallel_queue *queue, *next_queue;
178 struct padata_priv *padata; 175 struct padata_priv *padata;
179 struct padata_list *reorder; 176 struct padata_list *reorder;
@@ -189,14 +186,6 @@ static struct padata_priv *padata_get_next(struct parallel_data *pd)
189 cpu = padata_index_to_cpu(pd, next_index); 186 cpu = padata_index_to_cpu(pd, next_index);
190 next_queue = per_cpu_ptr(pd->pqueue, cpu); 187 next_queue = per_cpu_ptr(pd->pqueue, cpu);
191 188
192 if (unlikely(next_nr > pd->max_seq_nr)) {
193 next_nr = next_nr - pd->max_seq_nr - 1;
194 next_index = next_nr % num_cpus;
195 cpu = padata_index_to_cpu(pd, next_index);
196 next_queue = per_cpu_ptr(pd->pqueue, cpu);
197 pd->processed = 0;
198 }
199
200 padata = NULL; 189 padata = NULL;
201 190
202 reorder = &next_queue->reorder; 191 reorder = &next_queue->reorder;
@@ -205,8 +194,6 @@ static struct padata_priv *padata_get_next(struct parallel_data *pd)
205 padata = list_entry(reorder->list.next, 194 padata = list_entry(reorder->list.next,
206 struct padata_priv, list); 195 struct padata_priv, list);
207 196
208 BUG_ON(next_nr != padata->seq_nr);
209
210 spin_lock(&reorder->lock); 197 spin_lock(&reorder->lock);
211 list_del_init(&padata->list); 198 list_del_init(&padata->list);
212 atomic_dec(&pd->reorder_objects); 199 atomic_dec(&pd->reorder_objects);
@@ -230,6 +217,7 @@ out:
230 217
231static void padata_reorder(struct parallel_data *pd) 218static void padata_reorder(struct parallel_data *pd)
232{ 219{
220 int cb_cpu;
233 struct padata_priv *padata; 221 struct padata_priv *padata;
234 struct padata_serial_queue *squeue; 222 struct padata_serial_queue *squeue;
235 struct padata_instance *pinst = pd->pinst; 223 struct padata_instance *pinst = pd->pinst;
@@ -270,13 +258,14 @@ static void padata_reorder(struct parallel_data *pd)
270 return; 258 return;
271 } 259 }
272 260
273 squeue = per_cpu_ptr(pd->squeue, padata->cb_cpu); 261 cb_cpu = padata->cb_cpu;
262 squeue = per_cpu_ptr(pd->squeue, cb_cpu);
274 263
275 spin_lock(&squeue->serial.lock); 264 spin_lock(&squeue->serial.lock);
276 list_add_tail(&padata->list, &squeue->serial.list); 265 list_add_tail(&padata->list, &squeue->serial.list);
277 spin_unlock(&squeue->serial.lock); 266 spin_unlock(&squeue->serial.lock);
278 267
279 queue_work_on(padata->cb_cpu, pinst->wq, &squeue->work); 268 queue_work_on(cb_cpu, pinst->wq, &squeue->work);
280 } 269 }
281 270
282 spin_unlock_bh(&pd->lock); 271 spin_unlock_bh(&pd->lock);
@@ -367,13 +356,13 @@ static int padata_setup_cpumasks(struct parallel_data *pd,
367 if (!alloc_cpumask_var(&pd->cpumask.pcpu, GFP_KERNEL)) 356 if (!alloc_cpumask_var(&pd->cpumask.pcpu, GFP_KERNEL))
368 return -ENOMEM; 357 return -ENOMEM;
369 358
370 cpumask_and(pd->cpumask.pcpu, pcpumask, cpu_active_mask); 359 cpumask_and(pd->cpumask.pcpu, pcpumask, cpu_online_mask);
371 if (!alloc_cpumask_var(&pd->cpumask.cbcpu, GFP_KERNEL)) { 360 if (!alloc_cpumask_var(&pd->cpumask.cbcpu, GFP_KERNEL)) {
372 free_cpumask_var(pd->cpumask.cbcpu); 361 free_cpumask_var(pd->cpumask.cbcpu);
373 return -ENOMEM; 362 return -ENOMEM;
374 } 363 }
375 364
376 cpumask_and(pd->cpumask.cbcpu, cbcpumask, cpu_active_mask); 365 cpumask_and(pd->cpumask.cbcpu, cbcpumask, cpu_online_mask);
377 return 0; 366 return 0;
378} 367}
379 368
@@ -400,7 +389,7 @@ static void padata_init_squeues(struct parallel_data *pd)
400/* Initialize all percpu queues used by parallel workers */ 389/* Initialize all percpu queues used by parallel workers */
401static void padata_init_pqueues(struct parallel_data *pd) 390static void padata_init_pqueues(struct parallel_data *pd)
402{ 391{
403 int cpu_index, num_cpus, cpu; 392 int cpu_index, cpu;
404 struct padata_parallel_queue *pqueue; 393 struct padata_parallel_queue *pqueue;
405 394
406 cpu_index = 0; 395 cpu_index = 0;
@@ -415,9 +404,6 @@ static void padata_init_pqueues(struct parallel_data *pd)
415 INIT_WORK(&pqueue->work, padata_parallel_worker); 404 INIT_WORK(&pqueue->work, padata_parallel_worker);
416 atomic_set(&pqueue->num_obj, 0); 405 atomic_set(&pqueue->num_obj, 0);
417 } 406 }
418
419 num_cpus = cpumask_weight(pd->cpumask.pcpu);
420 pd->max_seq_nr = num_cpus ? (MAX_SEQ_NR / num_cpus) * num_cpus - 1 : 0;
421} 407}
422 408
423/* Allocate and initialize the internal cpumask dependend resources. */ 409/* Allocate and initialize the internal cpumask dependend resources. */
@@ -444,7 +430,7 @@ static struct parallel_data *padata_alloc_pd(struct padata_instance *pinst,
444 padata_init_pqueues(pd); 430 padata_init_pqueues(pd);
445 padata_init_squeues(pd); 431 padata_init_squeues(pd);
446 setup_timer(&pd->timer, padata_reorder_timer, (unsigned long)pd); 432 setup_timer(&pd->timer, padata_reorder_timer, (unsigned long)pd);
447 atomic_set(&pd->seq_nr, -1); 433 pd->seq_nr = 0;
448 atomic_set(&pd->reorder_objects, 0); 434 atomic_set(&pd->reorder_objects, 0);
449 atomic_set(&pd->refcnt, 0); 435 atomic_set(&pd->refcnt, 0);
450 pd->pinst = pinst; 436 pd->pinst = pinst;
@@ -580,7 +566,7 @@ EXPORT_SYMBOL(padata_unregister_cpumask_notifier);
580static bool padata_validate_cpumask(struct padata_instance *pinst, 566static bool padata_validate_cpumask(struct padata_instance *pinst,
581 const struct cpumask *cpumask) 567 const struct cpumask *cpumask)
582{ 568{
583 if (!cpumask_intersects(cpumask, cpu_active_mask)) { 569 if (!cpumask_intersects(cpumask, cpu_online_mask)) {
584 pinst->flags |= PADATA_INVALID; 570 pinst->flags |= PADATA_INVALID;
585 return false; 571 return false;
586 } 572 }
@@ -694,7 +680,7 @@ static int __padata_add_cpu(struct padata_instance *pinst, int cpu)
694{ 680{
695 struct parallel_data *pd; 681 struct parallel_data *pd;
696 682
697 if (cpumask_test_cpu(cpu, cpu_active_mask)) { 683 if (cpumask_test_cpu(cpu, cpu_online_mask)) {
698 pd = padata_alloc_pd(pinst, pinst->cpumask.pcpu, 684 pd = padata_alloc_pd(pinst, pinst->cpumask.pcpu,
699 pinst->cpumask.cbcpu); 685 pinst->cpumask.cbcpu);
700 if (!pd) 686 if (!pd)
@@ -762,6 +748,9 @@ static int __padata_remove_cpu(struct padata_instance *pinst, int cpu)
762 return -ENOMEM; 748 return -ENOMEM;
763 749
764 padata_replace(pinst, pd); 750 padata_replace(pinst, pd);
751
752 cpumask_clear_cpu(cpu, pd->cpumask.cbcpu);
753 cpumask_clear_cpu(cpu, pd->cpumask.pcpu);
765 } 754 }
766 755
767 return 0; 756 return 0;