diff options
Diffstat (limited to 'kernel/padata.c')
-rw-r--r-- | kernel/padata.c | 57 |
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 | ||
35 | static int padata_index_to_cpu(struct parallel_data *pd, int cpu_index) | 36 | static 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 | ||
46 | static int padata_cpu_hash(struct padata_priv *padata) | 47 | static 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); | |||
173 | static struct padata_priv *padata_get_next(struct parallel_data *pd) | 170 | static 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 | ||
231 | static void padata_reorder(struct parallel_data *pd) | 218 | static 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 */ |
401 | static void padata_init_pqueues(struct parallel_data *pd) | 390 | static 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); | |||
580 | static bool padata_validate_cpumask(struct padata_instance *pinst, | 566 | static 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; |