Commit b89661dff525a46edb7ee8a4423b5212068c05c0
Committed by
Herbert Xu
1 parent
fad3a906d3
Exists in
master
and in
4 other branches
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>
Showing 1 changed file with 7 additions and 17 deletions Side-by-side Diff
kernel/padata.c
... | ... | @@ -417,7 +417,7 @@ |
417 | 417 | } |
418 | 418 | |
419 | 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 | 423 | /* Allocate and initialize the internal cpumask dependend resources. */ |
424 | 424 | |
425 | 425 | |
426 | 426 | |
427 | 427 | |
... | ... | @@ -527,21 +527,19 @@ |
527 | 527 | rcu_assign_pointer(pinst->pd, pd_new); |
528 | 528 | |
529 | 529 | synchronize_rcu(); |
530 | - if (!pd_old) | |
531 | - goto out; | |
532 | 530 | |
533 | - padata_flush_queues(pd_old); | |
534 | 531 | if (!cpumask_equal(pd_old->cpumask.pcpu, pd_new->cpumask.pcpu)) |
535 | 532 | notification_mask |= PADATA_CPU_PARALLEL; |
536 | 533 | if (!cpumask_equal(pd_old->cpumask.cbcpu, pd_new->cpumask.cbcpu)) |
537 | 534 | notification_mask |= PADATA_CPU_SERIAL; |
538 | 535 | |
536 | + padata_flush_queues(pd_old); | |
539 | 537 | padata_free_pd(pd_old); |
538 | + | |
540 | 539 | if (notification_mask) |
541 | 540 | blocking_notifier_call_chain(&pinst->cpumask_change_notifier, |
542 | 541 | notification_mask, pinst); |
543 | 542 | |
544 | -out: | |
545 | 543 | pinst->flags &= ~PADATA_RESET; |
546 | 544 | } |
547 | 545 | |
... | ... | @@ -673,6 +671,7 @@ |
673 | 671 | struct parallel_data *pd = NULL; |
674 | 672 | |
675 | 673 | mutex_lock(&pinst->lock); |
674 | + get_online_cpus(); | |
676 | 675 | |
677 | 676 | valid = padata_validate_cpumask(pinst, pcpumask); |
678 | 677 | if (!valid) { |
679 | 678 | |
680 | 679 | |
681 | 680 | |
... | ... | @@ -681,20 +680,16 @@ |
681 | 680 | } |
682 | 681 | |
683 | 682 | valid = padata_validate_cpumask(pinst, cbcpumask); |
684 | - if (!valid) { | |
683 | + if (!valid) | |
685 | 684 | __padata_stop(pinst); |
686 | - goto out_replace; | |
687 | - } | |
688 | 685 | |
689 | - get_online_cpus(); | |
690 | - | |
686 | +out_replace: | |
691 | 687 | pd = padata_alloc_pd(pinst, pcpumask, cbcpumask); |
692 | 688 | if (!pd) { |
693 | 689 | err = -ENOMEM; |
694 | 690 | goto out; |
695 | 691 | } |
696 | 692 | |
697 | -out_replace: | |
698 | 693 | cpumask_copy(pinst->cpumask.pcpu, pcpumask); |
699 | 694 | cpumask_copy(pinst->cpumask.cbcpu, cbcpumask); |
700 | 695 | |
... | ... | @@ -705,7 +700,6 @@ |
705 | 700 | |
706 | 701 | out: |
707 | 702 | put_online_cpus(); |
708 | - | |
709 | 703 | mutex_unlock(&pinst->lock); |
710 | 704 | |
711 | 705 | return err; |
712 | 706 | |
... | ... | @@ -776,11 +770,8 @@ |
776 | 770 | if (cpumask_test_cpu(cpu, cpu_online_mask)) { |
777 | 771 | |
778 | 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 | 774 | __padata_stop(pinst); |
781 | - padata_replace(pinst, pd); | |
782 | - goto out; | |
783 | - } | |
784 | 775 | |
785 | 776 | pd = padata_alloc_pd(pinst, pinst->cpumask.pcpu, |
786 | 777 | pinst->cpumask.cbcpu); |
... | ... | @@ -790,7 +781,6 @@ |
790 | 781 | padata_replace(pinst, pd); |
791 | 782 | } |
792 | 783 | |
793 | -out: | |
794 | 784 | return 0; |
795 | 785 | } |
796 | 786 |