From: David Vrabel <david.vrabel@citrix.com>
To: xen-devel@lists.xen.org
Cc: Andrew Cooper <andrew.cooper3@citrix.com>,
Boris Ostrovsky <boris.ostrovsky@oracle.com>,
Stefano Stabellini <stefano.stabellini@eu.citrix.com>,
David Vrabel <david.vrabel@citrix.com>
Subject: [PATCH 1/3] x86/xen: allow for privcmd hypercalls to be preempted
Date: Tue, 11 Feb 2014 19:19:10 +0000 [thread overview]
Message-ID: <1392146352-16381-2-git-send-email-david.vrabel@citrix.com> (raw)
In-Reply-To: <1392146352-16381-1-git-send-email-david.vrabel@citrix.com>
From: Andrew Cooper <andrew.cooper3@citrix.com>
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@citrix.com>
Signed-off-by: David Vrabel <david.vrabel@citrix.com>
---
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
next prev parent reply other threads:[~2014-02-11 19:19 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-02-11 19:19 [PATCHv1 0/3]: xen: voluntary preemption for privcmd hypercalls David Vrabel
2014-02-11 19:19 ` David Vrabel [this message]
2014-02-12 9:38 ` [PATCH 1/3] x86/xen: allow for privcmd hypercalls to be preempted Ian Campbell
2014-02-12 10:10 ` Andrew Cooper
2014-02-12 10:18 ` Ian Campbell
2014-02-11 19:19 ` [PATCH 2/3] arm/xen: add stub is_preemptible_hypercall() David Vrabel
2014-02-11 19:19 ` [PATCH 3/3] xen/events: schedule if the interrupted task is in a preemptible hypercall David Vrabel
2014-02-12 11:59 ` Jan Beulich
2014-02-12 12:54 ` David Vrabel
2014-02-12 13:56 ` Jan Beulich
2014-02-12 16:35 ` David Vrabel
2014-02-12 16:47 ` Jan Beulich
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1392146352-16381-2-git-send-email-david.vrabel@citrix.com \
--to=david.vrabel@citrix.com \
--cc=andrew.cooper3@citrix.com \
--cc=boris.ostrovsky@oracle.com \
--cc=stefano.stabellini@eu.citrix.com \
--cc=xen-devel@lists.xen.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).