]> xenbits.xensource.com Git - people/sstabellini/xen-unstable.git/.git/commitdiff
x86/domctl: have XEN_DOMCTL_getpageframeinfo3 preemptible
authorAnthony PERARD <anthony.perard@citrix.com>
Tue, 26 Nov 2019 13:16:09 +0000 (14:16 +0100)
committerJan Beulich <jbeulich@suse.com>
Tue, 26 Nov 2019 13:16:09 +0000 (14:16 +0100)
This hypercall can take a long time to finish because it attempts to
grab the `hostp2m' lock up to 1024 times. The accumulated wait for the
lock can take several seconds.

This can easily happen with a guest with 32 vcpus and plenty of RAM,
during localhost migration.

While the patch doesn't fix the problem with the lock contention and
the fact that the `hostp2m' lock is currently global (and not on a
single page), it is still an improvement to the hypercall. It will in
particular, down the road, allow dropping the arbitrary limit of 1024
entries per request.

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
Release-acked-by: Juergen Gross <jgross@suse.com>
xen/arch/x86/domctl.c
xen/include/public/domctl.h

index 43e368d63bb976c7088fd4a964348940ea8c3285..b461aadbd640a592d6789ad04983b6fc4d196afe 100644 (file)
@@ -425,6 +425,26 @@ long arch_do_domctl(
                 ret = -EFAULT;
                 break;
             }
+
+            /*
+             * Avoid checking for preemption when the `hostp2m' lock isn't
+             * involve, i.e. non-translated guest, and avoid preemption on
+             * the last iteration.
+             */
+            if ( paging_mode_translate(d) &&
+                 likely((i + 1) < num) && hypercall_preempt_check() )
+            {
+                domctl->u.getpageframeinfo3.num = num - i - 1;
+                domctl->u.getpageframeinfo3.array.p =
+                    guest_handle + ((i + 1) * width);
+                if ( __copy_to_guest(u_domctl, domctl, 1) )
+                {
+                    ret = -EFAULT;
+                    break;
+                }
+                return hypercall_create_continuation(__HYPERVISOR_domctl,
+                                                     "h", u_domctl);
+            }
         }
 
         break;
index a03e80e5984a9d14fb8481dd3f1c2bc50c284baf..9f2cfd602cb28b869d8748b5bbc2b311b6dd0d8e 100644 (file)
@@ -163,6 +163,10 @@ DEFINE_XEN_GUEST_HANDLE(xen_domctl_getdomaininfo_t);
 #define XEN_DOMCTL_PFINFO_LTAB_MASK (0xfU<<28)
 
 /* XEN_DOMCTL_getpageframeinfo3 */
+/*
+ * Both value `num' and `array' may get modified by the hypercall to allow
+ * preemption.
+ */
 struct xen_domctl_getpageframeinfo3 {
     /* IN variables. */
     uint64_aligned_t num;