[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 1/3] x86/xen: allow for privcmd hypercalls to be preempted
From: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> Hypercalls submitted by user space tools via the privcmd driver can take a long time (potentially many 10s of seconds) if the hypercall has many sub-operations. A fully preemptible kernel may deschedule such as task in any upcall called from a hypercall continuation. However, in a kernel with only voluntary preemption, hypercall continuations in Xen allow event handlers to be run but the task issuing the hypercall will not be descheduled until the hypercall is complete and the ioctl returns to user space. These long running tasks may also trigger the kernel's soft lockup detection. There needs to be a voluntary preemption point (cond_resched()) at the end of an upcall, but only if the interrupted task had issued a hypercall via the privcmd driver. Add is_preemptible_hypercall() which may be used in a upcall to determine this. Implement is_premptible_hypercall() by adding a second hypercall page (preemptible_hypercall_page, copied from hypercall_page). Calls made via the new page may be preempted. Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> Signed-off-by: David Vrabel <david.vrabel@xxxxxxxxxx> --- arch/x86/include/asm/xen/hypercall.h | 14 ++++++++++++++ arch/x86/xen/enlighten.c | 7 +++++++ arch/x86/xen/xen-head.S | 18 +++++++++++++++++- 3 files changed, 38 insertions(+), 1 deletions(-) diff --git a/arch/x86/include/asm/xen/hypercall.h b/arch/x86/include/asm/xen/hypercall.h index e709884..4658a75 100644 --- a/arch/x86/include/asm/xen/hypercall.h +++ b/arch/x86/include/asm/xen/hypercall.h @@ -83,6 +83,16 @@ */ extern struct { char _entry[32]; } hypercall_page[]; +#ifndef CONFIG_PREEMPT +extern struct { char _entry[32]; } preemptible_hypercall_page[]; + +static inline bool is_preemptible_hypercall(struct pt_regs *regs) +{ + return !user_mode_vm(regs) && + regs->ip >= (unsigned long)preemptible_hypercall_page && + regs->ip < (unsigned long)preemptible_hypercall_page + PAGE_SIZE; +} +#endif #define __HYPERCALL "call hypercall_page+%c[offset]" #define __HYPERCALL_ENTRY(x) \ @@ -215,7 +225,11 @@ privcmd_call(unsigned call, asm volatile("call *%[call]" : __HYPERCALL_5PARAM +#ifndef CONFIG_PREEMPT + : [call] "a" (&preemptible_hypercall_page[call]) +#else : [call] "a" (&hypercall_page[call]) +#endif : __HYPERCALL_CLOBBER5); return (long)__res; diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index a4d7b64..7320fa8 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c @@ -84,6 +84,9 @@ #include "multicalls.h" EXPORT_SYMBOL_GPL(hypercall_page); +#ifndef CONFIG_PREEMPT +EXPORT_SYMBOL_GPL(preemptible_hypercall_page); +#endif /* * Pointer to the xen_vcpu_info structure or @@ -1517,6 +1520,10 @@ asmlinkage void __init xen_start_kernel(void) xen_pvh_early_guest_init(); xen_setup_machphys_mapping(); +#ifndef CONFIG_PREEMPT + copy_page(preemptible_hypercall_page, hypercall_page); +#endif + /* Install Xen paravirt ops */ pv_info = xen_info; pv_init_ops = xen_init_ops; diff --git a/arch/x86/xen/xen-head.S b/arch/x86/xen/xen-head.S index 485b695..0407d48 100644 --- a/arch/x86/xen/xen-head.S +++ b/arch/x86/xen/xen-head.S @@ -50,9 +50,18 @@ ENTRY(startup_xen) .pushsection .text .balign PAGE_SIZE ENTRY(hypercall_page) + +#ifdef CONFIG_PREEMPT +# define PREEMPT_HYPERCALL_ENTRY(x) +#else +# define PREEMPT_HYPERCALL_ENTRY(x) \ + .global xen_hypercall_##x ## _p ASM_NL \ + .set preemptible_xen_hypercall_##x, xen_hypercall_##x + PAGE_SIZE ASM_NL +#endif #define NEXT_HYPERCALL(x) \ ENTRY(xen_hypercall_##x) \ - .skip 32 + .skip 32 ASM_NL \ + PREEMPT_HYPERCALL_ENTRY(x) NEXT_HYPERCALL(set_trap_table) NEXT_HYPERCALL(mmu_update) @@ -103,6 +112,13 @@ NEXT_HYPERCALL(arch_4) NEXT_HYPERCALL(arch_5) NEXT_HYPERCALL(arch_6) .balign PAGE_SIZE + +#ifndef CONFIG_PREEMPT +ENTRY(preemptible_hypercall_page) + .skip PAGE_SIZE +#endif /* CONFIG_PREEMPT */ + +#undef NEXT_HYPERCALL .popsection ELFNOTE(Xen, XEN_ELFNOTE_GUEST_OS, .asciz "linux") -- 1.7.2.5 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |