diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/padata.c | 24 |
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 | ||
544 | out: | ||
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 | ||
686 | out_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 | ||
697 | out_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 | ||
706 | out: | 701 | out: |
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 | ||
793 | out: | ||
794 | return 0; | 784 | return 0; |
795 | } | 785 | } |
796 | 786 | ||