4a5ee0f11d
5537a4d8-libxl-use-DEBUG-log-level-instead-of-INFO.patch - Upstream patches from Jan 55dc78e9-x86-amd_ucode-skip-updates-for-final-levels.patch 55dc7937-x86-IO-APIC-don-t-create-pIRQ-mapping-from-masked-RTE.patch 55df2f76-IOMMU-skip-domains-without-page-tables-when-dumping.patch 55e43fd8-x86-NUMA-fix-setup_node.patch 55e43ff8-x86-NUMA-don-t-account-hotplug-regions.patch 55e593f1-x86-NUMA-make-init_node_heap-respect-Xen-heap-limit.patch 54c2553c-grant-table-use-uint16_t-consistently-for-offset-and-length.patch 54ca33bc-grant-table-refactor-grant-copy-to-reduce-duplicate-code.patch 54ca340e-grant-table-defer-releasing-pages-acquired-in-a-grant-copy.patch - bsc#944463 - VUL-0: CVE-2015-5239: qemu-kvm: Integer overflow in vnc_client_read() and protocol_client_msg() CVE-2015-5239-qemuu-limit-client_cut_text-msg-payload-size.patch CVE-2015-5239-qemut-limit-client_cut_text-msg-payload-size.patch - bsc#944697 - VUL-1: CVE-2015-6815: qemu: net: e1000: infinite loop issue CVE-2015-6815-qemuu-e1000-fix-infinite-loop.patch CVE-2015-6815-qemut-e1000-fix-infinite-loop.patch OBS-URL: https://build.opensuse.org/package/show/Virtualization/xen?expand=0&rev=375
156 lines
4.7 KiB
Diff
156 lines
4.7 KiB
Diff
# Commit d28f42f2703e483116bafd2b0b76a32af67d83ad
|
|
# Date 2015-01-29 14:22:22 +0100
|
|
# Author David Vrabel <david.vrabel@citrix.com>
|
|
# Committer Jan Beulich <jbeulich@suse.com>
|
|
grant-table: defer releasing pages acquired in a grant copy
|
|
|
|
Acquiring a page for the source or destination of a grant copy is an
|
|
expensive operation. A common use case is for two adjacent grant copy
|
|
ops to operate on either the same source or the same destination page.
|
|
|
|
Instead of always acquiring and releasing destination and source pages
|
|
for each operation, release the page once it is no longer valid for
|
|
the next op.
|
|
|
|
If either the source or destination domains changes both pages are
|
|
released as it is unlikely that either will still be valid.
|
|
|
|
XenServer's performance benchmarks show modest improvements in network
|
|
receive throughput (netback uses grant copy in the guest Rx path) and
|
|
no regressions in disk performance (using tapdisk3 which grant copies
|
|
as the backend).
|
|
|
|
Baseline Deferred Release
|
|
Interhost receive to VM 7.2 Gb/s ~9 Gbit/s
|
|
Interhost aggregate 24 Gb/s 28 Gb/s
|
|
Intrahost single stream 14 Gb/s 14 Gb/s
|
|
Intrahost aggregate 34 Gb/s 36 Gb/s
|
|
Aggregate disk write 900 MB/s 900 MB/s
|
|
Aggregate disk read 890 MB/s 890 MB/s
|
|
|
|
Signed-off-by: David Vrabel <david.vrabel@citrix.com>
|
|
Reviewed-by: Tim Deegan <tim@xen.org>
|
|
Reviewed-by: Jan Beulich <jbeulich@suse.com>
|
|
|
|
--- a/xen/common/grant_table.c
|
|
+++ b/xen/common/grant_table.c
|
|
@@ -2236,6 +2236,17 @@ static int gnttab_copy_claim_buf(const s
|
|
return rc;
|
|
}
|
|
|
|
+static bool_t gnttab_copy_buf_valid(const struct gnttab_copy_ptr *p,
|
|
+ const struct gnttab_copy_buf *b,
|
|
+ bool_t has_gref)
|
|
+{
|
|
+ if ( !b->virt )
|
|
+ return 0;
|
|
+ if ( has_gref )
|
|
+ return b->have_grant && p->u.ref == b->ptr.u.ref;
|
|
+ return p->u.gmfn == b->ptr.u.gmfn;
|
|
+}
|
|
+
|
|
static int gnttab_copy_buf(const struct gnttab_copy *op,
|
|
struct gnttab_copy_buf *dest,
|
|
const struct gnttab_copy_buf *src)
|
|
@@ -2274,23 +2285,40 @@ static int gnttab_copy_one(const struct
|
|
{
|
|
int rc;
|
|
|
|
- rc = gnttab_copy_lock_domains(op, src, dest);
|
|
- if ( rc < 0 )
|
|
- goto out;
|
|
+ if ( !src->domain || op->source.domid != src->ptr.domid ||
|
|
+ !dest->domain || op->dest.domid != dest->ptr.domid )
|
|
+ {
|
|
+ gnttab_copy_release_buf(src);
|
|
+ gnttab_copy_release_buf(dest);
|
|
+ gnttab_copy_unlock_domains(src, dest);
|
|
|
|
- rc = gnttab_copy_claim_buf(op, &op->source, src, GNTCOPY_source_gref);
|
|
- if ( rc < 0 )
|
|
- goto out;
|
|
+ rc = gnttab_copy_lock_domains(op, src, dest);
|
|
+ if ( rc < 0 )
|
|
+ goto out;
|
|
+ }
|
|
|
|
- rc = gnttab_copy_claim_buf(op, &op->dest, dest, GNTCOPY_dest_gref);
|
|
- if ( rc < 0 )
|
|
- goto out;
|
|
+ /* Different source? */
|
|
+ if ( !gnttab_copy_buf_valid(&op->source, src,
|
|
+ op->flags & GNTCOPY_source_gref) )
|
|
+ {
|
|
+ gnttab_copy_release_buf(src);
|
|
+ rc = gnttab_copy_claim_buf(op, &op->source, src, GNTCOPY_source_gref);
|
|
+ if ( rc < 0 )
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ /* Different dest? */
|
|
+ if ( !gnttab_copy_buf_valid(&op->dest, dest,
|
|
+ op->flags & GNTCOPY_dest_gref) )
|
|
+ {
|
|
+ gnttab_copy_release_buf(dest);
|
|
+ rc = gnttab_copy_claim_buf(op, &op->dest, dest, GNTCOPY_dest_gref);
|
|
+ if ( rc < 0 )
|
|
+ goto out;
|
|
+ }
|
|
|
|
rc = gnttab_copy_buf(op, dest, src);
|
|
out:
|
|
- gnttab_copy_release_buf(src);
|
|
- gnttab_copy_release_buf(dest);
|
|
- gnttab_copy_unlock_domains(src, dest);
|
|
return rc;
|
|
}
|
|
|
|
@@ -2301,21 +2329,42 @@ static long gnttab_copy(
|
|
struct gnttab_copy op;
|
|
struct gnttab_copy_buf src = {};
|
|
struct gnttab_copy_buf dest = {};
|
|
+ long rc = 0;
|
|
|
|
for ( i = 0; i < count; i++ )
|
|
{
|
|
- if (i && hypercall_preempt_check())
|
|
- return i;
|
|
+ if ( i && hypercall_preempt_check() )
|
|
+ {
|
|
+ rc = i;
|
|
+ break;
|
|
+ }
|
|
+
|
|
if ( unlikely(__copy_from_guest(&op, uop, 1)) )
|
|
- return -EFAULT;
|
|
+ {
|
|
+ rc = -EFAULT;
|
|
+ break;
|
|
+ }
|
|
|
|
op.status = gnttab_copy_one(&op, &dest, &src);
|
|
+ if ( op.status != GNTST_okay )
|
|
+ {
|
|
+ gnttab_copy_release_buf(&src);
|
|
+ gnttab_copy_release_buf(&dest);
|
|
+ }
|
|
|
|
if ( unlikely(__copy_field_to_guest(uop, &op, status)) )
|
|
- return -EFAULT;
|
|
+ {
|
|
+ rc = -EFAULT;
|
|
+ break;
|
|
+ }
|
|
guest_handle_add_offset(uop, 1);
|
|
}
|
|
- return 0;
|
|
+
|
|
+ gnttab_copy_release_buf(&src);
|
|
+ gnttab_copy_release_buf(&dest);
|
|
+ gnttab_copy_unlock_domains(&src, &dest);
|
|
+
|
|
+ return rc;
|
|
}
|
|
|
|
static long
|