[v3,2/8] drm/i915: get ready of memory for pvmmio

Submitted by Xiaolin Zhang on Nov. 13, 2018, 8:35 a.m.

Details

Message ID 1542098120-29684-3-git-send-email-xiaolin.zhang@intel.com
State New
Headers show
Series "i915 pvmmio to improve GVTg performance" ( rev: 1 ) in Intel GVT devel

Not browsing as part of any series.

Commit Message

Xiaolin Zhang Nov. 13, 2018, 8:35 a.m.
To enable pvmmio feature, we need to prepare one 4K shared page
which will be accessed by both guest and backend i915 driver used for
data exchagne.

the layout of shared_page also defined as well in this patch.

guest i915 will allocate one page memory and then pass this page's physical
address to backend i915 driver through PVINFO register so that backend i915
driver can access this shared page without hypeviser trap cost
for shared data exchagne via hyperviser read_gpa functionality.

v0: RFC
v1: addressed RFC comment to move both shared_page_lock and shared_page
to i915_virtual_gpu structure
v2: packed i915_virtual_gpu structure
v3: added SHARED_PAGE_SETUP g2v notification for pv shared_page setup

Cc: Zhenyu Wang <zhenyuw@linux.intel.com>
Cc: Zhi Wang <zhi.a.wang@intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: He Min <min.he@intel.com>
Cc: Jiang Fei <fei.jiang@intel.com>
Cc: Gong Zhipeng <zhipeng.gong@intel.com>
Cc: Yuan Hang <hang.yuan@intel.com>
Cc: Zhiyuan Lv <zhiyuan.lv@intel.com>
Signed-off-by: Xiaolin Zhang <xiaolin.zhang@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.c    |  2 ++
 drivers/gpu/drm/i915/i915_drv.h    |  4 +++-
 drivers/gpu/drm/i915/i915_pvinfo.h | 29 ++++++++++++++++++++++++++++-
 drivers/gpu/drm/i915/i915_vgpu.c   | 23 +++++++++++++++++++++++
 4 files changed, 56 insertions(+), 2 deletions(-)

Patch hide | download patch | download mbox

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index baac35f..557ab67 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -987,6 +987,8 @@  static void i915_mmio_cleanup(struct drm_i915_private *dev_priv)
 
 	intel_teardown_mchbar(dev_priv);
 	pci_iounmap(pdev, dev_priv->regs);
+	if (intel_vgpu_active(dev_priv) && dev_priv->vgpu.shared_page)
+		free_page((unsigned long)dev_priv->vgpu.shared_page);
 }
 
 /**
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 7b2d7cb..d7a972f 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1345,7 +1345,9 @@  struct i915_virtual_gpu {
 	bool active;
 	u32 caps;
 	u32 pv_caps;
-};
+	spinlock_t shared_page_lock;
+	struct gvt_shared_page *shared_page;
+} __packed;
 
 /* used in computing the new watermarks state */
 struct intel_wm_config {
diff --git a/drivers/gpu/drm/i915/i915_pvinfo.h b/drivers/gpu/drm/i915/i915_pvinfo.h
index 78a4b9c..aa5eebc 100644
--- a/drivers/gpu/drm/i915/i915_pvinfo.h
+++ b/drivers/gpu/drm/i915/i915_pvinfo.h
@@ -24,6 +24,8 @@ 
 #ifndef _I915_PVINFO_H_
 #define _I915_PVINFO_H_
 
+#include "i915_gem.h"
+
 /* The MMIO offset of the shared info between guest and host emulator */
 #define VGT_PVINFO_PAGE	0x78000
 #define VGT_PVINFO_SIZE	0x1000
@@ -46,9 +48,29 @@  enum vgt_g2v_type {
 	VGT_G2V_PPGTT_L4_PAGE_TABLE_DESTROY,
 	VGT_G2V_EXECLIST_CONTEXT_CREATE,
 	VGT_G2V_EXECLIST_CONTEXT_DESTROY,
+	VGT_G2V_SHARED_PAGE_SETUP,
 	VGT_G2V_MAX,
 };
 
+struct pv_ppgtt_update {
+	u64 pdp;
+	u64 start;
+	u64 length;
+	u32 cache_level;
+};
+
+/*
+ * shared page(4KB) between gvt and VM, could be allocated by guest driver
+ * or a fixed location in PCI bar 0 region
+ */
+struct gvt_shared_page {
+	u32 reg_addr;
+	u32 elsp_data[I915_NUM_ENGINES * 4];
+	u32 ring_id;
+	u32 disable_irq;
+	struct pv_ppgtt_update pv_ppgtt;
+};
+
 /*
  * VGT capabilities type
  */
@@ -121,7 +143,12 @@  struct vgt_if {
 
 	u32 pvmmio_caps;
 
-	u32  rsv7[0x200 - 25];    /* pad to one page */
+	struct {
+		u32 lo;
+		u32 hi;
+	} shared_page_gpa;
+
+	u32  rsv7[0x200 - 27];    /* pad to one page */
 } __packed;
 
 #define vgtif_reg(x) \
diff --git a/drivers/gpu/drm/i915/i915_vgpu.c b/drivers/gpu/drm/i915/i915_vgpu.c
index 219c7c0..63f70bf 100644
--- a/drivers/gpu/drm/i915/i915_vgpu.c
+++ b/drivers/gpu/drm/i915/i915_vgpu.c
@@ -63,6 +63,7 @@  void i915_check_vgpu(struct drm_i915_private *dev_priv)
 	u64 magic;
 	u16 version_major;
 	u32 gvt_caps;
+	u64 gpa;
 
 	BUILD_BUG_ON(sizeof(struct vgt_if) != VGT_PVINFO_SIZE);
 
@@ -95,6 +96,28 @@  void i915_check_vgpu(struct drm_i915_private *dev_priv)
 	if (!dev_priv->vgpu.pv_caps)
 		return;
 
+	dev_priv->vgpu.shared_page =  (struct gvt_shared_page *)
+			get_zeroed_page(GFP_KERNEL);
+	if (!dev_priv->vgpu.shared_page) {
+		DRM_ERROR("out of memory for shared page memory\n");
+		return;
+	}
+	gpa = __pa(dev_priv->vgpu.shared_page);
+	__raw_i915_write32(dev_priv, vgtif_reg(shared_page_gpa.lo),
+			lower_32_bits(gpa));
+	__raw_i915_write32(dev_priv, vgtif_reg(shared_page_gpa.hi),
+			upper_32_bits(gpa));
+	if (gpa != __raw_i915_read64(dev_priv,
+			vgtif_reg(shared_page_gpa))) {
+		DRM_ERROR("vgpu: passed shared_page_gpa failed\n");
+		free_page((unsigned long)dev_priv->vgpu.shared_page);
+		dev_priv->vgpu.pv_caps = 0;
+		__raw_i915_write32(dev_priv, vgtif_reg(pvmmio_caps), 0);
+		return;
+	}
+	__raw_i915_write32(dev_priv, vgtif_reg(g2v_notify),
+			VGT_G2V_SHARED_PAGE_SETUP);
+	spin_lock_init(&dev_priv->vgpu.shared_page_lock);
 
 	DRM_INFO("Virtual GPU for Intel GVT-g detected with pvmmio 0x%x\n",
 			dev_priv->vgpu.pv_caps);

Comments


On 2018.11.13 16:35:14 +0800, Xiaolin Zhang wrote:
> To enable pvmmio feature, we need to prepare one 4K shared page
> which will be accessed by both guest and backend i915 driver used for
> data exchagne.
> 
> the layout of shared_page also defined as well in this patch.
> 
> guest i915 will allocate one page memory and then pass this page's physical
> address to backend i915 driver through PVINFO register so that backend i915
> driver can access this shared page without hypeviser trap cost
> for shared data exchagne via hyperviser read_gpa functionality.
> 
> v0: RFC
> v1: addressed RFC comment to move both shared_page_lock and shared_page
> to i915_virtual_gpu structure
> v2: packed i915_virtual_gpu structure
> v3: added SHARED_PAGE_SETUP g2v notification for pv shared_page setup
> 
> Cc: Zhenyu Wang <zhenyuw@linux.intel.com>
> Cc: Zhi Wang <zhi.a.wang@intel.com>
> Cc: Chris Wilson <chris@chris-wilson.co.uk>
> Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
> Cc: He Min <min.he@intel.com>
> Cc: Jiang Fei <fei.jiang@intel.com>
> Cc: Gong Zhipeng <zhipeng.gong@intel.com>
> Cc: Yuan Hang <hang.yuan@intel.com>
> Cc: Zhiyuan Lv <zhiyuan.lv@intel.com>
> Signed-off-by: Xiaolin Zhang <xiaolin.zhang@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_drv.c    |  2 ++
>  drivers/gpu/drm/i915/i915_drv.h    |  4 +++-
>  drivers/gpu/drm/i915/i915_pvinfo.h | 29 ++++++++++++++++++++++++++++-
>  drivers/gpu/drm/i915/i915_vgpu.c   | 23 +++++++++++++++++++++++
>  4 files changed, 56 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
> index baac35f..557ab67 100644
> --- a/drivers/gpu/drm/i915/i915_drv.c
> +++ b/drivers/gpu/drm/i915/i915_drv.c
> @@ -987,6 +987,8 @@ static void i915_mmio_cleanup(struct drm_i915_private *dev_priv)
>  
>  	intel_teardown_mchbar(dev_priv);
>  	pci_iounmap(pdev, dev_priv->regs);
> +	if (intel_vgpu_active(dev_priv) && dev_priv->vgpu.shared_page)
> +		free_page((unsigned long)dev_priv->vgpu.shared_page);
>  }
>  
>  /**
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 7b2d7cb..d7a972f 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -1345,7 +1345,9 @@ struct i915_virtual_gpu {
>  	bool active;
>  	u32 caps;
>  	u32 pv_caps;
> -};
> +	spinlock_t shared_page_lock;
> +	struct gvt_shared_page *shared_page;
> +} __packed;
>  
>  /* used in computing the new watermarks state */
>  struct intel_wm_config {
> diff --git a/drivers/gpu/drm/i915/i915_pvinfo.h b/drivers/gpu/drm/i915/i915_pvinfo.h
> index 78a4b9c..aa5eebc 100644
> --- a/drivers/gpu/drm/i915/i915_pvinfo.h
> +++ b/drivers/gpu/drm/i915/i915_pvinfo.h
> @@ -24,6 +24,8 @@
>  #ifndef _I915_PVINFO_H_
>  #define _I915_PVINFO_H_
>  
> +#include "i915_gem.h"
> +
>  /* The MMIO offset of the shared info between guest and host emulator */
>  #define VGT_PVINFO_PAGE	0x78000
>  #define VGT_PVINFO_SIZE	0x1000
> @@ -46,9 +48,29 @@ enum vgt_g2v_type {
>  	VGT_G2V_PPGTT_L4_PAGE_TABLE_DESTROY,
>  	VGT_G2V_EXECLIST_CONTEXT_CREATE,
>  	VGT_G2V_EXECLIST_CONTEXT_DESTROY,
> +	VGT_G2V_SHARED_PAGE_SETUP,
>  	VGT_G2V_MAX,
>  };
>  
> +struct pv_ppgtt_update {
> +	u64 pdp;
> +	u64 start;
> +	u64 length;
> +	u32 cache_level;
> +};
> +
> +/*
> + * shared page(4KB) between gvt and VM, could be allocated by guest driver
> + * or a fixed location in PCI bar 0 region
> + */
> +struct gvt_shared_page {
> +	u32 reg_addr;
> +	u32 elsp_data[I915_NUM_ENGINES * 4];

You can't rely on I915_NUM_ENGINES, which may be changed so that would
cause incompatibility in shared page definition.

> +	u32 ring_id;
> +	u32 disable_irq;
> +	struct pv_ppgtt_update pv_ppgtt;
> +};
> +
>  /*
>   * VGT capabilities type
>   */
> @@ -121,7 +143,12 @@ struct vgt_if {
>  
>  	u32 pvmmio_caps;
>  
> -	u32  rsv7[0x200 - 25];    /* pad to one page */
> +	struct {
> +		u32 lo;
> +		u32 hi;
> +	} shared_page_gpa;
> +
> +	u32  rsv7[0x200 - 27];    /* pad to one page */
>  } __packed;
>  
>  #define vgtif_reg(x) \
> diff --git a/drivers/gpu/drm/i915/i915_vgpu.c b/drivers/gpu/drm/i915/i915_vgpu.c
> index 219c7c0..63f70bf 100644
> --- a/drivers/gpu/drm/i915/i915_vgpu.c
> +++ b/drivers/gpu/drm/i915/i915_vgpu.c
> @@ -63,6 +63,7 @@ void i915_check_vgpu(struct drm_i915_private *dev_priv)
>  	u64 magic;
>  	u16 version_major;
>  	u32 gvt_caps;
> +	u64 gpa;
>  
>  	BUILD_BUG_ON(sizeof(struct vgt_if) != VGT_PVINFO_SIZE);
>  
> @@ -95,6 +96,28 @@ void i915_check_vgpu(struct drm_i915_private *dev_priv)
>  	if (!dev_priv->vgpu.pv_caps)
>  		return;
>  
> +	dev_priv->vgpu.shared_page =  (struct gvt_shared_page *)
> +			get_zeroed_page(GFP_KERNEL);
> +	if (!dev_priv->vgpu.shared_page) {
> +		DRM_ERROR("out of memory for shared page memory\n");
> +		return;
> +	}
> +	gpa = __pa(dev_priv->vgpu.shared_page);
> +	__raw_i915_write32(dev_priv, vgtif_reg(shared_page_gpa.lo),
> +			lower_32_bits(gpa));
> +	__raw_i915_write32(dev_priv, vgtif_reg(shared_page_gpa.hi),
> +			upper_32_bits(gpa));
> +	if (gpa != __raw_i915_read64(dev_priv,
> +			vgtif_reg(shared_page_gpa))) {
> +		DRM_ERROR("vgpu: passed shared_page_gpa failed\n");
> +		free_page((unsigned long)dev_priv->vgpu.shared_page);
> +		dev_priv->vgpu.pv_caps = 0;
> +		__raw_i915_write32(dev_priv, vgtif_reg(pvmmio_caps), 0);
> +		return;
> +	}
> +	__raw_i915_write32(dev_priv, vgtif_reg(g2v_notify),
> +			VGT_G2V_SHARED_PAGE_SETUP);
> +	spin_lock_init(&dev_priv->vgpu.shared_page_lock);
>  
>  	DRM_INFO("Virtual GPU for Intel GVT-g detected with pvmmio 0x%x\n",
>  			dev_priv->vgpu.pv_caps);
> -- 
> 2.7.4
> 
> _______________________________________________
> intel-gvt-dev mailing list
> intel-gvt-dev@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gvt-dev