[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH 3/3] x86: introduce and use scratch CPU mask
On 08/12/16 16:02, Jan Beulich wrote: > __get_page_type(), so far using an on-stack CPU mask variable, is > involved in the recursion when e.g. pinning page tables. This means "in recursion". > there may be up two five instances of the function active at a time, "up to five". > implying five instances of the (up to 512 bytes large) CPU mask > variable. With an IRQ happening at the deepest point of the stack, and > with send_guest_pirq() being called from there (leading to vcpu_kick() > -> ... -> csched_vcpu_wake() -> __runq_tickle() -> > cpumask_raise_softirq(), the last two of which also have CPU mask > variables on their stacks), this has been observed to cause a stack "stacks), has been". > overflow with a 4095-pCPU build. > > Introduce a per-CPU variable instead, which can then be used by any > code never running in IRQ context. > > The mask can then also be used by other MMU code as well as by > msi_compose_msg() (and quite likely we'll find further uses down the > road). > > Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx> > > --- a/xen/arch/x86/mm.c > +++ b/xen/arch/x86/mm.c > @@ -2477,6 +2477,7 @@ static int __get_page_type(struct page_i > int rc = 0, iommu_ret = 0; > > ASSERT(!(type & ~(PGT_type_mask | PGT_pae_xen_l2))); > + ASSERT(!in_irq()); > > for ( ; ; ) > { > @@ -2509,20 +2510,21 @@ static int __get_page_type(struct page_i > * may be unnecessary (e.g., page was GDT/LDT) but those > * circumstances should be very rare. > */ > - cpumask_t mask; > + cpumask_t *mask = this_cpu(scratch_cpumask); This indirection looks suspicious. Why do you have a per_cpu pointer to a cpumask, with a dynamically allocated mask? It would be smaller and more efficient overall to have a fully cpumask allocated in the per-cpu area, and use it via cpumask_t *mask = &this_cpu(scratch_cpumask); except... > --- a/xen/arch/x86/smpboot.c > +++ b/xen/arch/x86/smpboot.c > @@ -56,6 +56,8 @@ DEFINE_PER_CPU_READ_MOSTLY(cpumask_var_t > /* representing HT and core siblings of each logical CPU */ > DEFINE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_core_mask); > > +DEFINE_PER_CPU_READ_MOSTLY(cpumask_var_t, scratch_cpumask); > + .. this does look correct, but.. > cpumask_t cpu_online_map __read_mostly; > EXPORT_SYMBOL(cpu_online_map); > > @@ -646,6 +648,7 @@ static void cpu_smpboot_free(unsigned in > > free_cpumask_var(per_cpu(cpu_sibling_mask, cpu)); > free_cpumask_var(per_cpu(cpu_core_mask, cpu)); > + free_cpumask_var(per_cpu(scratch_cpumask, cpu)); > > if ( per_cpu(stubs.addr, cpu) ) > { > @@ -734,7 +737,8 @@ static int cpu_smpboot_alloc(unsigned in > goto oom; > > if ( zalloc_cpumask_var(&per_cpu(cpu_sibling_mask, cpu)) && > - zalloc_cpumask_var(&per_cpu(cpu_core_mask, cpu)) ) > + zalloc_cpumask_var(&per_cpu(cpu_core_mask, cpu)) && > + alloc_cpumask_var(&per_cpu(scratch_cpumask, cpu)) ) > return 0; This doesn't. I'm confused. ~Andrew _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx https://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |