]> xenbits.xensource.com Git - people/royger/xen.git/commitdiff
xen/x86: allow calling {sh/hap}_set_allocation with the idle domain
authorRoger Pau Monne <roger.pau@citrix.com>
Fri, 28 Oct 2016 09:16:39 +0000 (11:16 +0200)
committerRoger Pau Monne <roger.pau@citrix.com>
Wed, 2 Nov 2016 17:29:28 +0000 (18:29 +0100)
... and using the "preempted" parameter. Introduce a new helper that can
be used from both hypercall or idle vcpu context (ie: during Dom0
creation) in order to check if preemption is needed. If such preemption
happens, the caller should then call process_pending_softirqs in order to
drain the pending softirqs, and then call {sh/hap}_set_allocation again to
continue with it's execution.

This allows us to call *_set_allocation() when building domain 0.

While there also convert hypercall_preempt_check to an inline function, and
document it.

Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Acked-by: George Dunlap <george.dunlap@citrix.com>
---
Cc: George Dunlap <george.dunlap@eu.citrix.com>
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
---
Changes since v3:
 - Introduce general_preempt_check.
 - Convert hypercall_preempt_check to an inline function.

Changes since v2:
 - Fix commit message.

xen/arch/x86/mm/hap/hap.c
xen/arch/x86/mm/shadow/common.c
xen/include/xen/sched.h

index f099e9412fd490124f2c624a4dea2e9790dcc18f..b9faba68345724d0b0eddf74ebdabdb990bfb986 100644 (file)
@@ -379,7 +379,7 @@ hap_set_allocation(struct domain *d, unsigned int pages, int *preempted)
             break;
 
         /* Check to see if we need to yield and try again */
-        if ( preempted && hypercall_preempt_check() )
+        if ( preempted && general_preempt_check() )
         {
             *preempted = 1;
             return 0;
index 065bdc76ddf32c16c2ad8c0660beba5bf019346a..d1e103b419cb910b2d382d60e519502a8d6de487 100644 (file)
@@ -1679,7 +1679,7 @@ static int sh_set_allocation(struct domain *d,
             break;
 
         /* Check to see if we need to yield and try again */
-        if ( preempted && hypercall_preempt_check() )
+        if ( preempted && general_preempt_check() )
         {
             *preempted = 1;
             return 0;
index 1fbda87813e1a91dc7a9162c8524411e25cc58f2..afd295d3af7af742dd728dfbe120d52da29df2d5 100644 (file)
@@ -708,10 +708,27 @@ unsigned long hypercall_create_continuation(
     unsigned int op, const char *format, ...);
 void hypercall_cancel_continuation(void);
 
-#define hypercall_preempt_check() (unlikely(    \
-        softirq_pending(smp_processor_id()) |   \
-        local_events_need_delivery()            \
-    ))
+ /*
+  * For long-running operations that must be in hypercall context, check
+  * if there is background work to be done that should interrupt this
+  * operation.
+  */
+static inline bool hypercall_preempt_check(void)
+{
+    return unlikely(softirq_pending(smp_processor_id()) |
+                    local_events_need_delivery());
+}
+
+ /*
+  * For long-running operations that may be in hypercall context or on
+  * the idle vcpu (e.g. during dom0 construction), check if there is
+  * background work to be done that should interrupt this operation.
+  */
+static inline bool general_preempt_check(void)
+{
+    return unlikely(softirq_pending(smp_processor_id()) ||
+                    (!is_idle_vcpu(current) && local_events_need_delivery()));
+}
 
 extern struct domain *domain_list;