aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/padata.c
diff options
context:
space:
mode:
authorSteffen Klassert <steffen.klassert@secunet.com>2010-07-20 02:49:20 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2010-07-26 02:13:58 -0400
commitb89661dff525a46edb7ee8a4423b5212068c05c0 (patch)
tree06f669f3efe74d37a546b8e75b3a5bd142a6a41f /kernel/padata.c
parentfad3a906d324c02b3c25ef51f702384154089846 (diff)
padata: Allocate cpumask dependend recources in any case
The cpumask separation work assumes the cpumask dependend recources present regardless of valid or invalid cpumasks. With this patch we allocate the cpumask dependend recources in any case. This fixes two NULL pointer dereference crashes in padata_replace and in padata_get_cpumask. Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'kernel/padata.c')
-rw-r--r--kernel/padata.c24
1 files changed, 7 insertions, 17 deletions
diff --git a/kernel/padata.c b/kernel/padata.c
index 4287868bbe37..6a519454a5bd 100644
--- a/kernel/padata.c
+++ b/kernel/padata.c
@@ -417,7 +417,7 @@ static void padata_init_pqueues(struct parallel_data *pd)
417 } 417 }
418 418
419 num_cpus = cpumask_weight(pd->cpumask.pcpu); 419 num_cpus = cpumask_weight(pd->cpumask.pcpu);
420 pd->max_seq_nr = (MAX_SEQ_NR / num_cpus) * num_cpus - 1; 420 pd->max_seq_nr = num_cpus ? (MAX_SEQ_NR / num_cpus) * num_cpus - 1 : 0;
421} 421}
422 422
423/* Allocate and initialize the internal cpumask dependend resources. */ 423/* Allocate and initialize the internal cpumask dependend resources. */
@@ -527,21 +527,19 @@ static void padata_replace(struct padata_instance *pinst,
527 rcu_assign_pointer(pinst->pd, pd_new); 527 rcu_assign_pointer(pinst->pd, pd_new);
528 528
529 synchronize_rcu(); 529 synchronize_rcu();
530 if (!pd_old)
531 goto out;
532 530
533 padata_flush_queues(pd_old);
534 if (!cpumask_equal(pd_old->cpumask.pcpu, pd_new->cpumask.pcpu)) 531 if (!cpumask_equal(pd_old->cpumask.pcpu, pd_new->cpumask.pcpu))
535 notification_mask |= PADATA_CPU_PARALLEL; 532 notification_mask |= PADATA_CPU_PARALLEL;
536 if (!cpumask_equal(pd_old->cpumask.cbcpu, pd_new->cpumask.cbcpu)) 533 if (!cpumask_equal(pd_old->cpumask.cbcpu, pd_new->cpumask.cbcpu))
537 notification_mask |= PADATA_CPU_SERIAL; 534 notification_mask |= PADATA_CPU_SERIAL;
538 535
536 padata_flush_queues(pd_old);
539 padata_free_pd(pd_old); 537 padata_free_pd(pd_old);
538
540 if (notification_mask) 539 if (notification_mask)
541 blocking_notifier_call_chain(&pinst->cpumask_change_notifier, 540 blocking_notifier_call_chain(&pinst->cpumask_change_notifier,
542 notification_mask, pinst); 541 notification_mask, pinst);
543 542
544out:
545 pinst->flags &= ~PADATA_RESET; 543 pinst->flags &= ~PADATA_RESET;
546} 544}
547 545
@@ -673,6 +671,7 @@ int __padata_set_cpumasks(struct padata_instance *pinst,
673 struct parallel_data *pd = NULL; 671 struct parallel_data *pd = NULL;
674 672
675 mutex_lock(&pinst->lock); 673 mutex_lock(&pinst->lock);
674 get_online_cpus();
676 675
677 valid = padata_validate_cpumask(pinst, pcpumask); 676 valid = padata_validate_cpumask(pinst, pcpumask);
678 if (!valid) { 677 if (!valid) {
@@ -681,20 +680,16 @@ int __padata_set_cpumasks(struct padata_instance *pinst,
681 } 680 }
682 681
683 valid = padata_validate_cpumask(pinst, cbcpumask); 682 valid = padata_validate_cpumask(pinst, cbcpumask);
684 if (!valid) { 683 if (!valid)
685 __padata_stop(pinst); 684 __padata_stop(pinst);
686 goto out_replace;
687 }
688
689 get_online_cpus();
690 685
686out_replace:
691 pd = padata_alloc_pd(pinst, pcpumask, cbcpumask); 687 pd = padata_alloc_pd(pinst, pcpumask, cbcpumask);
692 if (!pd) { 688 if (!pd) {
693 err = -ENOMEM; 689 err = -ENOMEM;
694 goto out; 690 goto out;
695 } 691 }
696 692
697out_replace:
698 cpumask_copy(pinst->cpumask.pcpu, pcpumask); 693 cpumask_copy(pinst->cpumask.pcpu, pcpumask);
699 cpumask_copy(pinst->cpumask.cbcpu, cbcpumask); 694 cpumask_copy(pinst->cpumask.cbcpu, cbcpumask);
700 695
@@ -705,7 +700,6 @@ out_replace:
705 700
706out: 701out:
707 put_online_cpus(); 702 put_online_cpus();
708
709 mutex_unlock(&pinst->lock); 703 mutex_unlock(&pinst->lock);
710 704
711 return err; 705 return err;
@@ -776,11 +770,8 @@ static int __padata_remove_cpu(struct padata_instance *pinst, int cpu)
776 if (cpumask_test_cpu(cpu, cpu_online_mask)) { 770 if (cpumask_test_cpu(cpu, cpu_online_mask)) {
777 771
778 if (!padata_validate_cpumask(pinst, pinst->cpumask.pcpu) || 772 if (!padata_validate_cpumask(pinst, pinst->cpumask.pcpu) ||
779 !padata_validate_cpumask(pinst, pinst->cpumask.cbcpu)) { 773 !padata_validate_cpumask(pinst, pinst->cpumask.cbcpu))
780 __padata_stop(pinst); 774 __padata_stop(pinst);
781 padata_replace(pinst, pd);
782 goto out;
783 }
784 775
785 pd = padata_alloc_pd(pinst, pinst->cpumask.pcpu, 776 pd = padata_alloc_pd(pinst, pinst->cpumask.pcpu,
786 pinst->cpumask.cbcpu); 777 pinst->cpumask.cbcpu);
@@ -790,7 +781,6 @@ static int __padata_remove_cpu(struct padata_instance *pinst, int cpu)
790 padata_replace(pinst, pd); 781 padata_replace(pinst, pd);
791 } 782 }
792 783
793out:
794 return 0; 784 return 0;
795} 785}
796 786