[PATCH v2 2/2] drm/i915/gvt: subsitute kvm_read/write_guest with vfio_dma_rw

Yan Zhao
2020-01-15T04:04:14Z

As a device model, it is better to read/write guest memory using vfio
interface, so that vfio is able to maintain dirty info of device IOVAs.

Compared to kvm interfaces kvm_read/write_guest(), vfio_dma_rw() has ~600
cycles more overhead on average.

-------------------------------------
| interface | avg cpu cycles |
|-----------------------------------|
| kvm_write_guest | 1554 |
| ----------------------------------|
| kvm_read_guest | 707 |
|-----------------------------------|
| vfio_dma_rw(w) | 2274 |
|-----------------------------------|
| vfio_dma_rw(r) | 1378 |
-------------------------------------

Comparison of benchmarks scores are as blow:
------------------------------------------------------
| avg score | kvm_read/write_guest | vfio_dma_rw |
|----------------------------------------------------|
| Glmark2 | 1284 | 1296 |
|----------------------------------------------------|
| Lightsmark | 61.24 | 61.27 |
|----------------------------------------------------|
| OpenArena | 140.9 | 137.4 |
|----------------------------------------------------|
| Heaven | 671 | 670 |
------------------------------------------------------
No obvious performance downgrade found.

Cc: Kevin Tian <kevin.tian@intel.com>
Signed-off-by: Yan Zhao <yan.y.zhao@intel.com>
---
drivers/gpu/drm/i915/gvt/kvmgt.c | 26 +++++++-------------------
1 file changed, 7 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index bd79a9718cc7..17edc9a7ff05 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -1966,31 +1966,19 @@ static int kvmgt_rw_gpa(unsigned long handle, unsigned long gpa,
void *buf, unsigned long len, bool write)
{
struct kvmgt_guest_info *info;
- struct kvm *kvm;
- int idx, ret;
- bool kthread = current->mm == NULL;
+ int ret;
+ struct intel_vgpu *vgpu;
+ struct device *dev;

if (!handle_valid(handle))
return -ESRCH;

info = (struct kvmgt_guest_info *)handle;
- kvm = info->kvm;
-
- if (kthread) {
- if (!mmget_not_zero(kvm->mm))
- return -EFAULT;
- use_mm(kvm->mm);
- }
-
- idx = srcu_read_lock(&kvm->srcu);
- ret = write ? kvm_write_guest(kvm, gpa, buf, len) :
- kvm_read_guest(kvm, gpa, buf, len);
- srcu_read_unlock(&kvm->srcu, idx);
+ vgpu = info->vgpu;
+ dev = mdev_dev(vgpu->vdev.mdev);

- if (kthread) {
- unuse_mm(kvm->mm);
- mmput(kvm->mm);
- }
+ ret = write ? vfio_dma_rw(dev, gpa, buf, len, true) :
+ vfio_dma_rw(dev, gpa, buf, len, false);

return ret;
}
--
2.17.1