diff options
author | Rusty Russell <rusty@rustcorp.com.au> | 2009-01-11 00:58:09 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-01-11 13:13:06 -0500 |
commit | 4595f9620cda8a1e973588e743cf5f8436dd20c6 (patch) | |
tree | 98a47cff17f58262979c7d04590cb3ffc0deead9 /arch/x86/xen/enlighten.c | |
parent | 802bf931f2688ad125b73db597ce63cc842fb27a (diff) |
x86: change flush_tlb_others to take a const struct cpumask
Impact: reduce stack usage, use new cpumask API.
This is made a little more tricky by uv_flush_tlb_others which
actually alters its argument, for an IPI to be sent to the remaining
cpus in the mask.
I solve this by allocating a cpumask_var_t for this case and falling back
to IPI should this fail.
To eliminate temporaries in the caller, all flush_tlb_others implementations
now do the this-cpu-elimination step themselves.
Note also the curious "cpus_or(f->flush_cpumask, cpumask, f->flush_cpumask)"
which has been there since pre-git and yet f->flush_cpumask is always zero
at this point.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Mike Travis <travis@sgi.com>
Diffstat (limited to 'arch/x86/xen/enlighten.c')
-rw-r--r-- | arch/x86/xen/enlighten.c | 31 |
1 files changed, 12 insertions, 19 deletions
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index bea215230b20..965539ec425f 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c | |||
@@ -634,35 +634,27 @@ static void xen_flush_tlb_single(unsigned long addr) | |||
634 | preempt_enable(); | 634 | preempt_enable(); |
635 | } | 635 | } |
636 | 636 | ||
637 | static void xen_flush_tlb_others(const cpumask_t *cpus, struct mm_struct *mm, | 637 | static void xen_flush_tlb_others(const struct cpumask *cpus, |
638 | unsigned long va) | 638 | struct mm_struct *mm, unsigned long va) |
639 | { | 639 | { |
640 | struct { | 640 | struct { |
641 | struct mmuext_op op; | 641 | struct mmuext_op op; |
642 | cpumask_t mask; | 642 | DECLARE_BITMAP(mask, NR_CPUS); |
643 | } *args; | 643 | } *args; |
644 | cpumask_t cpumask = *cpus; | ||
645 | struct multicall_space mcs; | 644 | struct multicall_space mcs; |
646 | 645 | ||
647 | /* | 646 | BUG_ON(cpumask_empty(cpus)); |
648 | * A couple of (to be removed) sanity checks: | ||
649 | * | ||
650 | * - current CPU must not be in mask | ||
651 | * - mask must exist :) | ||
652 | */ | ||
653 | BUG_ON(cpus_empty(cpumask)); | ||
654 | BUG_ON(cpu_isset(smp_processor_id(), cpumask)); | ||
655 | BUG_ON(!mm); | 647 | BUG_ON(!mm); |
656 | 648 | ||
657 | /* If a CPU which we ran on has gone down, OK. */ | ||
658 | cpus_and(cpumask, cpumask, cpu_online_map); | ||
659 | if (cpus_empty(cpumask)) | ||
660 | return; | ||
661 | |||
662 | mcs = xen_mc_entry(sizeof(*args)); | 649 | mcs = xen_mc_entry(sizeof(*args)); |
663 | args = mcs.args; | 650 | args = mcs.args; |
664 | args->mask = cpumask; | 651 | args->op.arg2.vcpumask = to_cpumask(args->mask); |
665 | args->op.arg2.vcpumask = &args->mask; | 652 | |
653 | /* Remove us, and any offline CPUS. */ | ||
654 | cpumask_and(to_cpumask(args->mask), cpus, cpu_online_mask); | ||
655 | cpumask_clear_cpu(smp_processor_id(), to_cpumask(args->mask)); | ||
656 | if (unlikely(cpumask_empty(to_cpumask(args->mask)))) | ||
657 | goto issue; | ||
666 | 658 | ||
667 | if (va == TLB_FLUSH_ALL) { | 659 | if (va == TLB_FLUSH_ALL) { |
668 | args->op.cmd = MMUEXT_TLB_FLUSH_MULTI; | 660 | args->op.cmd = MMUEXT_TLB_FLUSH_MULTI; |
@@ -673,6 +665,7 @@ static void xen_flush_tlb_others(const cpumask_t *cpus, struct mm_struct *mm, | |||
673 | 665 | ||
674 | MULTI_mmuext_op(mcs.mc, &args->op, 1, NULL, DOMID_SELF); | 666 | MULTI_mmuext_op(mcs.mc, &args->op, 1, NULL, DOMID_SELF); |
675 | 667 | ||
668 | issue: | ||
676 | xen_mc_issue(PARAVIRT_LAZY_MMU); | 669 | xen_mc_issue(PARAVIRT_LAZY_MMU); |
677 | } | 670 | } |
678 | 671 | ||