diff options
| -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 | ||
