All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFCv3 00/15] Introduce GVT context support
@ 2016-03-11 10:59 Zhi Wang
  2016-03-11 10:59 ` [RFCv3 01/15] drm/i915: factor out i915_pvinfo.h Zhi Wang
                   ` (15 more replies)
  0 siblings, 16 replies; 29+ messages in thread
From: Zhi Wang @ 2016-03-11 10:59 UTC (permalink / raw)
  To: intel-gfx, igvt-g; +Cc: daniel.vetter, david.j.cowperthwaite, zhiyuan.lv

This patchset is used to discuss and finalize the i915 changes required by
GVT context.

Thanks Joonas/Daniel/Kevin for the comments.

v3:

- Address comments from Joonas/Kevin.
- Add more introductions for better review.
- Factor out and expose some functions in i915_gem_fence.c for fence stealing

This previous review email:

[RFCv2 02/14] drm/i915/gvt: Introduce the basic architecture of GVT-g

http://www.spinics.net/lists/intel-gfx/msg88547.html

[RFCv2 03/14] drm/i915: Introduce host graphics memory/fence partition for GVT-g

http://www.spinics.net/lists/intel-gfx/msg88359.html

Acknowledgment
---------------

iGVT-g implementation is several years effort and many people
contributed to the code. There names are not here yet. In later formal
patchset we will reflect individual's contribution.

Meanwhile, in the previous iGVT-g related discussion, Daniel, Chris
and Joonas ever gave very good inputs. We appreciate them and look
forward to more comments/suggestions from community.

We are trying to get more familiar with i915 and willing to adopt
suggestions to keep improving. We hope to work with community together
to make iGVT-g a great component in i915 to support graphics 
virtualization. Thanks!

Bing Niu (1):
  drm/i915: Introduce host graphics memory partition for GVT-g

Zhi Wang (14):
  drm/i915: factor out i915_pvinfo.h
  drm/i915/gvt: Introduce the basic architecture of GVT-g
  drm/i915: factor out alloc_context_idr() and
    __i915_gem_create_context()
  drm/i915: factor out __create_legacy_hw_context()
  drm/i915: let __i915_gem_context_create() takes context creation
    params
  drm/i915: factor out __intel_lr_context_deferred_alloc()
  drm/i915: Support per-PPGTT address space mode
  drm/i915: generate address mode bit from PPGTT instance
  drm/i915: update PDPs by condition when submit the LRC context
  drm/i915: Introduce execlist context status change notification
  drm/i915: Support context single submission
  drm/i915: Introduce GVT context creation API
  drm/i915: factor out and expose i915_steal_fence()
  drm/i915: expose i915_find_fence_reg()

 drivers/gpu/drm/i915/Kconfig            |  15 +++
 drivers/gpu/drm/i915/Makefile           |   2 +
 drivers/gpu/drm/i915/gvt/Makefile       |   5 +
 drivers/gpu/drm/i915/gvt/debug.h        |  36 +++++
 drivers/gpu/drm/i915/gvt/gvt.c          | 230 ++++++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/gvt/gvt.h          |  84 ++++++++++++
 drivers/gpu/drm/i915/gvt/hypercall.h    |  35 +++++
 drivers/gpu/drm/i915/gvt/mpt.h          |  51 +++++++
 drivers/gpu/drm/i915/i915_dma.c         |  15 +++
 drivers/gpu/drm/i915/i915_drv.h         |  41 ++++++
 drivers/gpu/drm/i915/i915_gem_context.c | 204 ++++++++++++++++++++--------
 drivers/gpu/drm/i915/i915_gem_fence.c   |  46 +++++--
 drivers/gpu/drm/i915/i915_gem_gtt.c     |  92 +++++++------
 drivers/gpu/drm/i915/i915_gem_gtt.h     |   3 +
 drivers/gpu/drm/i915/i915_pvinfo.h      | 113 ++++++++++++++++
 drivers/gpu/drm/i915/i915_vgpu.c        |  31 ++++-
 drivers/gpu/drm/i915/i915_vgpu.h        |  88 +-----------
 drivers/gpu/drm/i915/intel_gvt.c        | 148 ++++++++++++++++++++
 drivers/gpu/drm/i915/intel_gvt.h        |  57 ++++++++
 drivers/gpu/drm/i915/intel_lrc.c        | 146 ++++++++++++++------
 drivers/gpu/drm/i915/intel_lrc.h        |  15 +++
 21 files changed, 1216 insertions(+), 241 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gvt/Makefile
 create mode 100644 drivers/gpu/drm/i915/gvt/debug.h
 create mode 100644 drivers/gpu/drm/i915/gvt/gvt.c
 create mode 100644 drivers/gpu/drm/i915/gvt/gvt.h
 create mode 100644 drivers/gpu/drm/i915/gvt/hypercall.h
 create mode 100644 drivers/gpu/drm/i915/gvt/mpt.h
 create mode 100644 drivers/gpu/drm/i915/i915_pvinfo.h
 create mode 100644 drivers/gpu/drm/i915/intel_gvt.c
 create mode 100644 drivers/gpu/drm/i915/intel_gvt.h

-- 
1.9.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [RFCv3 01/15] drm/i915: factor out i915_pvinfo.h
  2016-03-11 10:59 [RFCv3 00/15] Introduce GVT context support Zhi Wang
@ 2016-03-11 10:59 ` Zhi Wang
  2016-03-11 10:59 ` [RFCv3 02/15] drm/i915/gvt: Introduce the basic architecture of GVT-g Zhi Wang
                   ` (14 subsequent siblings)
  15 siblings, 0 replies; 29+ messages in thread
From: Zhi Wang @ 2016-03-11 10:59 UTC (permalink / raw)
  To: intel-gfx, igvt-g; +Cc: daniel.vetter, david.j.cowperthwaite, zhiyuan.lv

As the PVINFO page definition is used by both GVT-g guest (vGPU) and GVT-g
host (GVT-g kernel device model), factor it out for better code structure.

v3:

Take Joonas's comments:
- Use offsetof to calculate the member offset of PVINFO structure

Signed-off-by: Zhi Wang <zhi.a.wang@intel.com>
---
 drivers/gpu/drm/i915/i915_pvinfo.h | 113 +++++++++++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/i915_vgpu.h   |  86 +---------------------------
 2 files changed, 114 insertions(+), 85 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/i915_pvinfo.h

diff --git a/drivers/gpu/drm/i915/i915_pvinfo.h b/drivers/gpu/drm/i915/i915_pvinfo.h
new file mode 100644
index 0000000..480ef26
--- /dev/null
+++ b/drivers/gpu/drm/i915/i915_pvinfo.h
@@ -0,0 +1,113 @@
+/*
+ * Copyright(c) 2011-2016 Intel Corporation. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef _I915_PVINFO_H_
+#define _I915_PVINFO_H_
+
+/* The MMIO offset of the shared info between guest and host emulator */
+#define VGT_PVINFO_PAGE	0x78000
+#define VGT_PVINFO_SIZE	0x1000
+
+/*
+ * The following structure pages are defined in GEN MMIO space
+ * for virtualization. (One page for now)
+ */
+#define VGT_MAGIC         0x4776544776544776ULL	/* 'vGTvGTvG' */
+#define VGT_VERSION_MAJOR 1
+#define VGT_VERSION_MINOR 0
+
+#define INTEL_VGT_IF_VERSION_ENCODE(major, minor) ((major) << 16 | (minor))
+#define INTEL_VGT_IF_VERSION \
+	INTEL_VGT_IF_VERSION_ENCODE(VGT_VERSION_MAJOR, VGT_VERSION_MINOR)
+
+/*
+ * notifications from guest to vgpu device model
+ */
+enum vgt_g2v_type {
+	VGT_G2V_PPGTT_L3_PAGE_TABLE_CREATE = 2,
+	VGT_G2V_PPGTT_L3_PAGE_TABLE_DESTROY,
+	VGT_G2V_PPGTT_L4_PAGE_TABLE_CREATE,
+	VGT_G2V_PPGTT_L4_PAGE_TABLE_DESTROY,
+	VGT_G2V_EXECLIST_CONTEXT_CREATE,
+	VGT_G2V_EXECLIST_CONTEXT_DESTROY,
+	VGT_G2V_MAX,
+};
+
+struct vgt_if {
+	uint64_t magic;		/* VGT_MAGIC */
+	uint16_t version_major;
+	uint16_t version_minor;
+	uint32_t vgt_id;	/* ID of vGT instance */
+	uint32_t rsv1[12];	/* pad to offset 0x40 */
+	/*
+	 *  Data structure to describe the balooning info of resources.
+	 *  Each VM can only have one portion of continuous area for now.
+	 *  (May support scattered resource in future)
+	 *  (starting from offset 0x40)
+	 */
+	struct {
+		/* Aperture register balooning */
+		struct {
+			uint32_t base;
+			uint32_t size;
+		} mappable_gmadr;	/* aperture */
+		/* GMADR register balooning */
+		struct {
+			uint32_t base;
+			uint32_t size;
+		} nonmappable_gmadr;	/* non aperture */
+		/* allowed fence registers */
+		uint32_t fence_num;
+		uint32_t rsv2[3];
+	} avail_rs;		/* available/assigned resource */
+	uint32_t rsv3[0x200 - 24];	/* pad to half page */
+	/*
+	 * The bottom half page is for response from Gfx driver to hypervisor.
+	 */
+	uint32_t rsv4;
+	uint32_t display_ready;	/* ready for display owner switch */
+
+	uint32_t rsv5[4];
+
+	uint32_t g2v_notify;
+	uint32_t rsv6[7];
+
+	struct {
+		uint32_t lo;
+		uint32_t hi;
+	} pdp[4];
+
+	uint32_t execlist_context_descriptor_lo;
+	uint32_t execlist_context_descriptor_hi;
+
+	uint32_t  rsv7[0x200 - 24];    /* pad to one page */
+} __packed;
+
+#define vgtif_reg(x) \
+	_MMIO(VGT_PVINFO_PAGE + offsetof(struct vgt_if, x))
+
+/* vGPU display status to be used by the host side */
+#define VGT_DRV_DISPLAY_NOT_READY 0
+#define VGT_DRV_DISPLAY_READY     1  /* ready for display switch */
+
+#endif /* _I915_PVINFO_H_ */
diff --git a/drivers/gpu/drm/i915/i915_vgpu.h b/drivers/gpu/drm/i915/i915_vgpu.h
index 3c83b47..a3b06f3 100644
--- a/drivers/gpu/drm/i915/i915_vgpu.h
+++ b/drivers/gpu/drm/i915/i915_vgpu.h
@@ -24,91 +24,7 @@
 #ifndef _I915_VGPU_H_
 #define _I915_VGPU_H_
 
-/* The MMIO offset of the shared info between guest and host emulator */
-#define VGT_PVINFO_PAGE	0x78000
-#define VGT_PVINFO_SIZE	0x1000
-
-/*
- * The following structure pages are defined in GEN MMIO space
- * for virtualization. (One page for now)
- */
-#define VGT_MAGIC         0x4776544776544776ULL	/* 'vGTvGTvG' */
-#define VGT_VERSION_MAJOR 1
-#define VGT_VERSION_MINOR 0
-
-#define INTEL_VGT_IF_VERSION_ENCODE(major, minor) ((major) << 16 | (minor))
-#define INTEL_VGT_IF_VERSION \
-	INTEL_VGT_IF_VERSION_ENCODE(VGT_VERSION_MAJOR, VGT_VERSION_MINOR)
-
-/*
- * notifications from guest to vgpu device model
- */
-enum vgt_g2v_type {
-	VGT_G2V_PPGTT_L3_PAGE_TABLE_CREATE = 2,
-	VGT_G2V_PPGTT_L3_PAGE_TABLE_DESTROY,
-	VGT_G2V_PPGTT_L4_PAGE_TABLE_CREATE,
-	VGT_G2V_PPGTT_L4_PAGE_TABLE_DESTROY,
-	VGT_G2V_EXECLIST_CONTEXT_CREATE,
-	VGT_G2V_EXECLIST_CONTEXT_DESTROY,
-	VGT_G2V_MAX,
-};
-
-struct vgt_if {
-	uint64_t magic;		/* VGT_MAGIC */
-	uint16_t version_major;
-	uint16_t version_minor;
-	uint32_t vgt_id;	/* ID of vGT instance */
-	uint32_t rsv1[12];	/* pad to offset 0x40 */
-	/*
-	 *  Data structure to describe the balooning info of resources.
-	 *  Each VM can only have one portion of continuous area for now.
-	 *  (May support scattered resource in future)
-	 *  (starting from offset 0x40)
-	 */
-	struct {
-		/* Aperture register balooning */
-		struct {
-			uint32_t base;
-			uint32_t size;
-		} mappable_gmadr;	/* aperture */
-		/* GMADR register balooning */
-		struct {
-			uint32_t base;
-			uint32_t size;
-		} nonmappable_gmadr;	/* non aperture */
-		/* allowed fence registers */
-		uint32_t fence_num;
-		uint32_t rsv2[3];
-	} avail_rs;		/* available/assigned resource */
-	uint32_t rsv3[0x200 - 24];	/* pad to half page */
-	/*
-	 * The bottom half page is for response from Gfx driver to hypervisor.
-	 */
-	uint32_t rsv4;
-	uint32_t display_ready;	/* ready for display owner switch */
-
-	uint32_t rsv5[4];
-
-	uint32_t g2v_notify;
-	uint32_t rsv6[7];
-
-	struct {
-		uint32_t lo;
-		uint32_t hi;
-	} pdp[4];
-
-	uint32_t execlist_context_descriptor_lo;
-	uint32_t execlist_context_descriptor_hi;
-
-	uint32_t  rsv7[0x200 - 24];    /* pad to one page */
-} __packed;
-
-#define vgtif_reg(x) \
-	_MMIO((VGT_PVINFO_PAGE + (long)&((struct vgt_if *)NULL)->x))
-
-/* vGPU display status to be used by the host side */
-#define VGT_DRV_DISPLAY_NOT_READY 0
-#define VGT_DRV_DISPLAY_READY     1  /* ready for display switch */
+#include "i915_pvinfo.h"
 
 extern void i915_check_vgpu(struct drm_device *dev);
 extern int intel_vgt_balloon(struct drm_device *dev);
-- 
1.9.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [RFCv3 02/15] drm/i915/gvt: Introduce the basic architecture of GVT-g
  2016-03-11 10:59 [RFCv3 00/15] Introduce GVT context support Zhi Wang
  2016-03-11 10:59 ` [RFCv3 01/15] drm/i915: factor out i915_pvinfo.h Zhi Wang
@ 2016-03-11 10:59 ` Zhi Wang
  2016-03-11 10:59 ` [RFCv3 03/15] drm/i915: Introduce host graphics memory partition for GVT-g Zhi Wang
                   ` (13 subsequent siblings)
  15 siblings, 0 replies; 29+ messages in thread
From: Zhi Wang @ 2016-03-11 10:59 UTC (permalink / raw)
  To: intel-gfx, igvt-g; +Cc: daniel.vetter, david.j.cowperthwaite, zhiyuan.lv

This patch introduces the very basic framework of GVT-g device model,
includes basic prototypes, definitions, initialization.

v3:
Take Joonas' comments:
- Change file name i915_gvt.* to intel_gvt.*
- Move GVT kernel parameter into intel_gvt.c
- Remove redundant debug macros
- Change error handling style
- Add introductions for some stub functions
- Introduce drm/i915_gvt.h.

Take Kevin's comments:
- Move GVT-g host/guest check into intel_vgt_balloon in i915_gem_gtt.c

v2:
- Introduce i915_gvt.c.
It's necessary to introduce the stubs between i915 driver and GVT-g host,
as GVT-g components is configurable in kernel config. When disabled, the
stubs here do nothing.

Take Joonas' comments:
- Replace boolean return value with int.
- Replace customized info/warn/debug macros with DRM macros.
- Document all non-static functions like i915.
- Remove empty and unused functions.
- Replace magic number with marcos.
- Set GVT-g in kernel config to "n" by default.

Signed-off-by: Zhi Wang <zhi.a.wang@intel.com>
---
 drivers/gpu/drm/i915/Kconfig         |  15 +++
 drivers/gpu/drm/i915/Makefile        |   2 +
 drivers/gpu/drm/i915/gvt/Makefile    |   5 +
 drivers/gpu/drm/i915/gvt/debug.h     |  36 ++++++
 drivers/gpu/drm/i915/gvt/gvt.c       | 231 +++++++++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/gvt/gvt.h       |  82 +++++++++++++
 drivers/gpu/drm/i915/gvt/hypercall.h |  38 ++++++
 drivers/gpu/drm/i915/gvt/mpt.h       |  51 ++++++++
 drivers/gpu/drm/i915/i915_dma.c      |  15 +++
 drivers/gpu/drm/i915/i915_drv.h      |  12 ++
 drivers/gpu/drm/i915/i915_gem_gtt.c  |  11 +-
 drivers/gpu/drm/i915/i915_vgpu.c     |  10 +-
 drivers/gpu/drm/i915/i915_vgpu.h     |   2 +-
 drivers/gpu/drm/i915/intel_gvt.c     | 120 ++++++++++++++++++
 drivers/gpu/drm/i915/intel_gvt.h     |  54 ++++++++
 include/drm/i915_gvt.h               |  32 +++++
 16 files changed, 706 insertions(+), 10 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gvt/Makefile
 create mode 100644 drivers/gpu/drm/i915/gvt/debug.h
 create mode 100644 drivers/gpu/drm/i915/gvt/gvt.c
 create mode 100644 drivers/gpu/drm/i915/gvt/gvt.h
 create mode 100644 drivers/gpu/drm/i915/gvt/hypercall.h
 create mode 100644 drivers/gpu/drm/i915/gvt/mpt.h
 create mode 100644 drivers/gpu/drm/i915/intel_gvt.c
 create mode 100644 drivers/gpu/drm/i915/intel_gvt.h
 create mode 100644 include/drm/i915_gvt.h

diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig
index 20a5d04..26fdc33 100644
--- a/drivers/gpu/drm/i915/Kconfig
+++ b/drivers/gpu/drm/i915/Kconfig
@@ -56,3 +56,18 @@ config DRM_I915_USERPTR
 	  selected to enabled full userptr support.
 
 	  If in doubt, say "Y".
+
+config DRM_I915_GVT
+        tristate "Intel GVT-g host driver"
+        depends on DRM_I915
+        default n
+        help
+          Enabling GVT-g mediated graphics passthrough technique for Intel i915
+          based integrated graphics card. With GVT-g, it's possible to have one
+          integrated i915 device shared by multiple VMs. Performance critical
+          opterations such as apperture accesses and ring buffer operations
+          are pass-throughed to VM, with a minimal set of conflicting resources
+          (e.g. display settings) mediated by vGT driver. The benefit of vGT
+          is on both the performance, given that each VM could directly operate
+          its aperture space and submit commands like running on native, and
+          the feature completeness, given that a true GEN hardware is exposed.
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 0851de07..9927465 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -91,6 +91,8 @@ i915-y += dvo_ch7017.o \
 	  intel_sdvo.o \
 	  intel_tv.o
 
+obj-$(CONFIG_DRM_I915_GVT)  += intel_gvt.o gvt/
+
 # virtual gpu code
 i915-y += i915_vgpu.o
 
diff --git a/drivers/gpu/drm/i915/gvt/Makefile b/drivers/gpu/drm/i915/gvt/Makefile
new file mode 100644
index 0000000..09f59c3
--- /dev/null
+++ b/drivers/gpu/drm/i915/gvt/Makefile
@@ -0,0 +1,5 @@
+GVT_SOURCE := gvt.o
+
+ccflags-y                      += -I$(src) -I$(src)/.. -Wall -Werror -Wno-unused-function
+i915_gvt-y                     := $(GVT_SOURCE)
+obj-$(CONFIG_DRM_I915_GVT)     += i915_gvt.o
diff --git a/drivers/gpu/drm/i915/gvt/debug.h b/drivers/gpu/drm/i915/gvt/debug.h
new file mode 100644
index 0000000..5b067d2
--- /dev/null
+++ b/drivers/gpu/drm/i915/gvt/debug.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright(c) 2011-2016 Intel Corporation. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef __GVT_DEBUG_H__
+#define __GVT_DEBUG_H__
+
+#define gvt_info(fmt, args...) \
+	DRM_INFO("gvt: "fmt, ##args)
+
+#define gvt_err(fmt, args...) \
+	DRM_ERROR("gvt: "fmt, ##args)
+
+#define gvt_dbg_core(fmt, args...) \
+	DRM_DEBUG_DRIVER("gvt: core: "fmt, ##args)
+
+#endif
diff --git a/drivers/gpu/drm/i915/gvt/gvt.c b/drivers/gpu/drm/i915/gvt/gvt.c
new file mode 100644
index 0000000..bf16e85
--- /dev/null
+++ b/drivers/gpu/drm/i915/gvt/gvt.c
@@ -0,0 +1,231 @@
+/*
+ * Copyright(c) 2011-2016 Intel Corporation. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <linux/types.h>
+#include <xen/xen.h>
+#include <linux/kthread.h>
+
+#include "gvt.h"
+
+struct gvt_host gvt_host;
+
+static const char * const supported_hypervisors[] = {
+	[GVT_HYPERVISOR_TYPE_XEN] = "Xen",
+	[GVT_HYPERVISOR_TYPE_KVM] = "KVM",
+};
+
+static int gvt_init_host(void)
+{
+	if (WARN(gvt_host.initialized, "GVT host has been initialized!\n"))
+		return -EINVAL;
+
+	/* Xen DOM U */
+	if (xen_domain() && !xen_initial_domain())
+		return -ENODEV;
+
+	if (xen_initial_domain()) {
+		/* Xen Dom0 */
+		gvt_host.kdm = try_then_request_module(
+				symbol_get(xengt_kdm), "xengt");
+		gvt_host.hypervisor_type = GVT_HYPERVISOR_TYPE_XEN;
+	} else {
+		/* not in Xen. Try KVMGT */
+		gvt_host.kdm = try_then_request_module(
+				symbol_get(kvmgt_kdm), "kvm");
+		gvt_host.hypervisor_type = GVT_HYPERVISOR_TYPE_KVM;
+	}
+
+	if (!gvt_host.kdm) {
+		gvt_err("Fail to load any MPT modules.\n");
+		return -EINVAL;
+	}
+
+	if (!gvt_hypervisor_detect_host())
+		return -ENODEV;
+
+	gvt_info("Running with hypervisor %s in host mode\n",
+			supported_hypervisors[gvt_host.hypervisor_type]);
+
+	idr_init(&gvt_host.device_idr);
+	mutex_init(&gvt_host.device_idr_lock);
+
+	gvt_host.initialized = true;
+	return 0;
+}
+
+static int init_device_info(struct intel_gvt *pdev)
+{
+	struct gvt_device_info *info = &pdev->device_info;
+
+	if (IS_BROADWELL(pdev->dev_priv)) {
+		info->max_gtt_gm_sz = (1ULL << 32); /* 4GB */
+		/*
+		 * The layout of BAR0 in BDW:
+		 * |< - MMIO 2MB ->|<- Reserved 6MB ->|<- MAX GTT 8MB->|
+		 *
+		 * GTT offset in BAR0 starts from 8MB to 16MB, and
+		 * Whatever GTT size is configured in BIOS,
+		 * the size of BAR0 is always 16MB. The actual configured
+		 * GTT size can be found in GMCH_CTRL.
+		 */
+		info->gtt_start_offset = (1UL << 23); /* 8MB */
+		info->max_gtt_size = (1UL << 23); /* 8MB */
+		info->gtt_entry_size = 8;
+		info->gtt_entry_size_shift = 3;
+		info->gmadr_bytes_in_cmd = 8;
+		info->mmio_size = 2 * 1024 * 1024; /* 2MB */
+		info->max_support_vgpu = 8;
+	}
+
+	if (WARN_ON(info->max_support_vgpu > GVT_MAX_VGPU))
+		info->max_support_vgpu = GVT_MAX_VGPU;
+
+	return 0;
+}
+
+static void free_gvt_device(struct intel_gvt *pdev)
+{
+	struct gvt_host *host = &gvt_host;
+
+	mutex_lock(&host->device_idr_lock);
+	idr_remove(&host->device_idr, pdev->id);
+	mutex_unlock(&host->device_idr_lock);
+
+	vfree(pdev);
+}
+
+static struct intel_gvt *alloc_gvt_device(struct drm_i915_private *dev_priv)
+{
+	struct gvt_host *host = &gvt_host;
+	struct intel_gvt *pdev = NULL;
+	int ret;
+
+	pdev = vzalloc(sizeof(*pdev));
+	if (!pdev)
+		return ERR_PTR(-ENOMEM);
+
+	mutex_lock(&host->device_idr_lock);
+	ret = idr_alloc(&host->device_idr, pdev, 0, 0, GFP_KERNEL);
+	mutex_unlock(&host->device_idr_lock);
+
+	if (ret)
+		goto err;
+
+	pdev->id = ret;
+	mutex_init(&pdev->lock);
+	pdev->dev_priv = dev_priv;
+	idr_init(&pdev->vgpu_idr);
+
+	return pdev;
+err:
+	free_gvt_device(pdev);
+	return ERR_PTR(ret);
+}
+
+/**
+ * gvt_destroy_device - destroy a GVT device
+ * @gvt_device: gvt device
+ *
+ * This function is called at the driver unloading stage, to destroy a
+ * GVT device and free the related resources.
+ *
+ * Returns:
+ * None
+ */
+void gvt_destroy_device(void *gvt_device)
+{
+	struct intel_gvt *pdev = (struct intel_gvt *)gvt_device;
+
+	free_gvt_device(pdev);
+}
+
+/**
+ * gvt_create_device - create a GVT device
+ * @dev: drm device
+ *
+ * This function is called at the initialization stage, to create a
+ * GVT device and initialize necessary GVT components for it.
+ *
+ * Returns:
+ * pointer to the intel gvt device structure, NULL if failed.
+ */
+void *gvt_create_device(void *dev)
+{
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct intel_gvt *pdev = NULL;
+	int ret;
+
+	if (!gvt_host.initialized) {
+		ret = gvt_init_host();
+		if (ret)
+			return ERR_PTR(ret);
+	}
+
+	gvt_dbg_core("create new gvt device, i915 dev_priv: %p\n", dev_priv);
+
+	pdev = alloc_gvt_device(dev_priv);
+	if (IS_ERR(pdev)) {
+		ret = PTR_ERR(pdev);
+		goto err_alloc_gvt_device;
+	}
+
+	gvt_dbg_core("init gvt device, id %d\n", pdev->id);
+
+	ret = init_device_info(pdev);
+	if (ret)
+		goto err_init_device_info;
+
+	gvt_dbg_core("gvt device creation done, id %d\n", pdev->id);
+
+	return pdev;
+
+err_init_device_info:
+	free_gvt_device(pdev);
+err_alloc_gvt_device:
+	return ERR_PTR(ret);
+}
+
+/**
+ * gvt_post_init_device - post init a GVT device
+ * @dev: drm device
+ *
+ * This function is called at the end of the initialization stage, to
+ * post-initialize a GVT device and initialize necessary GVT components
+ * rely on i915 components.
+ *
+ * Returns:
+ * zero on success, non-zero if failed.
+ */
+int gvt_post_init_device(void *gvt_device)
+{
+	struct intel_gvt *pdev = (struct intel_gvt *)gvt_device;
+
+	if (!gvt_host.initialized) {
+		gvt_err("GVT host hasn't been initialized\n");
+		return -ENODEV;
+	}
+
+	gvt_dbg_core("post init gvt device %d\n", pdev->id);
+
+	return 0;
+}
diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h
new file mode 100644
index 0000000..5f5b25e
--- /dev/null
+++ b/drivers/gpu/drm/i915/gvt/gvt.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright(c) 2011-2016 Intel Corporation. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef _GVT_H_
+#define _GVT_H_
+
+#include "i915_drv.h"
+#include "i915_vgpu.h"
+
+#include "debug.h"
+#include "hypercall.h"
+
+#define GVT_MAX_VGPU 8
+
+enum {
+	GVT_HYPERVISOR_TYPE_XEN = 0,
+	GVT_HYPERVISOR_TYPE_KVM,
+};
+
+struct gvt_host {
+	bool initialized;
+	int hypervisor_type;
+	struct mutex device_idr_lock;
+	struct idr device_idr;
+	struct gvt_kernel_dm *kdm;
+};
+
+extern struct gvt_host gvt_host;
+
+/* Describe the limitation of HW.*/
+struct gvt_device_info {
+	u64 max_gtt_gm_sz;
+	u32 gtt_start_offset;
+	u32 gtt_end_offset;
+	u32 max_gtt_size;
+	u32 gtt_entry_size;
+	u32 gtt_entry_size_shift;
+	u32 gmadr_bytes_in_cmd;
+	u32 mmio_size;
+	u32 max_support_vgpu;
+};
+
+struct intel_vgpu {
+	struct intel_gvt *pdev;
+	int id;
+	int vm_id;
+	bool warn_untrack;
+};
+
+struct intel_gvt {
+	struct mutex lock;
+	int id;
+
+	struct drm_i915_private *dev_priv;
+	struct idr vgpu_idr;
+
+	struct gvt_device_info device_info;
+};
+
+#include "mpt.h"
+
+#endif
diff --git a/drivers/gpu/drm/i915/gvt/hypercall.h b/drivers/gpu/drm/i915/gvt/hypercall.h
new file mode 100644
index 0000000..3fefcc3
--- /dev/null
+++ b/drivers/gpu/drm/i915/gvt/hypercall.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright(c) 2011-2016 Intel Corporation. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef _GVT_HYPERCALL_H_
+#define _GVT_HYPERCALL_H_
+
+/*
+ * Specific GVT-g MPT modules function collections. Currently GVT-g supports
+ * both Xen and KVM by providing dedicated hypervisor-related MPT modules.
+ */
+struct gvt_kernel_dm {
+	int (*detect_host)(void);
+};
+
+extern struct gvt_kernel_dm xengt_kdm;
+extern struct gvt_kernel_dm kvmgt_kdm;
+
+#endif /* _GVT_HYPERCALL_H_ */
diff --git a/drivers/gpu/drm/i915/gvt/mpt.h b/drivers/gpu/drm/i915/gvt/mpt.h
new file mode 100644
index 0000000..8edde2f
--- /dev/null
+++ b/drivers/gpu/drm/i915/gvt/mpt.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright(c) 2011-2016 Intel Corporation. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef _GVT_MPT_H_
+#define _GVT_MPT_H_
+
+/**
+ * DOC: Hypervisor Service APIs for GVT-g Core Logic
+ *
+ * This is the glue layer between specific hypervisor MPT modules and GVT-g core
+ * logic. Each kind of hypervisor MPT module provides a collection of function
+ * callbacks via gvt_kernel_dm and will be attached to GVT host when driver
+ * loading. GVT-g core logic will call these APIs to request specific services
+ * from hypervisor.
+ */
+
+/**
+ * gvt_hypervisor_detect_host - check if GVT-g is running within hypervisor
+ * host/privilged domain
+ *
+ * Returns:
+ * Zero on success, -ENODEV if current kernel is running inside a VM
+ */
+static inline int gvt_hypervisor_detect_host(void)
+{
+	if (WARN_ON(!gvt_host.kdm))
+		return -ENODEV;
+	return gvt_host.kdm->detect_host();
+}
+
+#endif /* _GVT_MPT_H_ */
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index 1c6d227..c34a4a1 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -35,6 +35,7 @@
 #include "intel_drv.h"
 #include <drm/i915_drm.h>
 #include "i915_drv.h"
+#include "intel_gvt.h"
 #include "i915_vgpu.h"
 #include "i915_trace.h"
 #include <linux/pci.h>
@@ -1045,6 +1046,10 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
 
 	intel_uncore_init(dev);
 
+	ret = intel_gvt_init(dev);
+	if (ret)
+		goto out_gvt_cleanup;
+
 	ret = i915_gem_gtt_init(dev);
 	if (ret)
 		goto out_uncore_fini;
@@ -1135,6 +1140,12 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
 		goto out_power_well;
 	}
 
+	ret = intel_gvt_post_init(dev);
+	if (ret) {
+		DRM_ERROR("failed to post init pgt device\n");
+		goto out_power_well;
+	}
+
 	/*
 	 * Notify a valid surface after modesetting,
 	 * when running inside a VM.
@@ -1176,6 +1187,8 @@ out_gem_unload:
 	io_mapping_free(dev_priv->gtt.mappable);
 out_gtt:
 	i915_global_gtt_cleanup(dev);
+out_gvt_cleanup:
+	intel_gvt_cleanup(dev);
 out_uncore_fini:
 	intel_uncore_fini(dev);
 	i915_mmio_cleanup(dev);
@@ -1223,6 +1236,8 @@ int i915_driver_unload(struct drm_device *dev)
 
 	intel_modeset_cleanup(dev);
 
+	intel_gvt_cleanup(dev);
+
 	/*
 	 * free the memory space allocated for the child device
 	 * config parsed from VBT
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 9e76bfc..88f9041 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1709,6 +1709,10 @@ struct i915_workarounds {
 	u32 hw_whitelist_count[I915_NUM_RINGS];
 };
 
+struct i915_gvt {
+	void *gvt_device;
+};
+
 struct i915_virtual_gpu {
 	bool active;
 };
@@ -1748,6 +1752,8 @@ struct drm_i915_private {
 
 	struct i915_virtual_gpu vgpu;
 
+	struct i915_gvt gvt;
+
 	struct intel_guc guc;
 
 	struct intel_csr csr;
@@ -2785,6 +2791,12 @@ void intel_uncore_forcewake_get__locked(struct drm_i915_private *dev_priv,
 void intel_uncore_forcewake_put__locked(struct drm_i915_private *dev_priv,
 					enum forcewake_domains domains);
 void assert_forcewakes_inactive(struct drm_i915_private *dev_priv);
+
+static inline bool intel_gvt_active(struct drm_device *dev)
+{
+	return to_i915(dev)->gvt.gvt_device ? true : false;
+}
+
 static inline bool intel_vgpu_active(struct drm_device *dev)
 {
 	return to_i915(dev)->vgpu.active;
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 9127f8f..d03fe61 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -2734,11 +2734,9 @@ static int i915_gem_setup_global_gtt(struct drm_device *dev,
 	i915_address_space_init(ggtt_vm, dev_priv);
 	ggtt_vm->total += PAGE_SIZE;
 
-	if (intel_vgpu_active(dev)) {
-		ret = intel_vgt_balloon(dev);
-		if (ret)
-			return ret;
-	}
+	ret = intel_vgt_balloon(dev);
+	if (ret)
+		return ret;
 
 	if (!HAS_LLC(dev))
 		ggtt_vm->mm.color_adjust = i915_gtt_color_adjust;
@@ -2833,8 +2831,7 @@ void i915_global_gtt_cleanup(struct drm_device *dev)
 	i915_gem_cleanup_stolen(dev);
 
 	if (drm_mm_initialized(&vm->mm)) {
-		if (intel_vgpu_active(dev))
-			intel_vgt_deballoon();
+		intel_vgt_deballoon(dev);
 
 		drm_mm_takedown(&vm->mm);
 		list_del(&vm->global_link);
diff --git a/drivers/gpu/drm/i915/i915_vgpu.c b/drivers/gpu/drm/i915/i915_vgpu.c
index dea7429..836defe 100644
--- a/drivers/gpu/drm/i915/i915_vgpu.c
+++ b/drivers/gpu/drm/i915/i915_vgpu.c
@@ -102,10 +102,13 @@ static struct _balloon_info_ bl_info;
  * This function is called to deallocate the ballooned-out graphic memory, when
  * driver is unloaded or when ballooning fails.
  */
-void intel_vgt_deballoon(void)
+void intel_vgt_deballoon(struct drm_device *dev)
 {
 	int i;
 
+	if (!intel_vgpu_active(dev) && !intel_gvt_active(dev))
+		return;
+
 	DRM_DEBUG("VGT deballoon.\n");
 
 	for (i = 0; i < 4; i++) {
@@ -188,6 +191,9 @@ int intel_vgt_balloon(struct drm_device *dev)
 	unsigned long unmappable_base, unmappable_size, unmappable_end;
 	int ret;
 
+	if (!intel_vgpu_active(dev) && !intel_gvt_active(dev))
+		return 0;
+
 	mappable_base = I915_READ(vgtif_reg(avail_rs.mappable_gmadr.base));
 	mappable_size = I915_READ(vgtif_reg(avail_rs.mappable_gmadr.size));
 	unmappable_base = I915_READ(vgtif_reg(avail_rs.nonmappable_gmadr.base));
@@ -259,6 +265,6 @@ int intel_vgt_balloon(struct drm_device *dev)
 
 err:
 	DRM_ERROR("VGT balloon fail\n");
-	intel_vgt_deballoon();
+	intel_vgt_deballoon(dev);
 	return ret;
 }
diff --git a/drivers/gpu/drm/i915/i915_vgpu.h b/drivers/gpu/drm/i915/i915_vgpu.h
index a3b06f3..484acc2 100644
--- a/drivers/gpu/drm/i915/i915_vgpu.h
+++ b/drivers/gpu/drm/i915/i915_vgpu.h
@@ -28,6 +28,6 @@
 
 extern void i915_check_vgpu(struct drm_device *dev);
 extern int intel_vgt_balloon(struct drm_device *dev);
-extern void intel_vgt_deballoon(void);
+extern void intel_vgt_deballoon(struct drm_device *dev);
 
 #endif /* _I915_VGPU_H_ */
diff --git a/drivers/gpu/drm/i915/intel_gvt.c b/drivers/gpu/drm/i915/intel_gvt.c
new file mode 100644
index 0000000..a89b0ad
--- /dev/null
+++ b/drivers/gpu/drm/i915/intel_gvt.c
@@ -0,0 +1,120 @@
+/*
+ * Copyright(c) 2011-2016 Intel Corporation. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include "i915_drv.h"
+#include "intel_gvt.h"
+
+/**
+ * DOC: Intel GVT-g host support
+ *
+ * Intel GVT-g is a graphics virtualization technology which shares the
+ * GPU among multiple virtual machines on a time-sharing basis. Each
+ * virtual machine is presented a virtual GPU (vGPU), which has equivalent
+ * features as the underlying physical GPU (pGPU), so i915 driver can run
+ * seamlessly in a virtual machine. This file provides the englightments
+ * of GVT and the necessary components used by GVT in i915 driver.
+ */
+
+struct gvt_kernel_params gvt = {
+	.enable = false,
+};
+
+/* i915.gvt_enable */
+module_param_named(gvt_enable, gvt.enable, bool, 0600);
+MODULE_PARM_DESC(gvt_enable, "Enable Intel GVT-g host support");
+
+static bool is_supported_device(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = to_i915(dev);
+
+	if (IS_BROADWELL(dev_priv))
+		return true;
+
+	return false;
+}
+/**
+ * intel_gvt_init - initialize GVT components at the beginning of i915
+ * driver loading.
+ * @dev: drm device *
+ *
+ * This function is called at the beginning of the initialization stage,
+ * to initialize the GVT components that have to be initialized
+ * before HW gets touched by other i915 components.
+ */
+int intel_gvt_init(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = to_i915(dev);
+
+	if (!gvt.enable) {
+		DRM_DEBUG_DRIVER("GVT-g is disabled by kernel params\n");
+		return 0;
+	}
+
+	if (!is_supported_device(dev)) {
+		DRM_DEBUG_DRIVER("Unsupported device. GVT-g is disabled\n");
+		return 0;
+	}
+
+	dev_priv->gvt.gvt_device = gvt_create_device(dev);
+	if (intel_gvt_active(dev))
+		DRM_DEBUG_DRIVER("GVT-g is running in host mode\n");
+
+	return 0;
+}
+
+/**
+ * intel_gvt_post_init - initialize GVT components at the end of i915
+ * driver loading.
+ * @dev: drm device *
+ *
+ * This function is called at the end of the initialization stage,
+ * to initialize the GVT components that have to be initialized after
+ * other i915 components are ready.
+ */
+int intel_gvt_post_init(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = to_i915(dev);
+
+	if (!intel_gvt_active(dev))
+		return 0;
+
+	return gvt_post_init_device(dev_priv->gvt.gvt_device);
+}
+
+/**
+ * intel_gvt_cleanup - cleanup GVT components when i915 driver is unloading
+ * @dev: drm device *
+ *
+ * This function is called at the i915 driver unloading stage, to shutdown
+ * GVT components and release the related resources.
+ */
+void intel_gvt_cleanup(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = to_i915(dev);
+
+	if (!intel_gvt_active(dev))
+		return;
+
+	gvt_destroy_device(dev_priv->gvt.gvt_device);
+	dev_priv->gvt.gvt_device = NULL;
+}
diff --git a/drivers/gpu/drm/i915/intel_gvt.h b/drivers/gpu/drm/i915/intel_gvt.h
new file mode 100644
index 0000000..9be5a4f
--- /dev/null
+++ b/drivers/gpu/drm/i915/intel_gvt.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright(c) 2011-2016 Intel Corporation. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef _INTEL_GVT_H_
+#define _INTEL_GVT_H_
+
+#ifdef CONFIG_DRM_I915_GVT
+
+#include <drm/i915_gvt.h>
+
+struct gvt_kernel_params {
+	bool enable;
+};
+
+extern struct gvt_kernel_params gvt;
+
+extern int intel_gvt_init(struct drm_device *dev);
+extern int intel_gvt_post_init(struct drm_device *dev);
+extern void intel_gvt_cleanup(struct drm_device *dev);
+#else
+static inline int intel_gvt_init(struct drm_device *dev)
+{
+	return 0;
+}
+static inline int intel_gvt_post_init(struct drm_device *dev)
+{
+	return 0;
+}
+static inline void intel_gvt_cleanup(struct drm_device *dev)
+{
+}
+#endif
+
+#endif /* _INTEL_GVT_H_ */
diff --git a/include/drm/i915_gvt.h b/include/drm/i915_gvt.h
new file mode 100644
index 0000000..28c8d7a
--- /dev/null
+++ b/include/drm/i915_gvt.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright(c) 2011-2016 Intel Corporation. All rights reserved.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+#ifndef _I915_GVT_H
+#define _I915_GVT_H
+
+extern void *gvt_create_device(void *dev);
+extern int gvt_post_init_device(void *gvt_device);
+extern void gvt_destroy_device(void *gvt_device);
+
+#endif /* _I915_GVT_H */
-- 
1.9.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [RFCv3 03/15] drm/i915: Introduce host graphics memory partition for GVT-g
  2016-03-11 10:59 [RFCv3 00/15] Introduce GVT context support Zhi Wang
  2016-03-11 10:59 ` [RFCv3 01/15] drm/i915: factor out i915_pvinfo.h Zhi Wang
  2016-03-11 10:59 ` [RFCv3 02/15] drm/i915/gvt: Introduce the basic architecture of GVT-g Zhi Wang
@ 2016-03-11 10:59 ` Zhi Wang
  2016-03-11 10:59 ` [RFCv3 04/15] drm/i915: factor out alloc_context_idr() and __i915_gem_create_context() Zhi Wang
                   ` (12 subsequent siblings)
  15 siblings, 0 replies; 29+ messages in thread
From: Zhi Wang @ 2016-03-11 10:59 UTC (permalink / raw)
  To: intel-gfx, igvt-g; +Cc: daniel.vetter, david.j.cowperthwaite, zhiyuan.lv

From: Bing Niu <bing.niu@intel.com>

This patch introduces host graphics memory partition when GVT-g
is enabled.

Under GVT-g, i915 host driver only owned limited graphics resources,
others are managed by GVT-g resource allocator and kept for other vGPUs.

v3:

- Remove fence partition, will use i915 fence stealing in future.(Kevin)
- Santinize GVT host gm kernel parameters. (Joonas)

v2:
- Address all coding-style comments from Joonas previously.
- Fix errors and warnning reported by checkpatch.pl. (Joonas)
- Move the graphs into the header files. (Daniel)

Signed-off-by: Bing Niu <bing.niu@intel.com>
Signed-off-by: Zhi Wang <zhi.a.wang@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h  | 22 ++++++++++++++++++++
 drivers/gpu/drm/i915/i915_vgpu.c | 21 ++++++++++++++++----
 drivers/gpu/drm/i915/intel_gvt.c | 43 ++++++++++++++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_gvt.h |  2 ++
 4 files changed, 84 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 88f9041..972b4ce 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1709,8 +1709,30 @@ struct i915_workarounds {
 	u32 hw_whitelist_count[I915_NUM_RINGS];
 };
 
+/*
+ * Under GVT-g, i915 host driver only owned limited graphics resources,
+ * others are managed by GVT-g resource allocator and kept for other vGPUs.
+ *
+ * For graphics memory space partition, a typical layout looks like:
+ *
+ * +-------+-----------------------+------+-----------------------+
+ * |* Host |   *GVT-g Resource     |* Host|   *GVT-g Resource     |
+ * | Owned |   Allocator Managed   | Owned|   Allocator Managed   |
+ * |       |                       |      |                       |
+ * +---------------+-------+----------------------+-------+-------+
+ * |       |       |       |       |      |       |       |       |
+ * | i915  | vm 1  | vm 2  | vm 3  | i915 | vm 1  | vm 2  | vm 3  |
+ * |       |       |       |       |      |       |       |       |
+ * +-------+-------+-------+--------------+-------+-------+-------+
+ * |           Aperture            |            Hidden            |
+ * +-------------------------------+------------------------------+
+ * |                       GGTT memory space                      |
+ * +--------------------------------------------------------------+
+ */
 struct i915_gvt {
 	void *gvt_device;
+	u64 low_gm_size;
+	u64 high_gm_size;
 };
 
 struct i915_virtual_gpu {
diff --git a/drivers/gpu/drm/i915/i915_vgpu.c b/drivers/gpu/drm/i915/i915_vgpu.c
index 836defe..5b364b4 100644
--- a/drivers/gpu/drm/i915/i915_vgpu.c
+++ b/drivers/gpu/drm/i915/i915_vgpu.c
@@ -194,10 +194,23 @@ int intel_vgt_balloon(struct drm_device *dev)
 	if (!intel_vgpu_active(dev) && !intel_gvt_active(dev))
 		return 0;
 
-	mappable_base = I915_READ(vgtif_reg(avail_rs.mappable_gmadr.base));
-	mappable_size = I915_READ(vgtif_reg(avail_rs.mappable_gmadr.size));
-	unmappable_base = I915_READ(vgtif_reg(avail_rs.nonmappable_gmadr.base));
-	unmappable_size = I915_READ(vgtif_reg(avail_rs.nonmappable_gmadr.size));
+	if (intel_gvt_active(dev)) {
+		mappable_base = 0;
+		mappable_size = dev_priv->gvt.low_gm_size;
+		unmappable_base = dev_priv->gtt.mappable_end;
+		unmappable_size = dev_priv->gvt.high_gm_size;
+	} else if (intel_vgpu_active(dev)) {
+		mappable_base = I915_READ(
+			vgtif_reg(avail_rs.mappable_gmadr.base));
+		mappable_size = I915_READ(
+			vgtif_reg(avail_rs.mappable_gmadr.size));
+		unmappable_base = I915_READ(
+			vgtif_reg(avail_rs.nonmappable_gmadr.base));
+		unmappable_size = I915_READ(
+			vgtif_reg(avail_rs.nonmappable_gmadr.size));
+	} else {
+		return -ENODEV;
+	}
 
 	mappable_end = mappable_base + mappable_size;
 	unmappable_end = unmappable_base + unmappable_size;
diff --git a/drivers/gpu/drm/i915/intel_gvt.c b/drivers/gpu/drm/i915/intel_gvt.c
index a89b0ad..8efc1cb 100644
--- a/drivers/gpu/drm/i915/intel_gvt.c
+++ b/drivers/gpu/drm/i915/intel_gvt.c
@@ -43,6 +43,46 @@ struct gvt_kernel_params gvt = {
 module_param_named(gvt_enable, gvt.enable, bool, 0600);
 MODULE_PARM_DESC(gvt_enable, "Enable Intel GVT-g host support");
 
+/* i915.gvt_low_gm_size */
+module_param_named(gvt_low_gm_size, gvt.low_gm_size, charp, 0600);
+MODULE_PARM_DESC(gvt_low_gm_size, "GVT low graphics memory size");
+
+/* i915.gvt_high_gm_size */
+module_param_named(gvt_high_gm_size, gvt.high_gm_size, charp, 0600);
+MODULE_PARM_DESC(gvt_high_gm_size, "GVT high graphics memory size");
+
+#define KB(x) ((x) * 1024)
+#define MB(x) (KB(x) * 1024)
+
+#define MAX_GVT_LOW_GM_SIZE	MB(96)
+#define MAX_GVT_HIGH_GM_SIZE	MB(384)
+
+static void setup_gm_size(struct drm_i915_private *dev_priv)
+{
+	u64 low_gm_size, high_gm_size;
+
+	low_gm_size = high_gm_size = 0;
+
+	/* Try to parse kernel parameter first */
+	if (gvt.low_gm_size)
+		low_gm_size = memparse(gvt.low_gm_size, NULL);
+
+	if (gvt.high_gm_size)
+		high_gm_size = memparse(gvt.high_gm_size, NULL);
+
+	if (!low_gm_size || low_gm_size > MAX_GVT_LOW_GM_SIZE)
+		low_gm_size = MAX_GVT_LOW_GM_SIZE;
+
+	if (!high_gm_size || high_gm_size > MAX_GVT_HIGH_GM_SIZE)
+		high_gm_size = MAX_GVT_HIGH_GM_SIZE;
+
+	dev_priv->gvt.low_gm_size = low_gm_size;
+	dev_priv->gvt.high_gm_size = high_gm_size;
+
+	DRM_DEBUG_DRIVER("GVT low graphics memory size: %llx\n", low_gm_size);
+	DRM_DEBUG_DRIVER("GVT high graphics memory size: %llx\n", high_gm_size);
+}
+
 static bool is_supported_device(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = to_i915(dev);
@@ -52,6 +92,7 @@ static bool is_supported_device(struct drm_device *dev)
 
 	return false;
 }
+
 /**
  * intel_gvt_init - initialize GVT components at the beginning of i915
  * driver loading.
@@ -75,6 +116,8 @@ int intel_gvt_init(struct drm_device *dev)
 		return 0;
 	}
 
+	setup_gm_size(dev_priv);
+
 	dev_priv->gvt.gvt_device = gvt_create_device(dev);
 	if (intel_gvt_active(dev))
 		DRM_DEBUG_DRIVER("GVT-g is running in host mode\n");
diff --git a/drivers/gpu/drm/i915/intel_gvt.h b/drivers/gpu/drm/i915/intel_gvt.h
index 9be5a4f..2b98244 100644
--- a/drivers/gpu/drm/i915/intel_gvt.h
+++ b/drivers/gpu/drm/i915/intel_gvt.h
@@ -30,6 +30,8 @@
 
 struct gvt_kernel_params {
 	bool enable;
+	char *low_gm_size;
+	char *high_gm_size;
 };
 
 extern struct gvt_kernel_params gvt;
-- 
1.9.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [RFCv3 04/15] drm/i915: factor out alloc_context_idr() and __i915_gem_create_context()
  2016-03-11 10:59 [RFCv3 00/15] Introduce GVT context support Zhi Wang
                   ` (2 preceding siblings ...)
  2016-03-11 10:59 ` [RFCv3 03/15] drm/i915: Introduce host graphics memory partition for GVT-g Zhi Wang
@ 2016-03-11 10:59 ` Zhi Wang
  2016-03-11 10:59 ` [RFCv3 05/15] drm/i915: factor out __create_legacy_hw_context() Zhi Wang
                   ` (11 subsequent siblings)
  15 siblings, 0 replies; 29+ messages in thread
From: Zhi Wang @ 2016-03-11 10:59 UTC (permalink / raw)
  To: intel-gfx, igvt-g; +Cc: daniel.vetter, david.j.cowperthwaite, zhiyuan.lv

For flexible GEM context creation, we factor out __i915_gem_create_context
as the core logic of creation a GEM context. After the refactor, it more
likes a context creation service, which is able to create context by
explicit requirement of upper level components.

For the assumptions in original implementation, we keep them in the upper
level wrapper: i915_gem_create_context().

alloc_context_idr() is another function factored out to setup a IDR for
ordinary GEM context. Some context, e.g. GVT context, will not be
manipulated by user space application, so it doesn't need an IDR.

Signed-off-by: Zhi Wang <zhi.a.wang@intel.com>
---
 drivers/gpu/drm/i915/i915_gem_context.c | 62 ++++++++++++++++++++++++---------
 1 file changed, 45 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
index 4be2ce9..38e9fe1 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -235,17 +235,7 @@ __create_hw_context(struct drm_device *dev,
 		ctx->legacy_hw_ctx.rcs_state = obj;
 	}
 
-	/* Default context will never have a file_priv */
-	if (file_priv != NULL) {
-		ret = idr_alloc(&file_priv->context_idr, ctx,
-				DEFAULT_CONTEXT_HANDLE, 0, GFP_KERNEL);
-		if (ret < 0)
-			goto err_out;
-	} else
-		ret = DEFAULT_CONTEXT_HANDLE;
-
 	ctx->file_priv = file_priv;
-	ctx->user_handle = ret;
 	/* NB: Mark all slices as needing a remap so that when the context first
 	 * loads it will restore whatever remap state already exists. If there
 	 * is no remap info, it will be a NOP. */
@@ -260,13 +250,8 @@ err_out:
 	return ERR_PTR(ret);
 }
 
-/**
- * The default context needs to exist per ring that uses contexts. It stores the
- * context state of the GPU for applications that don't utilize HW contexts, as
- * well as an idle case.
- */
 static struct intel_context *
-i915_gem_create_context(struct drm_device *dev,
+__i915_gem_create_context(struct drm_device *dev,
 			struct drm_i915_file_private *file_priv)
 {
 	const bool is_global_default_ctx = file_priv == NULL;
@@ -316,11 +301,54 @@ err_unpin:
 	if (is_global_default_ctx && ctx->legacy_hw_ctx.rcs_state)
 		i915_gem_object_ggtt_unpin(ctx->legacy_hw_ctx.rcs_state);
 err_destroy:
-	idr_remove(&file_priv->context_idr, ctx->user_handle);
 	i915_gem_context_unreference(ctx);
 	return ERR_PTR(ret);
 }
 
+static inline int alloc_context_idr(struct drm_device *dev,
+	struct intel_context *ctx)
+{
+	int ret;
+
+	/* Default context will never have a file_priv */
+	if (ctx->file_priv != NULL) {
+		ret = idr_alloc(&ctx->file_priv->context_idr, ctx,
+				DEFAULT_CONTEXT_HANDLE, 0, GFP_KERNEL);
+		if (ret < 0)
+			return ret;
+	} else {
+		ret = DEFAULT_CONTEXT_HANDLE;
+	}
+
+	ctx->user_handle = ret;
+	return 0;
+}
+
+/**
+ * The default context needs to exist per ring that uses contexts. It stores the
+ * context state of the GPU for applications that don't utilize HW contexts, as
+ * well as an idle case.
+ */
+static struct intel_context *
+i915_gem_create_context(struct drm_device *dev,
+		struct drm_i915_file_private *file_priv)
+{
+	struct intel_context *ctx;
+	int ret;
+
+	ctx = __i915_gem_create_context(dev, file_priv);
+	if (IS_ERR(ctx))
+		return ctx;
+
+	ret = alloc_context_idr(dev, ctx);
+	if (ret < 0) {
+		i915_gem_context_unreference(ctx);
+		return ERR_PTR(ret);
+	}
+
+	return ctx;
+}
+
 static void i915_gem_context_unpin(struct intel_context *ctx,
 				   struct intel_engine_cs *engine)
 {
-- 
1.9.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [RFCv3 05/15] drm/i915: factor out __create_legacy_hw_context()
  2016-03-11 10:59 [RFCv3 00/15] Introduce GVT context support Zhi Wang
                   ` (3 preceding siblings ...)
  2016-03-11 10:59 ` [RFCv3 04/15] drm/i915: factor out alloc_context_idr() and __i915_gem_create_context() Zhi Wang
@ 2016-03-11 10:59 ` Zhi Wang
  2016-03-11 10:59 ` [RFCv3 06/15] drm/i915: let __i915_gem_context_create() takes context creation params Zhi Wang
                   ` (10 subsequent siblings)
  15 siblings, 0 replies; 29+ messages in thread
From: Zhi Wang @ 2016-03-11 10:59 UTC (permalink / raw)
  To: intel-gfx, igvt-g; +Cc: daniel.vetter, david.j.cowperthwaite, zhiyuan.lv

As creating the legacy HW context has become into an option in GEM context
creating service and will only be used in legacy ring buffer mode,
we factor out __create_legacy_hw_context() from __create_hw_context() for
better code structure.

Signed-off-by: Zhi Wang <zhi.a.wang@intel.com>
---
 drivers/gpu/drm/i915/i915_gem_context.c | 43 ++++++++++++++++++---------------
 1 file changed, 24 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
index 38e9fe1..5516346 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -209,13 +209,26 @@ i915_gem_alloc_context_obj(struct drm_device *dev, size_t size)
 	return obj;
 }
 
+static int __create_legacy_hw_context(struct drm_device *dev,
+		struct intel_context *ctx)
+{
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct drm_i915_gem_object *obj =
+		i915_gem_alloc_context_obj(dev, dev_priv->hw_context_size);
+
+	if (IS_ERR(obj))
+		return PTR_ERR(obj);
+
+	ctx->legacy_hw_ctx.rcs_state = obj;
+	return 0;
+}
+
 static struct intel_context *
 __create_hw_context(struct drm_device *dev,
 		    struct drm_i915_file_private *file_priv)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_context *ctx;
-	int ret;
 
 	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
 	if (ctx == NULL)
@@ -224,37 +237,23 @@ __create_hw_context(struct drm_device *dev,
 	kref_init(&ctx->ref);
 	list_add_tail(&ctx->link, &dev_priv->context_list);
 	ctx->i915 = dev_priv;
-
-	if (dev_priv->hw_context_size) {
-		struct drm_i915_gem_object *obj =
-				i915_gem_alloc_context_obj(dev, dev_priv->hw_context_size);
-		if (IS_ERR(obj)) {
-			ret = PTR_ERR(obj);
-			goto err_out;
-		}
-		ctx->legacy_hw_ctx.rcs_state = obj;
-	}
-
 	ctx->file_priv = file_priv;
 	/* NB: Mark all slices as needing a remap so that when the context first
 	 * loads it will restore whatever remap state already exists. If there
 	 * is no remap info, it will be a NOP. */
 	ctx->remap_slice = (1 << NUM_L3_SLICES(dev)) - 1;
-
 	ctx->hang_stats.ban_period_seconds = DRM_I915_CTX_BAN_PERIOD;
 
 	return ctx;
-
-err_out:
-	i915_gem_context_unreference(ctx);
-	return ERR_PTR(ret);
 }
 
 static struct intel_context *
 __i915_gem_create_context(struct drm_device *dev,
 			struct drm_i915_file_private *file_priv)
 {
+	struct drm_i915_private *dev_priv = to_i915(dev);
 	const bool is_global_default_ctx = file_priv == NULL;
+	const bool is_legacy_ctx = !!dev_priv->hw_context_size;
 	struct intel_context *ctx;
 	int ret = 0;
 
@@ -264,7 +263,13 @@ __i915_gem_create_context(struct drm_device *dev,
 	if (IS_ERR(ctx))
 		return ctx;
 
-	if (is_global_default_ctx && ctx->legacy_hw_ctx.rcs_state) {
+	if (is_legacy_ctx) {
+		ret = __create_legacy_hw_context(dev, ctx);
+		if (ret)
+			goto err_destroy;
+	}
+
+	if (is_global_default_ctx && is_legacy_ctx) {
 		/* We may need to do things with the shrinker which
 		 * require us to immediately switch back to the default
 		 * context. This can cause a problem as pinning the
@@ -298,7 +303,7 @@ __i915_gem_create_context(struct drm_device *dev,
 	return ctx;
 
 err_unpin:
-	if (is_global_default_ctx && ctx->legacy_hw_ctx.rcs_state)
+	if (is_global_default_ctx && is_legacy_ctx)
 		i915_gem_object_ggtt_unpin(ctx->legacy_hw_ctx.rcs_state);
 err_destroy:
 	i915_gem_context_unreference(ctx);
-- 
1.9.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [RFCv3 06/15] drm/i915: let __i915_gem_context_create() takes context creation params
  2016-03-11 10:59 [RFCv3 00/15] Introduce GVT context support Zhi Wang
                   ` (4 preceding siblings ...)
  2016-03-11 10:59 ` [RFCv3 05/15] drm/i915: factor out __create_legacy_hw_context() Zhi Wang
@ 2016-03-11 10:59 ` Zhi Wang
  2016-03-11 10:59 ` [RFCv3 07/15] drm/i915: factor out __intel_lr_context_deferred_alloc() Zhi Wang
                   ` (9 subsequent siblings)
  15 siblings, 0 replies; 29+ messages in thread
From: Zhi Wang @ 2016-03-11 10:59 UTC (permalink / raw)
  To: intel-gfx, igvt-g; +Cc: daniel.vetter, david.j.cowperthwaite, zhiyuan.lv

Let the core logic of context creation service creates the GEM context by
context creation params.

Now it provides following options for context creation:
- Need to create legacy context for this GEM context?
- Need to create PPGTT instance for this GEM context?
- Need to treat this context as the global default context?

And for all the assumptions in the original implementation, we keep them
in the upper-level wrapper.

Signed-off-by: Zhi Wang <zhi.a.wang@intel.com>
---
 drivers/gpu/drm/i915/i915_gem_context.c | 71 ++++++++++++++++++++-------------
 1 file changed, 43 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
index 5516346..e7415b1a 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -223,6 +223,13 @@ static int __create_legacy_hw_context(struct drm_device *dev,
 	return 0;
 }
 
+struct i915_gem_context_create_params {
+	struct drm_i915_file_private *file_priv;
+	bool has_legacy_ctx;
+	bool has_ppgtt;
+	bool is_global_default_ctx;
+};
+
 static struct intel_context *
 __create_hw_context(struct drm_device *dev,
 		    struct drm_i915_file_private *file_priv)
@@ -249,44 +256,43 @@ __create_hw_context(struct drm_device *dev,
 
 static struct intel_context *
 __i915_gem_create_context(struct drm_device *dev,
-			struct drm_i915_file_private *file_priv)
+			struct i915_gem_context_create_params *params)
 {
-	struct drm_i915_private *dev_priv = to_i915(dev);
-	const bool is_global_default_ctx = file_priv == NULL;
-	const bool is_legacy_ctx = !!dev_priv->hw_context_size;
 	struct intel_context *ctx;
 	int ret = 0;
 
 	BUG_ON(!mutex_is_locked(&dev->struct_mutex));
 
-	ctx = __create_hw_context(dev, file_priv);
+	ctx = __create_hw_context(dev, params->file_priv);
 	if (IS_ERR(ctx))
 		return ctx;
 
-	if (is_legacy_ctx) {
+	if (params->has_legacy_ctx) {
 		ret = __create_legacy_hw_context(dev, ctx);
 		if (ret)
 			goto err_destroy;
-	}
 
-	if (is_global_default_ctx && is_legacy_ctx) {
-		/* We may need to do things with the shrinker which
-		 * require us to immediately switch back to the default
-		 * context. This can cause a problem as pinning the
-		 * default context also requires GTT space which may not
-		 * be available. To avoid this we always pin the default
-		 * context.
-		 */
-		ret = i915_gem_obj_ggtt_pin(ctx->legacy_hw_ctx.rcs_state,
-					    get_context_alignment(dev), 0);
-		if (ret) {
-			DRM_DEBUG_DRIVER("Couldn't pin %d\n", ret);
-			goto err_destroy;
+		if (params->is_global_default_ctx) {
+			/* We may need to do things with the shrinker
+			 * which require us to immediately switch back to
+			 * the default context. This can cause a problem as
+			 * pinning the default context also requires GTT
+			 * space which may not be available. To avoid this
+			 * we always pin the default context.
+			 */
+			ret = i915_gem_obj_ggtt_pin(
+					ctx->legacy_hw_ctx.rcs_state,
+					get_context_alignment(dev), 0);
+			if (ret) {
+				DRM_DEBUG_DRIVER("Couldn't pin %d\n", ret);
+				goto err_destroy;
+			}
 		}
 	}
 
-	if (USES_FULL_PPGTT(dev)) {
-		struct i915_hw_ppgtt *ppgtt = i915_ppgtt_create(dev, file_priv);
+	if (params->has_ppgtt) {
+		struct i915_hw_ppgtt *ppgtt = i915_ppgtt_create(dev,
+			params->file_priv);
 
 		if (IS_ERR_OR_NULL(ppgtt)) {
 			DRM_DEBUG_DRIVER("PPGTT setup failed (%ld)\n",
@@ -303,7 +309,7 @@ __i915_gem_create_context(struct drm_device *dev,
 	return ctx;
 
 err_unpin:
-	if (is_global_default_ctx && is_legacy_ctx)
+	if (params->is_global_default_ctx && params->has_legacy_ctx)
 		i915_gem_object_ggtt_unpin(ctx->legacy_hw_ctx.rcs_state);
 err_destroy:
 	i915_gem_context_unreference(ctx);
@@ -311,12 +317,12 @@ err_destroy:
 }
 
 static inline int alloc_context_idr(struct drm_device *dev,
-	struct intel_context *ctx)
+	struct intel_context *ctx,
+	struct i915_gem_context_create_params *params)
 {
 	int ret;
 
-	/* Default context will never have a file_priv */
-	if (ctx->file_priv != NULL) {
+	if (params->is_global_default_ctx) {
 		ret = idr_alloc(&ctx->file_priv->context_idr, ctx,
 				DEFAULT_CONTEXT_HANDLE, 0, GFP_KERNEL);
 		if (ret < 0)
@@ -338,14 +344,23 @@ static struct intel_context *
 i915_gem_create_context(struct drm_device *dev,
 		struct drm_i915_file_private *file_priv)
 {
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct i915_gem_context_create_params params;
 	struct intel_context *ctx;
 	int ret;
 
-	ctx = __i915_gem_create_context(dev, file_priv);
+	memset(&params, 0, sizeof(params));
+
+	params.file_priv = file_priv;
+	params.has_legacy_ctx = !!dev_priv->hw_context_size;
+	params.has_ppgtt = USES_FULL_PPGTT(dev);
+	params.is_global_default_ctx = (file_priv == NULL);
+
+	ctx = __i915_gem_create_context(dev, &params);
 	if (IS_ERR(ctx))
 		return ctx;
 
-	ret = alloc_context_idr(dev, ctx);
+	ret = alloc_context_idr(dev, ctx, &params);
 	if (ret < 0) {
 		i915_gem_context_unreference(ctx);
 		return ERR_PTR(ret);
-- 
1.9.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [RFCv3 07/15] drm/i915: factor out __intel_lr_context_deferred_alloc()
  2016-03-11 10:59 [RFCv3 00/15] Introduce GVT context support Zhi Wang
                   ` (5 preceding siblings ...)
  2016-03-11 10:59 ` [RFCv3 06/15] drm/i915: let __i915_gem_context_create() takes context creation params Zhi Wang
@ 2016-03-11 10:59 ` Zhi Wang
  2016-03-11 10:59 ` [RFCv3 08/15] drm/i915: Support per-PPGTT address space mode Zhi Wang
                   ` (8 subsequent siblings)
  15 siblings, 0 replies; 29+ messages in thread
From: Zhi Wang @ 2016-03-11 10:59 UTC (permalink / raw)
  To: intel-gfx, igvt-g; +Cc: daniel.vetter, david.j.cowperthwaite, zhiyuan.lv

For flexible LRC context creation, we factor out the core logic of LRC
context creation as __intel_lr_context_deferred_alloc().

For the hard-coded LRC context configurations, we keep them in the
upper-level function intel_lr_context_deferred_alloc().

Signed-off-by: Zhi Wang <zhi.a.wang@intel.com>
---
 drivers/gpu/drm/i915/intel_lrc.c | 46 ++++++++++++++++++++++++++++++----------
 drivers/gpu/drm/i915/intel_lrc.h |  8 +++++++
 2 files changed, 43 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index 3a03646..599687f 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -2525,22 +2525,19 @@ static void lrc_setup_hardware_status_page(struct intel_engine_cs *ring,
 }
 
 /**
- * intel_lr_context_deferred_alloc() - create the LRC specific bits of a context
+ * __intel_lr_context_deferred_alloc() - core logic of creating a LRC context
  * @ctx: LR context to create.
- * @ring: engine to be used with the context.
+ * @params: parameters to specify configurable options of the context.
  *
- * This function can be called more than once, with different engines, if we plan
- * to use the context with them. The context backing objects and the ringbuffers
- * (specially the ringbuffer backing objects) suck a lot of memory up, and that's why
- * the creation is a deferred call: it's better to make sure first that we need to use
- * a given ring with the context.
+ * This function is the core logic of creating and initializing a LRC context
  *
  * Return: non-zero on error.
  */
 
-int intel_lr_context_deferred_alloc(struct intel_context *ctx,
-				    struct intel_engine_cs *ring)
+int __intel_lr_context_deferred_alloc(struct intel_context *ctx,
+	struct intel_lr_context_alloc_params *params)
 {
+	struct intel_engine_cs *ring = params->ring;
 	struct drm_device *dev = ring->dev;
 	struct drm_i915_gem_object *ctx_obj;
 	uint32_t context_size;
@@ -2561,7 +2558,7 @@ int intel_lr_context_deferred_alloc(struct intel_context *ctx,
 		return -ENOMEM;
 	}
 
-	ringbuf = intel_engine_create_ringbuffer(ring, 4 * PAGE_SIZE);
+	ringbuf = intel_engine_create_ringbuffer(ring, params->ringbuffer_size);
 	if (IS_ERR(ringbuf)) {
 		ret = PTR_ERR(ringbuf);
 		goto error_deref_obj;
@@ -2576,7 +2573,7 @@ int intel_lr_context_deferred_alloc(struct intel_context *ctx,
 	ctx->engine[ring->id].ringbuf = ringbuf;
 	ctx->engine[ring->id].state = ctx_obj;
 
-	if (ctx != ctx->i915->kernel_context && ring->init_context) {
+	if (params->ctx_needs_init && ring->init_context) {
 		struct drm_i915_gem_request *req;
 
 		req = i915_gem_request_alloc(ring, ctx);
@@ -2606,6 +2603,33 @@ error_deref_obj:
 	return ret;
 }
 
+/**
+ * intel_lr_context_deferred_alloc() - create the LRC specific bits of a context
+ * @ctx: LR context to create.
+ * @ring: engine to be used with the context.
+ *
+ * This function can be called more than once, with different engines, if we
+ * plan to use the context with them. The context backing objects and the
+ * ringbuffers (specially the ringbuffer backing objects) suck a lot of memory
+ * up, and that's why the creation is a deferred call: it's better to make sure
+ * firstthat we need to use a given ring with the context.
+ *
+ * Return: non-zero on error.
+ */
+int intel_lr_context_deferred_alloc(struct intel_context *ctx,
+				    struct intel_engine_cs *ring)
+{
+	struct intel_lr_context_alloc_params params;
+
+	memset(&params, 0, sizeof(params));
+
+	params.ring = ring;
+	params.ringbuffer_size = 4 * PAGE_SIZE;
+	params.ctx_needs_init = (ctx != ctx->i915->kernel_context);
+
+	return __intel_lr_context_deferred_alloc(ctx, &params);
+}
+
 void intel_lr_context_reset(struct drm_device *dev,
 			struct intel_context *ctx)
 {
diff --git a/drivers/gpu/drm/i915/intel_lrc.h b/drivers/gpu/drm/i915/intel_lrc.h
index e6cda3e..528c4fb 100644
--- a/drivers/gpu/drm/i915/intel_lrc.h
+++ b/drivers/gpu/drm/i915/intel_lrc.h
@@ -97,10 +97,18 @@ static inline void intel_logical_ring_emit_reg(struct intel_ringbuffer *ringbuf,
 #define LRC_PPHWSP_PN	(LRC_GUCSHR_PN + 1)
 #define LRC_STATE_PN	(LRC_PPHWSP_PN + 1)
 
+struct intel_lr_context_alloc_params {
+	struct intel_engine_cs *ring;
+	u32 ringbuffer_size;
+	bool ctx_needs_init;
+};
+
 void intel_lr_context_free(struct intel_context *ctx);
 uint32_t intel_lr_context_size(struct intel_engine_cs *ring);
 int intel_lr_context_deferred_alloc(struct intel_context *ctx,
 				    struct intel_engine_cs *ring);
+int __intel_lr_context_deferred_alloc(struct intel_context *ctx,
+			struct intel_lr_context_alloc_params *params);
 void intel_lr_context_unpin(struct intel_context *ctx,
 			    struct intel_engine_cs *engine);
 void intel_lr_context_reset(struct drm_device *dev,
-- 
1.9.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [RFCv3 08/15] drm/i915: Support per-PPGTT address space mode
  2016-03-11 10:59 [RFCv3 00/15] Introduce GVT context support Zhi Wang
                   ` (6 preceding siblings ...)
  2016-03-11 10:59 ` [RFCv3 07/15] drm/i915: factor out __intel_lr_context_deferred_alloc() Zhi Wang
@ 2016-03-11 10:59 ` Zhi Wang
  2016-03-11 10:59 ` [RFCv3 09/15] drm/i915: generate address mode bit from PPGTT instance Zhi Wang
                   ` (7 subsequent siblings)
  15 siblings, 0 replies; 29+ messages in thread
From: Zhi Wang @ 2016-03-11 10:59 UTC (permalink / raw)
  To: intel-gfx, igvt-g; +Cc: daniel.vetter, david.j.cowperthwaite, zhiyuan.lv

Previously the address space mode of each PPGTT instance is hard-coded to
host system configuration, e.g. if the host system is configured to use
48bit full PPGTT, then address space mode of all PPGTT instances is 48bit.

Per Daniel and Kevin's advice, GVT-g will leverage i915 PPGTT interface to
populate its shadow PPGTT page table. Under GVT-g the address space mode
of PPGTT instances could be various, some guest may use 32bit, some guest
may use 48bit.

We store the address space mode into i915_hw_ppgtt, and let i915 page
table manipulation routines / LRC context population routines read the
address space mode from it instead of the system configuration.

Signed-off-by: Zhi Wang <zhi.a.wang@intel.com>
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 81 ++++++++++++++++++++-----------------
 drivers/gpu/drm/i915/i915_gem_gtt.h |  3 ++
 drivers/gpu/drm/i915/intel_lrc.c    |  6 +--
 3 files changed, 51 insertions(+), 39 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index d03fe61..375add0 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -564,22 +564,22 @@ static void __pdp_fini(struct i915_page_directory_pointer *pdp)
 }
 
 static struct
-i915_page_directory_pointer *alloc_pdp(struct drm_device *dev)
+i915_page_directory_pointer *alloc_pdp(struct i915_hw_ppgtt *ppgtt)
 {
 	struct i915_page_directory_pointer *pdp;
 	int ret = -ENOMEM;
 
-	WARN_ON(!USES_FULL_48BIT_PPGTT(dev));
+	WARN_ON(!IS_48BIT_PPGTT(ppgtt));
 
 	pdp = kzalloc(sizeof(*pdp), GFP_KERNEL);
 	if (!pdp)
 		return ERR_PTR(-ENOMEM);
 
-	ret = __pdp_init(dev, pdp);
+	ret = __pdp_init(ppgtt->base.dev, pdp);
 	if (ret)
 		goto fail_bitmap;
 
-	ret = setup_px(dev, pdp);
+	ret = setup_px(ppgtt->base.dev, pdp);
 	if (ret)
 		goto fail_page_m;
 
@@ -593,12 +593,12 @@ fail_bitmap:
 	return ERR_PTR(ret);
 }
 
-static void free_pdp(struct drm_device *dev,
+static void free_pdp(struct i915_hw_ppgtt *ppgtt,
 		     struct i915_page_directory_pointer *pdp)
 {
 	__pdp_fini(pdp);
-	if (USES_FULL_48BIT_PPGTT(dev)) {
-		cleanup_px(dev, pdp);
+	if (IS_48BIT_PPGTT(ppgtt)) {
+		cleanup_px(ppgtt->base.dev, pdp);
 		kfree(pdp);
 	}
 }
@@ -632,7 +632,7 @@ gen8_setup_page_directory(struct i915_hw_ppgtt *ppgtt,
 {
 	gen8_ppgtt_pdpe_t *page_directorypo;
 
-	if (!USES_FULL_48BIT_PPGTT(ppgtt->base.dev))
+	if (!IS_48BIT_PPGTT(ppgtt))
 		return;
 
 	page_directorypo = kmap_px(pdp);
@@ -648,7 +648,7 @@ gen8_setup_page_directory_pointer(struct i915_hw_ppgtt *ppgtt,
 {
 	gen8_ppgtt_pml4e_t *pagemap = kmap_px(pml4);
 
-	WARN_ON(!USES_FULL_48BIT_PPGTT(ppgtt->base.dev));
+	WARN_ON(!IS_48BIT_PPGTT(ppgtt));
 	pagemap[index] = gen8_pml4e_encode(px_dma(pdp), I915_CACHE_LLC);
 	kunmap_px(ppgtt, pagemap);
 }
@@ -767,7 +767,7 @@ static void gen8_ppgtt_clear_range(struct i915_address_space *vm,
 	gen8_pte_t scratch_pte = gen8_pte_encode(px_dma(vm->scratch_page),
 						 I915_CACHE_LLC, use_scratch);
 
-	if (!USES_FULL_48BIT_PPGTT(vm->dev)) {
+	if (!IS_48BIT_PPGTT(ppgtt)) {
 		gen8_ppgtt_clear_pte_range(vm, &ppgtt->pdp, start, length,
 					   scratch_pte);
 	} else {
@@ -835,7 +835,7 @@ static void gen8_ppgtt_insert_entries(struct i915_address_space *vm,
 
 	__sg_page_iter_start(&sg_iter, pages->sgl, sg_nents(pages->sgl), 0);
 
-	if (!USES_FULL_48BIT_PPGTT(vm->dev)) {
+	if (!IS_48BIT_PPGTT(ppgtt)) {
 		gen8_ppgtt_insert_pte_entries(vm, &ppgtt->pdp, &sg_iter, start,
 					      cache_level);
 	} else {
@@ -869,6 +869,8 @@ static void gen8_free_page_tables(struct drm_device *dev,
 
 static int gen8_init_scratch(struct i915_address_space *vm)
 {
+	struct i915_hw_ppgtt *ppgtt =
+		container_of(vm, struct i915_hw_ppgtt, base);
 	struct drm_device *dev = vm->dev;
 
 	vm->scratch_page = alloc_scratch_page(dev);
@@ -888,8 +890,8 @@ static int gen8_init_scratch(struct i915_address_space *vm)
 		return PTR_ERR(vm->scratch_pd);
 	}
 
-	if (USES_FULL_48BIT_PPGTT(dev)) {
-		vm->scratch_pdp = alloc_pdp(dev);
+	if (IS_48BIT_PPGTT(ppgtt)) {
+		vm->scratch_pdp = alloc_pdp(ppgtt);
 		if (IS_ERR(vm->scratch_pdp)) {
 			free_pd(dev, vm->scratch_pd);
 			free_pt(dev, vm->scratch_pt);
@@ -900,7 +902,7 @@ static int gen8_init_scratch(struct i915_address_space *vm)
 
 	gen8_initialize_pt(vm, vm->scratch_pt);
 	gen8_initialize_pd(vm, vm->scratch_pd);
-	if (USES_FULL_48BIT_PPGTT(dev))
+	if (IS_48BIT_PPGTT(ppgtt))
 		gen8_initialize_pdp(vm, vm->scratch_pdp);
 
 	return 0;
@@ -913,7 +915,7 @@ static int gen8_ppgtt_notify_vgt(struct i915_hw_ppgtt *ppgtt, bool create)
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	int i;
 
-	if (USES_FULL_48BIT_PPGTT(dev)) {
+	if (IS_48BIT_PPGTT(ppgtt)) {
 		u64 daddr = px_dma(&ppgtt->pml4);
 
 		I915_WRITE(vgtif_reg(pdp[0].lo), lower_32_bits(daddr));
@@ -942,14 +944,17 @@ static void gen8_free_scratch(struct i915_address_space *vm)
 {
 	struct drm_device *dev = vm->dev;
 
-	if (USES_FULL_48BIT_PPGTT(dev))
-		free_pdp(dev, vm->scratch_pdp);
+	struct i915_hw_ppgtt *ppgtt =
+		container_of(vm, struct i915_hw_ppgtt, base);
+
+	if (IS_48BIT_PPGTT(ppgtt))
+		free_pdp(ppgtt, vm->scratch_pdp);
 	free_pd(dev, vm->scratch_pd);
 	free_pt(dev, vm->scratch_pt);
 	free_scratch_page(dev, vm->scratch_page);
 }
 
-static void gen8_ppgtt_cleanup_3lvl(struct drm_device *dev,
+static void gen8_ppgtt_cleanup_3lvl(struct i915_hw_ppgtt *ppgtt,
 				    struct i915_page_directory_pointer *pdp)
 {
 	int i;
@@ -958,11 +963,11 @@ static void gen8_ppgtt_cleanup_3lvl(struct drm_device *dev,
 		if (WARN_ON(!pdp->page_directory[i]))
 			continue;
 
-		gen8_free_page_tables(dev, pdp->page_directory[i]);
-		free_pd(dev, pdp->page_directory[i]);
+		gen8_free_page_tables(ppgtt->base.dev, pdp->page_directory[i]);
+		free_pd(ppgtt->base.dev, pdp->page_directory[i]);
 	}
 
-	free_pdp(dev, pdp);
+	free_pdp(ppgtt, pdp);
 }
 
 static void gen8_ppgtt_cleanup_4lvl(struct i915_hw_ppgtt *ppgtt)
@@ -973,7 +978,7 @@ static void gen8_ppgtt_cleanup_4lvl(struct i915_hw_ppgtt *ppgtt)
 		if (WARN_ON(!ppgtt->pml4.pdps[i]))
 			continue;
 
-		gen8_ppgtt_cleanup_3lvl(ppgtt->base.dev, ppgtt->pml4.pdps[i]);
+		gen8_ppgtt_cleanup_3lvl(ppgtt, ppgtt->pml4.pdps[i]);
 	}
 
 	cleanup_px(ppgtt->base.dev, &ppgtt->pml4);
@@ -987,8 +992,8 @@ static void gen8_ppgtt_cleanup(struct i915_address_space *vm)
 	if (intel_vgpu_active(vm->dev))
 		gen8_ppgtt_notify_vgt(ppgtt, false);
 
-	if (!USES_FULL_48BIT_PPGTT(ppgtt->base.dev))
-		gen8_ppgtt_cleanup_3lvl(ppgtt->base.dev, &ppgtt->pdp);
+	if (!IS_48BIT_PPGTT(ppgtt))
+		gen8_ppgtt_cleanup_3lvl(ppgtt, &ppgtt->pdp);
 	else
 		gen8_ppgtt_cleanup_4lvl(ppgtt);
 
@@ -1133,7 +1138,8 @@ gen8_ppgtt_alloc_page_dirpointers(struct i915_address_space *vm,
 				  uint64_t length,
 				  unsigned long *new_pdps)
 {
-	struct drm_device *dev = vm->dev;
+	struct i915_hw_ppgtt *ppgtt =
+		container_of(vm, struct i915_hw_ppgtt, base);
 	struct i915_page_directory_pointer *pdp;
 	uint32_t pml4e;
 
@@ -1141,7 +1147,7 @@ gen8_ppgtt_alloc_page_dirpointers(struct i915_address_space *vm,
 
 	gen8_for_each_pml4e(pdp, pml4, start, length, pml4e) {
 		if (!test_bit(pml4e, pml4->used_pml4es)) {
-			pdp = alloc_pdp(dev);
+			pdp = alloc_pdp(ppgtt);
 			if (IS_ERR(pdp))
 				goto unwind_out;
 
@@ -1159,7 +1165,7 @@ gen8_ppgtt_alloc_page_dirpointers(struct i915_address_space *vm,
 
 unwind_out:
 	for_each_set_bit(pml4e, new_pdps, GEN8_PML4ES_PER_PML4)
-		free_pdp(dev, pml4->pdps[pml4e]);
+		free_pdp(ppgtt, pml4->pdps[pml4e]);
 
 	return -ENOMEM;
 }
@@ -1368,7 +1374,7 @@ static int gen8_alloc_va_range_4lvl(struct i915_address_space *vm,
 
 err_out:
 	for_each_set_bit(pml4e, new_pdps, GEN8_PML4ES_PER_PML4)
-		gen8_ppgtt_cleanup_3lvl(vm->dev, pml4->pdps[pml4e]);
+		gen8_ppgtt_cleanup_3lvl(ppgtt, pml4->pdps[pml4e]);
 
 	return ret;
 }
@@ -1379,7 +1385,7 @@ static int gen8_alloc_va_range(struct i915_address_space *vm,
 	struct i915_hw_ppgtt *ppgtt =
 		container_of(vm, struct i915_hw_ppgtt, base);
 
-	if (USES_FULL_48BIT_PPGTT(vm->dev))
+	if (IS_48BIT_PPGTT(ppgtt))
 		return gen8_alloc_va_range_4lvl(vm, &ppgtt->pml4, start, length);
 	else
 		return gen8_alloc_va_range_3lvl(vm, &ppgtt->pdp, start, length);
@@ -1450,7 +1456,7 @@ static void gen8_dump_ppgtt(struct i915_hw_ppgtt *ppgtt, struct seq_file *m)
 	gen8_pte_t scratch_pte = gen8_pte_encode(px_dma(vm->scratch_page),
 						 I915_CACHE_LLC, true);
 
-	if (!USES_FULL_48BIT_PPGTT(vm->dev)) {
+	if (!IS_48BIT_PPGTT(ppgtt)) {
 		gen8_dump_pdp(&ppgtt->pdp, start, length, scratch_pte, m);
 	} else {
 		uint64_t pml4e;
@@ -1501,7 +1507,7 @@ static int gen8_preallocate_top_level_pdps(struct i915_hw_ppgtt *ppgtt)
  * space.
  *
  */
-static int gen8_ppgtt_init(struct i915_hw_ppgtt *ppgtt)
+static int gen8_ppgtt_init(struct i915_hw_ppgtt *ppgtt, int address_space_mode)
 {
 	int ret;
 
@@ -1518,7 +1524,7 @@ static int gen8_ppgtt_init(struct i915_hw_ppgtt *ppgtt)
 	ppgtt->base.bind_vma = ppgtt_bind_vma;
 	ppgtt->debug_dump = gen8_dump_ppgtt;
 
-	if (USES_FULL_48BIT_PPGTT(ppgtt->base.dev)) {
+	if (address_space_mode == 48) {
 		ret = setup_px(ppgtt->base.dev, &ppgtt->pml4);
 		if (ret)
 			goto free_scratch;
@@ -1545,6 +1551,8 @@ static int gen8_ppgtt_init(struct i915_hw_ppgtt *ppgtt)
 		}
 	}
 
+	ppgtt->address_space_mode = address_space_mode;
+
 	if (intel_vgpu_active(ppgtt->base.dev))
 		gen8_ppgtt_notify_vgt(ppgtt, true);
 
@@ -2112,14 +2120,15 @@ static int gen6_ppgtt_init(struct i915_hw_ppgtt *ppgtt)
 	return 0;
 }
 
-static int __hw_ppgtt_init(struct drm_device *dev, struct i915_hw_ppgtt *ppgtt)
+static int __hw_ppgtt_init(struct drm_device *dev,
+		struct i915_hw_ppgtt *ppgtt, int address_space_mode)
 {
 	ppgtt->base.dev = dev;
 
 	if (INTEL_INFO(dev)->gen < 8)
 		return gen6_ppgtt_init(ppgtt);
 	else
-		return gen8_ppgtt_init(ppgtt);
+		return gen8_ppgtt_init(ppgtt, address_space_mode);
 }
 
 static void i915_address_space_init(struct i915_address_space *vm,
@@ -2156,7 +2165,7 @@ int i915_ppgtt_init(struct drm_device *dev, struct i915_hw_ppgtt *ppgtt)
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	int ret = 0;
 
-	ret = __hw_ppgtt_init(dev, ppgtt);
+	ret = __hw_ppgtt_init(dev, ppgtt, USES_FULL_48BIT_PPGTT(dev) ? 48 : 32);
 	if (ret == 0) {
 		kref_init(&ppgtt->ref);
 		i915_address_space_init(&ppgtt->base, dev_priv);
@@ -2777,7 +2786,7 @@ static int i915_gem_setup_global_gtt(struct drm_device *dev,
 		if (!ppgtt)
 			return -ENOMEM;
 
-		ret = __hw_ppgtt_init(dev, ppgtt);
+		ret = __hw_ppgtt_init(dev, ppgtt, 32);
 		if (ret) {
 			ppgtt->base.cleanup(&ppgtt->base);
 			kfree(ppgtt);
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h
index 368d111..e6a1fd3 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.h
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
@@ -110,6 +110,7 @@ typedef uint64_t gen8_ppgtt_pml4e_t;
 
 #define I915_PDPES_PER_PDP(dev) (USES_FULL_48BIT_PPGTT(dev) ?\
 				 GEN8_PML4ES_PER_PML4 : GEN8_LEGACY_PDPES)
+#define IS_48BIT_PPGTT(ppgtt)	((ppgtt) && ((ppgtt)->address_space_mode == 48))
 
 #define PPAT_UNCACHED_INDEX		(_PAGE_PWT | _PAGE_PCD)
 #define PPAT_CACHED_PDE_INDEX		0 /* WB LLC */
@@ -372,6 +373,8 @@ struct i915_hw_ppgtt {
 		struct i915_page_directory pd;		/* GEN6-7 */
 	};
 
+	int address_space_mode;
+
 	struct drm_i915_file_private *file_priv;
 
 	gen6_pte_t __iomem *pd_addr;
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index 599687f..62158af 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -395,7 +395,7 @@ static int execlists_update_context(struct drm_i915_gem_request *rq)
 
 	reg_state[CTX_RING_TAIL+1] = rq->tail;
 
-	if (ppgtt && !USES_FULL_48BIT_PPGTT(ppgtt->base.dev)) {
+	if (ppgtt && !IS_48BIT_PPGTT(ppgtt)) {
 		/* True 32b PPGTT with dynamic page allocation: update PDP
 		 * registers and point the unallocated PDPs to scratch page.
 		 * PML4 is allocated during ppgtt init, so this is not needed
@@ -1674,7 +1674,7 @@ static int gen8_emit_bb_start(struct drm_i915_gem_request *req,
 	 * not needed in 48-bit.*/
 	if (req->ctx->ppgtt &&
 	    (intel_ring_flag(req->ring) & req->ctx->ppgtt->pd_dirty_rings)) {
-		if (!USES_FULL_48BIT_PPGTT(req->i915) &&
+		if (!IS_48BIT_PPGTT(req->ctx->ppgtt) &&
 		    !intel_vgpu_active(req->i915->dev)) {
 			ret = intel_logical_ring_emit_pdps(req);
 			if (ret)
@@ -2408,7 +2408,7 @@ populate_lr_context(struct intel_context *ctx, struct drm_i915_gem_object *ctx_o
 	ASSIGN_CTX_REG(reg_state, CTX_PDP0_UDW, GEN8_RING_PDP_UDW(ring, 0), 0);
 	ASSIGN_CTX_REG(reg_state, CTX_PDP0_LDW, GEN8_RING_PDP_LDW(ring, 0), 0);
 
-	if (USES_FULL_48BIT_PPGTT(ppgtt->base.dev)) {
+	if (IS_48BIT_PPGTT(ppgtt)) {
 		/* 64b PPGTT (48bit canonical)
 		 * PDP0_DESCRIPTOR contains the base address to PML4 and
 		 * other PDP Descriptors are ignored.
-- 
1.9.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [RFCv3 09/15] drm/i915: generate address mode bit from PPGTT instance
  2016-03-11 10:59 [RFCv3 00/15] Introduce GVT context support Zhi Wang
                   ` (7 preceding siblings ...)
  2016-03-11 10:59 ` [RFCv3 08/15] drm/i915: Support per-PPGTT address space mode Zhi Wang
@ 2016-03-11 10:59 ` Zhi Wang
  2016-03-11 10:59 ` [RFCv3 10/15] drm/i915: update PDPs by condition when submit the LRC context Zhi Wang
                   ` (6 subsequent siblings)
  15 siblings, 0 replies; 29+ messages in thread
From: Zhi Wang @ 2016-03-11 10:59 UTC (permalink / raw)
  To: intel-gfx, igvt-g; +Cc: daniel.vetter, david.j.cowperthwaite, zhiyuan.lv

After the per-PPGTT address mode gets support, the LRC submission should
generate the address mode bit from PPGTT instance, instead of the
hard-coded system configuration.

Signed-off-by: Zhi Wang <zhi.a.wang@intel.com>
---
 drivers/gpu/drm/i915/intel_lrc.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index 62158af..01ea99c2 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -213,7 +213,7 @@ enum {
 	LEGACY_64B_CONTEXT
 };
 #define GEN8_CTX_ADDRESSING_MODE_SHIFT 3
-#define GEN8_CTX_ADDRESSING_MODE(dev)  (USES_FULL_48BIT_PPGTT(dev) ?\
+#define GEN8_CTX_ADDRESSING_MODE(ppgtt) (IS_48BIT_PPGTT(ppgtt) ? \
 		LEGACY_64B_CONTEXT :\
 		LEGACY_32B_CONTEXT)
 enum {
@@ -274,8 +274,6 @@ logical_ring_init_platform_invariants(struct intel_engine_cs *ring)
 					(ring->id == VCS || ring->id == VCS2);
 
 	ring->ctx_desc_template = GEN8_CTX_VALID;
-	ring->ctx_desc_template |= GEN8_CTX_ADDRESSING_MODE(dev) <<
-				   GEN8_CTX_ADDRESSING_MODE_SHIFT;
 	if (IS_GEN8(dev))
 		ring->ctx_desc_template |= GEN8_CTX_L3LLC_COHERENT;
 	ring->ctx_desc_template |= GEN8_CTX_PRIVILEGE;
@@ -318,6 +316,8 @@ intel_lr_context_descriptor_update(struct intel_context *ctx,
 	       LRC_PPHWSP_PN * PAGE_SIZE;
 
 	desc = ring->ctx_desc_template;			   /* bits  0-11 */
+	desc |= GEN8_CTX_ADDRESSING_MODE(ctx->ppgtt) <<	   /* bits  3-4 */
+			GEN8_CTX_ADDRESSING_MODE_SHIFT;
 	desc |= lrca;					   /* bits 12-31 */
 	desc |= (lrca >> PAGE_SHIFT) << GEN8_CTX_ID_SHIFT; /* bits 32-51 */
 
-- 
1.9.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [RFCv3 10/15] drm/i915: update PDPs by condition when submit the LRC context
  2016-03-11 10:59 [RFCv3 00/15] Introduce GVT context support Zhi Wang
                   ` (8 preceding siblings ...)
  2016-03-11 10:59 ` [RFCv3 09/15] drm/i915: generate address mode bit from PPGTT instance Zhi Wang
@ 2016-03-11 10:59 ` Zhi Wang
  2016-03-11 11:27   ` Chris Wilson
  2016-03-11 10:59 ` [RFCv3 11/15] drm/i915: Introduce execlist context status change notification Zhi Wang
                   ` (5 subsequent siblings)
  15 siblings, 1 reply; 29+ messages in thread
From: Zhi Wang @ 2016-03-11 10:59 UTC (permalink / raw)
  To: intel-gfx, igvt-g; +Cc: daniel.vetter, david.j.cowperthwaite, zhiyuan.lv

Previously the PDPs inside the ring context will be updated

- When populating a LRC context
- Before submitting a LRC context (only for 32 bit PPGTT, as the amount
of used PDPs may be changed during PPGTT page table grow)

Under GVT-g, each VM owns a GVT context used as the shadow context. When
guest submits a context, GVT-g will load guest context into the GVT
context, and submit this context to i915 GEM submission system.

So this GVT context could be used by different guest context, and the
PPGTT root pointer in guest contexts might be different as well, if guest
is using full PPGTT mode.

In current i915, the root pointer in a LRC context will only be updated
during the LRC context creation.

This patch postpones the root pointer upgrade to the time of submission,
which will give GVT-g a chance to reload a new PPGTT page table root
pointer into an existing GVT context.

Signed-off-by: Zhi Wang <zhi.a.wang@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h  |  1 +
 drivers/gpu/drm/i915/intel_lrc.c | 54 +++++++++++++++++++---------------------
 2 files changed, 27 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 972b4ce..1281bbf 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -891,6 +891,7 @@ struct intel_context {
 		struct i915_vma *lrc_vma;
 		u64 lrc_desc;
 		uint32_t *lrc_reg_state;
+		bool root_pointer_dirty;
 	} engine[I915_NUM_RINGS];
 
 	struct list_head link;
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index 01ea99c2..19c6b46 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -391,22 +391,40 @@ static int execlists_update_context(struct drm_i915_gem_request *rq)
 {
 	struct intel_engine_cs *ring = rq->ring;
 	struct i915_hw_ppgtt *ppgtt = rq->ctx->ppgtt;
+	struct drm_i915_private *dev_priv = to_i915(ring->dev);
+
 	uint32_t *reg_state = rq->ctx->engine[ring->id].lrc_reg_state;
 
 	reg_state[CTX_RING_TAIL+1] = rq->tail;
 
-	if (ppgtt && !IS_48BIT_PPGTT(ppgtt)) {
-		/* True 32b PPGTT with dynamic page allocation: update PDP
-		 * registers and point the unallocated PDPs to scratch page.
-		 * PML4 is allocated during ppgtt init, so this is not needed
-		 * in 48-bit mode.
+	if (!ppgtt)
+		ppgtt = dev_priv->mm.aliasing_ppgtt;
+
+	/* Update root pointers for 32b PPGTT in every submission */
+	if (!rq->ctx->engine[ring->id].root_pointer_dirty
+			&& !IS_48BIT_PPGTT(ppgtt))
+		return 0;
+
+	if (!IS_48BIT_PPGTT(ppgtt)) {
+		/* 32b PPGTT
+		 * PDP*_DESCRIPTOR contains the base address of space
+		 * supported. With dynamic page allocation, PDPs may
+		 * not be allocated at this point. Point the unallocated
+		 * PDPs to the scratch page
 		 */
 		ASSIGN_CTX_PDP(ppgtt, reg_state, 3);
 		ASSIGN_CTX_PDP(ppgtt, reg_state, 2);
 		ASSIGN_CTX_PDP(ppgtt, reg_state, 1);
 		ASSIGN_CTX_PDP(ppgtt, reg_state, 0);
+	} else {
+		/* 64b PPGTT (48bit canonical)
+		 * PDP0_DESCRIPTOR contains the base address to PML4
+		 * and other PDP Descriptors are ignored.
+		 */
+		ASSIGN_CTX_PML4(ppgtt, reg_state);
 	}
 
+	rq->ctx->engine[ring->id].root_pointer_dirty = false;
 	return 0;
 }
 
@@ -2322,15 +2340,10 @@ populate_lr_context(struct intel_context *ctx, struct drm_i915_gem_object *ctx_o
 		    struct intel_engine_cs *ring, struct intel_ringbuffer *ringbuf)
 {
 	struct drm_device *dev = ring->dev;
-	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct i915_hw_ppgtt *ppgtt = ctx->ppgtt;
 	struct page *page;
 	uint32_t *reg_state;
 	int ret;
 
-	if (!ppgtt)
-		ppgtt = dev_priv->mm.aliasing_ppgtt;
-
 	ret = i915_gem_object_set_to_cpu_domain(ctx_obj, true);
 	if (ret) {
 		DRM_DEBUG_DRIVER("Could not set to CPU domain\n");
@@ -2408,24 +2421,6 @@ populate_lr_context(struct intel_context *ctx, struct drm_i915_gem_object *ctx_o
 	ASSIGN_CTX_REG(reg_state, CTX_PDP0_UDW, GEN8_RING_PDP_UDW(ring, 0), 0);
 	ASSIGN_CTX_REG(reg_state, CTX_PDP0_LDW, GEN8_RING_PDP_LDW(ring, 0), 0);
 
-	if (IS_48BIT_PPGTT(ppgtt)) {
-		/* 64b PPGTT (48bit canonical)
-		 * PDP0_DESCRIPTOR contains the base address to PML4 and
-		 * other PDP Descriptors are ignored.
-		 */
-		ASSIGN_CTX_PML4(ppgtt, reg_state);
-	} else {
-		/* 32b PPGTT
-		 * PDP*_DESCRIPTOR contains the base address of space supported.
-		 * With dynamic page allocation, PDPs may not be allocated at
-		 * this point. Point the unallocated PDPs to the scratch page
-		 */
-		ASSIGN_CTX_PDP(ppgtt, reg_state, 3);
-		ASSIGN_CTX_PDP(ppgtt, reg_state, 2);
-		ASSIGN_CTX_PDP(ppgtt, reg_state, 1);
-		ASSIGN_CTX_PDP(ppgtt, reg_state, 0);
-	}
-
 	if (ring->id == RCS) {
 		reg_state[CTX_LRI_HEADER_2] = MI_LOAD_REGISTER_IMM(1);
 		ASSIGN_CTX_REG(reg_state, CTX_R_PWR_CLK_STATE, GEN8_R_PWR_CLK_STATE,
@@ -2435,6 +2430,9 @@ populate_lr_context(struct intel_context *ctx, struct drm_i915_gem_object *ctx_o
 	kunmap_atomic(reg_state);
 	i915_gem_object_unpin_pages(ctx_obj);
 
+	/* PDPs inside the ring context need to be updated */
+	ctx->engine[ring->id].root_pointer_dirty = true;
+
 	return 0;
 }
 
-- 
1.9.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [RFCv3 11/15] drm/i915: Introduce execlist context status change notification
  2016-03-11 10:59 [RFCv3 00/15] Introduce GVT context support Zhi Wang
                   ` (9 preceding siblings ...)
  2016-03-11 10:59 ` [RFCv3 10/15] drm/i915: update PDPs by condition when submit the LRC context Zhi Wang
@ 2016-03-11 10:59 ` Zhi Wang
  2016-03-11 11:28   ` Chris Wilson
  2016-03-11 10:59 ` [RFCv3 12/15] drm/i915: Support context single submission Zhi Wang
                   ` (4 subsequent siblings)
  15 siblings, 1 reply; 29+ messages in thread
From: Zhi Wang @ 2016-03-11 10:59 UTC (permalink / raw)
  To: intel-gfx, igvt-g; +Cc: daniel.vetter, david.j.cowperthwaite, zhiyuan.lv

This patch introduces an approach to track the execlist context status
change.

GVT-g uses GVT context as the "shadow context". The content inside GVT
context will be copied back to guest after the context is idle. So GVT-g
has to know the status of the execlist context.

This function is configurable in the context creation service. Currently,
Only GVT-g will create the "status-change-notification" enabled GEM
context.

Signed-off-by: Zhi Wang <zhi.a.wang@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h  |  2 ++
 drivers/gpu/drm/i915/intel_lrc.c | 28 ++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_lrc.h |  6 ++++++
 3 files changed, 36 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 1281bbf..68b821a 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -892,6 +892,8 @@ struct intel_context {
 		u64 lrc_desc;
 		uint32_t *lrc_reg_state;
 		bool root_pointer_dirty;
+		bool need_status_change_notification;
+		struct atomic_notifier_head status_notifier_head;
 	} engine[I915_NUM_RINGS];
 
 	struct list_head link;
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index 19c6b46..ae1ab92 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -439,6 +439,18 @@ static void execlists_submit_requests(struct drm_i915_gem_request *rq0,
 	execlists_elsp_write(rq0, rq1);
 }
 
+static inline void execlists_context_status_change(
+		struct intel_context *ctx,
+		struct intel_engine_cs *ring,
+		unsigned long status)
+{
+	if (!ctx->engine[ring->id].need_status_change_notification)
+		return;
+
+	atomic_notifier_call_chain(&ctx->engine[ring->id].status_notifier_head,
+			status, NULL);
+}
+
 static void execlists_context_unqueue(struct intel_engine_cs *ring)
 {
 	struct drm_i915_gem_request *req0 = NULL, *req1 = NULL;
@@ -495,6 +507,13 @@ static void execlists_context_unqueue(struct intel_engine_cs *ring)
 
 	WARN_ON(req1 && req1->elsp_submitted);
 
+	execlists_context_status_change(req0->ctx, ring, CONTEXT_SCHEDULE_IN);
+
+	if (req1) {
+		execlists_context_status_change(req1->ctx,
+			ring, CONTEXT_SCHEDULE_IN);
+	}
+
 	execlists_submit_requests(req0, req1);
 }
 
@@ -515,6 +534,8 @@ static bool execlists_check_remove_request(struct intel_engine_cs *ring,
 			     "Never submitted head request\n");
 
 			if (--head_req->elsp_submitted <= 0) {
+				execlists_context_status_change(head_req->ctx,
+					ring, CONTEXT_SCHEDULE_OUT);
 				list_move_tail(&head_req->execlist_link,
 					       &ring->execlist_retired_req_list);
 				return true;
@@ -2590,6 +2611,13 @@ int __intel_lr_context_deferred_alloc(struct intel_context *ctx,
 		}
 		i915_add_request_no_flush(req);
 	}
+
+	if (params->ctx_needs_status_change_notification) {
+		ctx->engine[ring->id].need_status_change_notification = true;
+		ATOMIC_INIT_NOTIFIER_HEAD(
+			&ctx->engine[ring->id].status_notifier_head);
+	}
+
 	return 0;
 
 error_ringbuf:
diff --git a/drivers/gpu/drm/i915/intel_lrc.h b/drivers/gpu/drm/i915/intel_lrc.h
index 528c4fb..15791d4 100644
--- a/drivers/gpu/drm/i915/intel_lrc.h
+++ b/drivers/gpu/drm/i915/intel_lrc.h
@@ -54,6 +54,11 @@
 #define GEN8_CSB_READ_PTR(csb_status) \
 	(((csb_status) & GEN8_CSB_READ_PTR_MASK) >> 8)
 
+enum {
+	CONTEXT_SCHEDULE_IN = 0,
+	CONTEXT_SCHEDULE_OUT,
+};
+
 /* Logical Rings */
 int intel_logical_ring_alloc_request_extras(struct drm_i915_gem_request *request);
 int intel_logical_ring_reserve_space(struct drm_i915_gem_request *request);
@@ -101,6 +106,7 @@ struct intel_lr_context_alloc_params {
 	struct intel_engine_cs *ring;
 	u32 ringbuffer_size;
 	bool ctx_needs_init;
+	bool ctx_needs_status_change_notification;
 };
 
 void intel_lr_context_free(struct intel_context *ctx);
-- 
1.9.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [RFCv3 12/15] drm/i915: Support context single submission
  2016-03-11 10:59 [RFCv3 00/15] Introduce GVT context support Zhi Wang
                   ` (10 preceding siblings ...)
  2016-03-11 10:59 ` [RFCv3 11/15] drm/i915: Introduce execlist context status change notification Zhi Wang
@ 2016-03-11 10:59 ` Zhi Wang
  2016-03-11 11:25   ` Chris Wilson
  2016-03-11 10:59 ` [RFCv3 13/15] drm/i915: Introduce GVT context creation API Zhi Wang
                   ` (3 subsequent siblings)
  15 siblings, 1 reply; 29+ messages in thread
From: Zhi Wang @ 2016-03-11 10:59 UTC (permalink / raw)
  To: intel-gfx, igvt-g; +Cc: daniel.vetter, david.j.cowperthwaite, zhiyuan.lv

This patch introduces the support of context signle submission. As GVT
context may come from different guests, which requires different
configuration of render registers. It can't be combined in a dual ELSP
submission combo.

We make this function as a context feature in context creation service.
Only GVT-g will create this kinds of GEM context currently.

Signed-off-by: Zhi Wang <zhi.a.wang@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h  |  1 +
 drivers/gpu/drm/i915/intel_lrc.c | 10 +++++++++-
 drivers/gpu/drm/i915/intel_lrc.h |  1 +
 3 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 68b821a..d7fc738 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -895,6 +895,7 @@ struct intel_context {
 		bool need_status_change_notification;
 		struct atomic_notifier_head status_notifier_head;
 	} engine[I915_NUM_RINGS];
+	bool single_submission;
 
 	struct list_head link;
 };
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index ae1ab92..3a047fe 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -472,6 +472,9 @@ static void execlists_context_unqueue(struct intel_engine_cs *ring)
 				 execlist_link) {
 		if (!req0) {
 			req0 = cursor;
+			/* req0 ctx requires single submission, stop picking */
+			if (req0->ctx->single_submission)
+				break;
 		} else if (req0->ctx == cursor->ctx) {
 			/* Same ctx: ignore first request, as second request
 			 * will update tail past first request's workload */
@@ -480,7 +483,12 @@ static void execlists_context_unqueue(struct intel_engine_cs *ring)
 				       &ring->execlist_retired_req_list);
 			req0 = cursor;
 		} else {
-			req1 = cursor;
+			/*
+			 * req0 ctx doesn't require single submission, but
+			 * next req ctx requires, stop picking req1
+			 */
+			if (!cursor->ctx->single_submission)
+				req1 = cursor;
 			break;
 		}
 	}
diff --git a/drivers/gpu/drm/i915/intel_lrc.h b/drivers/gpu/drm/i915/intel_lrc.h
index 15791d4..4873dd8 100644
--- a/drivers/gpu/drm/i915/intel_lrc.h
+++ b/drivers/gpu/drm/i915/intel_lrc.h
@@ -107,6 +107,7 @@ struct intel_lr_context_alloc_params {
 	u32 ringbuffer_size;
 	bool ctx_needs_init;
 	bool ctx_needs_status_change_notification;
+	bool ctx_needs_single_submission;
 };
 
 void intel_lr_context_free(struct intel_context *ctx);
-- 
1.9.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [RFCv3 13/15] drm/i915: Introduce GVT context creation API
  2016-03-11 10:59 [RFCv3 00/15] Introduce GVT context support Zhi Wang
                   ` (11 preceding siblings ...)
  2016-03-11 10:59 ` [RFCv3 12/15] drm/i915: Support context single submission Zhi Wang
@ 2016-03-11 10:59 ` Zhi Wang
  2016-03-11 10:59 ` [RFCv3 14/15] drm/i915: factor out and expose i915_steal_fence() Zhi Wang
                   ` (2 subsequent siblings)
  15 siblings, 0 replies; 29+ messages in thread
From: Zhi Wang @ 2016-03-11 10:59 UTC (permalink / raw)
  To: intel-gfx, igvt-g; +Cc: daniel.vetter, david.j.cowperthwaite, zhiyuan.lv

GVT workload scheduler needs special host LRC contexts, the so called
"shadow LRC context" to submit guest workload to host i915. During the
guest workload submission, GVT fills the shadow LRC context with the
content of guest LRC context: engine context is copied without changes,
ring context is mostly owned by host i915.

The GVT-g workload scheduler flow:

         +-----------+                   +-----------+
         | GVT Guest |                   | GVT Guest |
         +-+-----^---+                   +-+-----^---+
           |     |                         |     |
           |     | GVT-g                   |     | GVT-g
vELSP write|     | emulates     vELSP write|     | emulates
           |     | Execlist/CSB            |     | Execlist/CSB
           |     | Status                  |     | Status
           |     |                         |     |
    +------v-----+-------------------------v-----+---------+
    |           GVT Virtual Execlist Submission            |
    +------+-------------------------------+---------------+
           |                               |
           | Per-VM/Ring Workoad Q         | Per-VM/Ring Workload Q
   +---------------------+--+      +------------------------+
       +---v--------+    ^             +---v--------+
       |GVT Workload|... |             |GVT Workload|...
       +------------+    |             +------------+
                         |
                         | Pick Workload from Q
    +--------------------+---------------------------------+
    |                GVT Workload Scheduler                |
    +--------------------+---------------------------------+
                         |         * Shadow guest LRC context
                  +------v------+  * Shadow guest ring buffer
                  | GVT Context |  * Scan/Patch guest RB instructions
                  +------+------+
                         |
                         v
              Host i915 GEM Submission

v2:

Mostly based on Daniel's idea. Call the refactored core logic of GEM
context creation service and LRC context creation service to create the GVT
context.

Signed-off-by: Zhi Wang <zhi.a.wang@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h         |  1 +
 drivers/gpu/drm/i915/i915_gem_context.c | 52 +++++++++++++++++++++++++++++++++
 2 files changed, 53 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index d7fc738..26106e5 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -3270,6 +3270,7 @@ i915_gem_context_get(struct drm_i915_file_private *file_priv, u32 id);
 void i915_gem_context_free(struct kref *ctx_ref);
 struct drm_i915_gem_object *
 i915_gem_alloc_context_obj(struct drm_device *dev, size_t size);
+struct intel_context *i915_gem_create_gvt_context(struct drm_device *dev);
 static inline void i915_gem_context_reference(struct intel_context *ctx)
 {
 	kref_get(&ctx->ref);
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
index e7415b1a..a9d5f17 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -369,6 +369,58 @@ i915_gem_create_context(struct drm_device *dev,
 	return ctx;
 }
 
+/**
+ * i915_gem_create_gvt_context - create a GVT GEM context
+ * @dev: drm device *
+ *
+ * This function is used to create a GVT specific GEM context.
+ *
+ * Returns:
+ * pointer to intel_context on success, NULL if failed
+ *
+ */
+struct intel_context *
+i915_gem_create_gvt_context(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct i915_gem_context_create_params params;
+	struct intel_lr_context_alloc_params alloc_params;
+	struct intel_context *ctx;
+	int i, ret;
+
+	memset(&params, 0, sizeof(params));
+	memset(&alloc_params, 0, sizeof(alloc_params));
+
+	params.file_priv = NULL;
+	params.has_legacy_ctx = false;
+	params.has_ppgtt = false;
+	params.is_global_default_ctx = false;
+
+	alloc_params.ctx_needs_init = false;
+	alloc_params.ctx_needs_status_change_notification = true;
+	alloc_params.ctx_needs_single_submission = true;
+	alloc_params.ringbuffer_size = 512 * PAGE_SIZE;
+
+	mutex_lock(&dev->struct_mutex);
+
+	ctx = __i915_gem_create_context(dev, &params);
+	if (IS_ERR(ctx))
+		return ctx;
+
+	for (i = 0; i < I915_NUM_RINGS; i++) {
+		alloc_params.ring = &dev_priv->ring[i];
+		ret = __intel_lr_context_deferred_alloc(ctx, &alloc_params);
+		if (ret) {
+			i915_gem_context_unreference(ctx);
+			ctx = NULL;
+			goto out;
+		}
+	}
+out:
+	mutex_unlock(&dev->struct_mutex);
+	return ctx;
+}
+
 static void i915_gem_context_unpin(struct intel_context *ctx,
 				   struct intel_engine_cs *engine)
 {
-- 
1.9.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [RFCv3 14/15] drm/i915: factor out and expose i915_steal_fence()
  2016-03-11 10:59 [RFCv3 00/15] Introduce GVT context support Zhi Wang
                   ` (12 preceding siblings ...)
  2016-03-11 10:59 ` [RFCv3 13/15] drm/i915: Introduce GVT context creation API Zhi Wang
@ 2016-03-11 10:59 ` Zhi Wang
  2016-03-11 11:21   ` Chris Wilson
  2016-03-11 10:59 ` [RFCv3 15/15] drm/i915: expose i915_find_fence_reg() Zhi Wang
  2016-03-11 11:09 ` ✗ Fi.CI.BAT: failure for Introduce GVT context support Patchwork
  15 siblings, 1 reply; 29+ messages in thread
From: Zhi Wang @ 2016-03-11 10:59 UTC (permalink / raw)
  To: intel-gfx, igvt-g; +Cc: daniel.vetter, david.j.cowperthwaite, zhiyuan.lv

Factor out and expose fence stealing functionality for GVT-g. GVT-g
will use i915_find_fence_reg() to find a free/unpin fence register
and use i915_steal_fence() to steal it.

Signed-off-by: Zhi Wang <zhi.a.wang@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h       |  1 +
 drivers/gpu/drm/i915/i915_gem_fence.c | 36 ++++++++++++++++++++++++++---------
 2 files changed, 28 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 26106e5..deb7143b 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -3247,6 +3247,7 @@ i915_gem_object_ggtt_unpin(struct drm_i915_gem_object *obj)
 /* i915_gem_fence.c */
 int __must_check i915_gem_object_get_fence(struct drm_i915_gem_object *obj);
 int __must_check i915_gem_object_put_fence(struct drm_i915_gem_object *obj);
+int i915_steal_fence(struct drm_i915_fence_reg *reg);
 
 bool i915_gem_object_pin_fence(struct drm_i915_gem_object *obj);
 void i915_gem_object_unpin_fence(struct drm_i915_gem_object *obj);
diff --git a/drivers/gpu/drm/i915/i915_gem_fence.c b/drivers/gpu/drm/i915/i915_gem_fence.c
index 5981985..dd897c6 100644
--- a/drivers/gpu/drm/i915/i915_gem_fence.c
+++ b/drivers/gpu/drm/i915/i915_gem_fence.c
@@ -346,6 +346,30 @@ deadlock:
 }
 
 /**
+ * i915_steal_fence - steal a fence from a GEM object
+ * @reg: the fence register to be stolen
+ *
+ * Returns:
+ *
+ * 0 on success, negative error code on failure.
+ */
+int i915_steal_fence(struct drm_i915_fence_reg *reg)
+{
+	int ret;
+
+	if (reg->obj) {
+		struct drm_i915_gem_object *old = reg->obj;
+
+		ret = i915_gem_object_wait_fence(old);
+		if (ret)
+			return ret;
+
+		i915_gem_object_fence_lost(old);
+	}
+	return 0;
+}
+
+/**
  * i915_gem_object_get_fence - set up fencing for an object
  * @obj: object to map through a fence reg
  *
@@ -397,15 +421,9 @@ i915_gem_object_get_fence(struct drm_i915_gem_object *obj)
 		if (IS_ERR(reg))
 			return PTR_ERR(reg);
 
-		if (reg->obj) {
-			struct drm_i915_gem_object *old = reg->obj;
-
-			ret = i915_gem_object_wait_fence(old);
-			if (ret)
-				return ret;
-
-			i915_gem_object_fence_lost(old);
-		}
+		ret = i915_steal_fence(reg);
+		if (ret)
+			return ret;
 	} else
 		return 0;
 
-- 
1.9.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [RFCv3 15/15] drm/i915: expose i915_find_fence_reg()
  2016-03-11 10:59 [RFCv3 00/15] Introduce GVT context support Zhi Wang
                   ` (13 preceding siblings ...)
  2016-03-11 10:59 ` [RFCv3 14/15] drm/i915: factor out and expose i915_steal_fence() Zhi Wang
@ 2016-03-11 10:59 ` Zhi Wang
  2016-03-11 11:09 ` ✗ Fi.CI.BAT: failure for Introduce GVT context support Patchwork
  15 siblings, 0 replies; 29+ messages in thread
From: Zhi Wang @ 2016-03-11 10:59 UTC (permalink / raw)
  To: intel-gfx, igvt-g; +Cc: daniel.vetter, david.j.cowperthwaite, zhiyuan.lv

Expose i915_find_fence_reg() for GVT-g to allocate the fence registers
for vGPUs.

Signed-off-by: Zhi Wang <zhi.a.wang@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h       |  1 +
 drivers/gpu/drm/i915/i915_gem_fence.c | 10 +++++++++-
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index deb7143b..67c953a 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -3248,6 +3248,7 @@ i915_gem_object_ggtt_unpin(struct drm_i915_gem_object *obj)
 int __must_check i915_gem_object_get_fence(struct drm_i915_gem_object *obj);
 int __must_check i915_gem_object_put_fence(struct drm_i915_gem_object *obj);
 int i915_steal_fence(struct drm_i915_fence_reg *reg);
+struct drm_i915_fence_reg *i915_find_fence_reg(struct drm_device *dev);
 
 bool i915_gem_object_pin_fence(struct drm_i915_gem_object *obj);
 void i915_gem_object_unpin_fence(struct drm_i915_gem_object *obj);
diff --git a/drivers/gpu/drm/i915/i915_gem_fence.c b/drivers/gpu/drm/i915/i915_gem_fence.c
index dd897c6..38da3f3 100644
--- a/drivers/gpu/drm/i915/i915_gem_fence.c
+++ b/drivers/gpu/drm/i915/i915_gem_fence.c
@@ -308,7 +308,15 @@ i915_gem_object_put_fence(struct drm_i915_gem_object *obj)
 	return 0;
 }
 
-static struct drm_i915_fence_reg *
+/**
+ * i915_find_fence_reg - find a free or unpinned fence register
+ * @dev: drm device
+ *
+ * Returns:
+ *
+ * pointer to fence register on success, error code in pointer on failure.
+ */
+struct drm_i915_fence_reg *
 i915_find_fence_reg(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
-- 
1.9.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* ✗ Fi.CI.BAT: failure for Introduce GVT context support
  2016-03-11 10:59 [RFCv3 00/15] Introduce GVT context support Zhi Wang
                   ` (14 preceding siblings ...)
  2016-03-11 10:59 ` [RFCv3 15/15] drm/i915: expose i915_find_fence_reg() Zhi Wang
@ 2016-03-11 11:09 ` Patchwork
  15 siblings, 0 replies; 29+ messages in thread
From: Patchwork @ 2016-03-11 11:09 UTC (permalink / raw)
  To: Wang, Zhi A; +Cc: intel-gfx

== Series Details ==

Series: Introduce GVT context support
URL   : https://patchwork.freedesktop.org/series/4351/
State : failure

== Summary ==

Series 4351v1 Introduce GVT context support
2016-03-11T10:50:52.806659 http://patchwork.freedesktop.org/api/1.0/series/4351/revisions/1/mbox/
Applying: drm/i915: factor out i915_pvinfo.h
Applying: drm/i915/gvt: Introduce the basic architecture of GVT-g
Using index info to reconstruct a base tree...
M	drivers/gpu/drm/i915/Kconfig
M	drivers/gpu/drm/i915/Makefile
M	drivers/gpu/drm/i915/i915_dma.c
M	drivers/gpu/drm/i915/i915_drv.h
M	drivers/gpu/drm/i915/i915_gem_gtt.c
Falling back to patching base and 3-way merge...
Auto-merging drivers/gpu/drm/i915/i915_gem_gtt.c
Auto-merging drivers/gpu/drm/i915/i915_drv.h
Auto-merging drivers/gpu/drm/i915/i915_dma.c
Auto-merging drivers/gpu/drm/i915/Makefile
Auto-merging drivers/gpu/drm/i915/Kconfig
CONFLICT (content): Merge conflict in drivers/gpu/drm/i915/Kconfig
Patch failed at 0002 drm/i915/gvt: Introduce the basic architecture of GVT-g

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [RFCv3 14/15] drm/i915: factor out and expose i915_steal_fence()
  2016-03-11 10:59 ` [RFCv3 14/15] drm/i915: factor out and expose i915_steal_fence() Zhi Wang
@ 2016-03-11 11:21   ` Chris Wilson
  2016-03-11 12:29     ` Wang, Zhi A
  0 siblings, 1 reply; 29+ messages in thread
From: Chris Wilson @ 2016-03-11 11:21 UTC (permalink / raw)
  To: Zhi Wang
  Cc: daniel.vetter, intel-gfx, david.j.cowperthwaite, igvt-g, zhiyuan.lv

On Fri, Mar 11, 2016 at 06:59:45PM +0800, Zhi Wang wrote:
> Factor out and expose fence stealing functionality for GVT-g. GVT-g
> will use i915_find_fence_reg() to find a free/unpin fence register
> and use i915_steal_fence() to steal it.
> 
> Signed-off-by: Zhi Wang <zhi.a.wang@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_drv.h       |  1 +
>  drivers/gpu/drm/i915/i915_gem_fence.c | 36 ++++++++++++++++++++++++++---------
>  2 files changed, 28 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 26106e5..deb7143b 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -3247,6 +3247,7 @@ i915_gem_object_ggtt_unpin(struct drm_i915_gem_object *obj)
>  /* i915_gem_fence.c */
>  int __must_check i915_gem_object_get_fence(struct drm_i915_gem_object *obj);
>  int __must_check i915_gem_object_put_fence(struct drm_i915_gem_object *obj);
> +int i915_steal_fence(struct drm_i915_fence_reg *reg);
>  
>  bool i915_gem_object_pin_fence(struct drm_i915_gem_object *obj);
>  void i915_gem_object_unpin_fence(struct drm_i915_gem_object *obj);
> diff --git a/drivers/gpu/drm/i915/i915_gem_fence.c b/drivers/gpu/drm/i915/i915_gem_fence.c
> index 5981985..dd897c6 100644
> --- a/drivers/gpu/drm/i915/i915_gem_fence.c
> +++ b/drivers/gpu/drm/i915/i915_gem_fence.c
> @@ -346,6 +346,30 @@ deadlock:
>  }
>  
>  /**
> + * i915_steal_fence - steal a fence from a GEM object
> + * @reg: the fence register to be stolen
> + *
> + * Returns:
> + *
> + * 0 on success, negative error code on failure.
> + */
> +int i915_steal_fence(struct drm_i915_fence_reg *reg)
> +{
> +	int ret;
> +

No, this is not safe.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [RFCv3 12/15] drm/i915: Support context single submission
  2016-03-11 10:59 ` [RFCv3 12/15] drm/i915: Support context single submission Zhi Wang
@ 2016-03-11 11:25   ` Chris Wilson
  2016-03-11 12:42     ` Wang, Zhi A
  0 siblings, 1 reply; 29+ messages in thread
From: Chris Wilson @ 2016-03-11 11:25 UTC (permalink / raw)
  To: Zhi Wang
  Cc: daniel.vetter, intel-gfx, david.j.cowperthwaite, igvt-g, zhiyuan.lv

On Fri, Mar 11, 2016 at 06:59:43PM +0800, Zhi Wang wrote:
> This patch introduces the support of context signle submission. As GVT
> context may come from different guests, which requires different
> configuration of render registers. It can't be combined in a dual ELSP
> submission combo.

That sounds wrong since the register are part of the context. I presume
what you mean is that you cannot combine requests from the same GVT
context but different guests.

> We make this function as a context feature in context creation service.
> Only GVT-g will create this kinds of GEM context currently.
> 
> Signed-off-by: Zhi Wang <zhi.a.wang@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_drv.h  |  1 +
>  drivers/gpu/drm/i915/intel_lrc.c | 10 +++++++++-
>  drivers/gpu/drm/i915/intel_lrc.h |  1 +
>  3 files changed, 11 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 68b821a..d7fc738 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -895,6 +895,7 @@ struct intel_context {
>  		bool need_status_change_notification;
>  		struct atomic_notifier_head status_notifier_head;
>  	} engine[I915_NUM_RINGS];
> +	bool single_submission;
>  
>  	struct list_head link;
>  };
> diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
> index ae1ab92..3a047fe 100644
> --- a/drivers/gpu/drm/i915/intel_lrc.c
> +++ b/drivers/gpu/drm/i915/intel_lrc.c
> @@ -472,6 +472,9 @@ static void execlists_context_unqueue(struct intel_engine_cs *ring)
>  				 execlist_link) {
>  		if (!req0) {
>  			req0 = cursor;
> +			/* req0 ctx requires single submission, stop picking */
> +			if (req0->ctx->single_submission)
> +				break;
>  		} else if (req0->ctx == cursor->ctx) {
>  			/* Same ctx: ignore first request, as second request
>  			 * will update tail past first request's workload */
> @@ -480,7 +483,12 @@ static void execlists_context_unqueue(struct intel_engine_cs *ring)
>  				       &ring->execlist_retired_req_list);
>  			req0 = cursor;
>  		} else {
> -			req1 = cursor;
> +			/*
> +			 * req0 ctx doesn't require single submission, but
> +			 * next req ctx requires, stop picking req1
> +			 */
> +			if (!cursor->ctx->single_submission)
> +				req1 = cursor;
>  			break;
>  		}
>  	}
> diff --git a/drivers/gpu/drm/i915/intel_lrc.h b/drivers/gpu/drm/i915/intel_lrc.h
> index 15791d4..4873dd8 100644
> --- a/drivers/gpu/drm/i915/intel_lrc.h
> +++ b/drivers/gpu/drm/i915/intel_lrc.h
> @@ -107,6 +107,7 @@ struct intel_lr_context_alloc_params {
>  	u32 ringbuffer_size;
>  	bool ctx_needs_init;
>  	bool ctx_needs_status_change_notification;
> +	bool ctx_needs_single_submission;

Random garbage.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [RFCv3 10/15] drm/i915: update PDPs by condition when submit the LRC context
  2016-03-11 10:59 ` [RFCv3 10/15] drm/i915: update PDPs by condition when submit the LRC context Zhi Wang
@ 2016-03-11 11:27   ` Chris Wilson
  2016-03-11 12:56     ` Wang, Zhi A
  0 siblings, 1 reply; 29+ messages in thread
From: Chris Wilson @ 2016-03-11 11:27 UTC (permalink / raw)
  To: Zhi Wang
  Cc: daniel.vetter, intel-gfx, david.j.cowperthwaite, igvt-g, zhiyuan.lv

On Fri, Mar 11, 2016 at 06:59:41PM +0800, Zhi Wang wrote:
> Previously the PDPs inside the ring context will be updated
> 
> - When populating a LRC context
> - Before submitting a LRC context (only for 32 bit PPGTT, as the amount
> of used PDPs may be changed during PPGTT page table grow)
> 
> Under GVT-g, each VM owns a GVT context used as the shadow context. When
> guest submits a context, GVT-g will load guest context into the GVT
> context, and submit this context to i915 GEM submission system.
> 
> So this GVT context could be used by different guest context, and the
> PPGTT root pointer in guest contexts might be different as well, if guest
> is using full PPGTT mode.
> 
> In current i915, the root pointer in a LRC context will only be updated
> during the LRC context creation.
> 
> This patch postpones the root pointer upgrade to the time of submission,
> which will give GVT-g a chance to reload a new PPGTT page table root
> pointer into an existing GVT context.

Not explained is why you cannot use the existing dirty flags.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [RFCv3 11/15] drm/i915: Introduce execlist context status change notification
  2016-03-11 10:59 ` [RFCv3 11/15] drm/i915: Introduce execlist context status change notification Zhi Wang
@ 2016-03-11 11:28   ` Chris Wilson
  2016-03-11 12:47     ` Wang, Zhi A
  0 siblings, 1 reply; 29+ messages in thread
From: Chris Wilson @ 2016-03-11 11:28 UTC (permalink / raw)
  To: Zhi Wang
  Cc: daniel.vetter, intel-gfx, david.j.cowperthwaite, igvt-g, zhiyuan.lv

On Fri, Mar 11, 2016 at 06:59:42PM +0800, Zhi Wang wrote:
> This patch introduces an approach to track the execlist context status
> change.
> 
> GVT-g uses GVT context as the "shadow context". The content inside GVT
> context will be copied back to guest after the context is idle. So GVT-g
> has to know the status of the execlist context.
> 
> This function is configurable in the context creation service. Currently,
> Only GVT-g will create the "status-change-notification" enabled GEM
> context.

Nope. Please hook into the lower-frequency idle mechanism then.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [RFCv3 14/15] drm/i915: factor out and expose i915_steal_fence()
  2016-03-11 11:21   ` Chris Wilson
@ 2016-03-11 12:29     ` Wang, Zhi A
  2016-03-11 12:42       ` Chris Wilson
  0 siblings, 1 reply; 29+ messages in thread
From: Wang, Zhi A @ 2016-03-11 12:29 UTC (permalink / raw)
  To: Chris Wilson
  Cc: daniel.vetter, intel-gfx, Cowperthwaite, David J, igvt-g, Lv, Zhiyuan

Hi Chris:
    Do you mean I should also check the fence pin count in this API like i915_find_fence_reg, then it will be safe here? :) 

-----Original Message-----
From: Chris Wilson [mailto:chris@chris-wilson.co.uk] 
Sent: Friday, March 11, 2016 7:22 PM
To: Wang, Zhi A
Cc: intel-gfx@lists.freedesktop.org; igvt-g@lists.01.org; Tian, Kevin; Lv, Zhiyuan; Niu, Bing; Song, Jike; daniel.vetter@ffwll.ch; Cowperthwaite, David J; joonas.lahtinen@linux.intel.com
Subject: Re: [RFCv3 14/15] drm/i915: factor out and expose i915_steal_fence()

On Fri, Mar 11, 2016 at 06:59:45PM +0800, Zhi Wang wrote:
> Factor out and expose fence stealing functionality for GVT-g. GVT-g
> will use i915_find_fence_reg() to find a free/unpin fence register
> and use i915_steal_fence() to steal it.
> 
> Signed-off-by: Zhi Wang <zhi.a.wang@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_drv.h       |  1 +
>  drivers/gpu/drm/i915/i915_gem_fence.c | 36 ++++++++++++++++++++++++++---------
>  2 files changed, 28 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 26106e5..deb7143b 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -3247,6 +3247,7 @@ i915_gem_object_ggtt_unpin(struct drm_i915_gem_object *obj)
>  /* i915_gem_fence.c */
>  int __must_check i915_gem_object_get_fence(struct drm_i915_gem_object *obj);
>  int __must_check i915_gem_object_put_fence(struct drm_i915_gem_object *obj);
> +int i915_steal_fence(struct drm_i915_fence_reg *reg);
>  
>  bool i915_gem_object_pin_fence(struct drm_i915_gem_object *obj);
>  void i915_gem_object_unpin_fence(struct drm_i915_gem_object *obj);
> diff --git a/drivers/gpu/drm/i915/i915_gem_fence.c b/drivers/gpu/drm/i915/i915_gem_fence.c
> index 5981985..dd897c6 100644
> --- a/drivers/gpu/drm/i915/i915_gem_fence.c
> +++ b/drivers/gpu/drm/i915/i915_gem_fence.c
> @@ -346,6 +346,30 @@ deadlock:
>  }
>  
>  /**
> + * i915_steal_fence - steal a fence from a GEM object
> + * @reg: the fence register to be stolen
> + *
> + * Returns:
> + *
> + * 0 on success, negative error code on failure.
> + */
> +int i915_steal_fence(struct drm_i915_fence_reg *reg)
> +{
> +	int ret;
> +

No, this is not safe.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [RFCv3 12/15] drm/i915: Support context single submission
  2016-03-11 11:25   ` Chris Wilson
@ 2016-03-11 12:42     ` Wang, Zhi A
  0 siblings, 0 replies; 29+ messages in thread
From: Wang, Zhi A @ 2016-03-11 12:42 UTC (permalink / raw)
  To: Chris Wilson
  Cc: daniel.vetter, intel-gfx, Cowperthwaite, David J, igvt-g, Lv, Zhiyuan

Hi Chris:
    We found that some guest would configure the render MMIOs via MMIO write, not like i915 which issues a lot of LRIs and configure the render mmio by itself(If they initialize their context like what i915 does, that would be nice..). 

Here is the scenario, guest configures render MMIOs via MMIO writes(GVT-g will store these values into virtual registers, as HW might be being used by someone else) and then guest submits a restore-inhibit LRC context. It assume currently the render MMIOs have been configured as what it wishes and these MMIO values should be saved into the context...

So  we have to reload the render MMIOs to HW for them before the context is submitted to HW by i915 GEM submission...

-----Original Message-----
From: Chris Wilson [mailto:chris@chris-wilson.co.uk] 
Sent: Friday, March 11, 2016 7:26 PM
To: Wang, Zhi A
Cc: intel-gfx@lists.freedesktop.org; igvt-g@lists.01.org; Tian, Kevin; Lv, Zhiyuan; Niu, Bing; Song, Jike; daniel.vetter@ffwll.ch; Cowperthwaite, David J; joonas.lahtinen@linux.intel.com
Subject: Re: [RFCv3 12/15] drm/i915: Support context single submission

On Fri, Mar 11, 2016 at 06:59:43PM +0800, Zhi Wang wrote:
> This patch introduces the support of context signle submission. As GVT
> context may come from different guests, which requires different
> configuration of render registers. It can't be combined in a dual ELSP
> submission combo.

That sounds wrong since the register are part of the context. I presume
what you mean is that you cannot combine requests from the same GVT
context but different guests.

> We make this function as a context feature in context creation service.
> Only GVT-g will create this kinds of GEM context currently.
> 
> Signed-off-by: Zhi Wang <zhi.a.wang@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_drv.h  |  1 +
>  drivers/gpu/drm/i915/intel_lrc.c | 10 +++++++++-
>  drivers/gpu/drm/i915/intel_lrc.h |  1 +
>  3 files changed, 11 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 68b821a..d7fc738 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -895,6 +895,7 @@ struct intel_context {
>  		bool need_status_change_notification;
>  		struct atomic_notifier_head status_notifier_head;
>  	} engine[I915_NUM_RINGS];
> +	bool single_submission;
>  
>  	struct list_head link;
>  };
> diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
> index ae1ab92..3a047fe 100644
> --- a/drivers/gpu/drm/i915/intel_lrc.c
> +++ b/drivers/gpu/drm/i915/intel_lrc.c
> @@ -472,6 +472,9 @@ static void execlists_context_unqueue(struct intel_engine_cs *ring)
>  				 execlist_link) {
>  		if (!req0) {
>  			req0 = cursor;
> +			/* req0 ctx requires single submission, stop picking */
> +			if (req0->ctx->single_submission)
> +				break;
>  		} else if (req0->ctx == cursor->ctx) {
>  			/* Same ctx: ignore first request, as second request
>  			 * will update tail past first request's workload */
> @@ -480,7 +483,12 @@ static void execlists_context_unqueue(struct intel_engine_cs *ring)
>  				       &ring->execlist_retired_req_list);
>  			req0 = cursor;
>  		} else {
> -			req1 = cursor;
> +			/*
> +			 * req0 ctx doesn't require single submission, but
> +			 * next req ctx requires, stop picking req1
> +			 */
> +			if (!cursor->ctx->single_submission)
> +				req1 = cursor;
>  			break;
>  		}
>  	}
> diff --git a/drivers/gpu/drm/i915/intel_lrc.h b/drivers/gpu/drm/i915/intel_lrc.h
> index 15791d4..4873dd8 100644
> --- a/drivers/gpu/drm/i915/intel_lrc.h
> +++ b/drivers/gpu/drm/i915/intel_lrc.h
> @@ -107,6 +107,7 @@ struct intel_lr_context_alloc_params {
>  	u32 ringbuffer_size;
>  	bool ctx_needs_init;
>  	bool ctx_needs_status_change_notification;
> +	bool ctx_needs_single_submission;

Random garbage.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [RFCv3 14/15] drm/i915: factor out and expose i915_steal_fence()
  2016-03-11 12:29     ` Wang, Zhi A
@ 2016-03-11 12:42       ` Chris Wilson
  2016-03-11 12:53         ` Wang, Zhi A
  2016-03-11 12:55         ` Wang, Zhi A
  0 siblings, 2 replies; 29+ messages in thread
From: Chris Wilson @ 2016-03-11 12:42 UTC (permalink / raw)
  To: Wang, Zhi A
  Cc: daniel.vetter, intel-gfx, Cowperthwaite, David J, igvt-g, Lv, Zhiyuan

On Fri, Mar 11, 2016 at 12:29:06PM +0000, Wang, Zhi A wrote:
> Hi Chris:
>     Do you mean I should also check the fence pin count in this API like i915_find_fence_reg, then it will be safe here? :) 

Along those lines. I don't like the prospect of exporting this API and
without seeing the consumer I cannot advise on a better method.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [RFCv3 11/15] drm/i915: Introduce execlist context status change notification
  2016-03-11 11:28   ` Chris Wilson
@ 2016-03-11 12:47     ` Wang, Zhi A
  0 siblings, 0 replies; 29+ messages in thread
From: Wang, Zhi A @ 2016-03-11 12:47 UTC (permalink / raw)
  To: Chris Wilson
  Cc: daniel.vetter, intel-gfx, Cowperthwaite, David J, igvt-g, Lv, Zhiyuan

Hi Chirs:
     Could you elaborate your idea here? :) As we have to know the status change of the LRC context, not only the request to copy the content back to guest (There will be a small window between a request is finished and the context is switched out). We tried i915_wait_request() before, looks not help... And it seems only CSB change will show the context is really idle. 

-----Original Message-----
From: Chris Wilson [mailto:chris@chris-wilson.co.uk] 
Sent: Friday, March 11, 2016 7:28 PM
To: Wang, Zhi A
Cc: intel-gfx@lists.freedesktop.org; igvt-g@lists.01.org; Tian, Kevin; Lv, Zhiyuan; Niu, Bing; Song, Jike; daniel.vetter@ffwll.ch; Cowperthwaite, David J; joonas.lahtinen@linux.intel.com
Subject: Re: [RFCv3 11/15] drm/i915: Introduce execlist context status change notification

On Fri, Mar 11, 2016 at 06:59:42PM +0800, Zhi Wang wrote:
> This patch introduces an approach to track the execlist context status
> change.
> 
> GVT-g uses GVT context as the "shadow context". The content inside GVT
> context will be copied back to guest after the context is idle. So GVT-g
> has to know the status of the execlist context.
> 
> This function is configurable in the context creation service. Currently,
> Only GVT-g will create the "status-change-notification" enabled GEM
> context.

Nope. Please hook into the lower-frequency idle mechanism then.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [RFCv3 14/15] drm/i915: factor out and expose i915_steal_fence()
  2016-03-11 12:42       ` Chris Wilson
@ 2016-03-11 12:53         ` Wang, Zhi A
  2016-03-11 12:55         ` Wang, Zhi A
  1 sibling, 0 replies; 29+ messages in thread
From: Wang, Zhi A @ 2016-03-11 12:53 UTC (permalink / raw)
  To: Chris Wilson
  Cc: daniel.vetter, intel-gfx, Cowperthwaite, David J, igvt-g, Lv, Zhiyuan

OK. I see. Previously the fence registers for host  is partitioned. For example, host i915 will only take 4 fence registers, others are kept by GVT-g resource allocator for vGPUs. Danile and Kevin, they thought we could use i915 fence stealing functionality to prevent this static partition. So my idea is:

a. When GVT create a guest, it will call i915_find_fence_regs for available physical fence registers.
b. Then it will call i915_steal_fence and pin these fence registers for vGPUs.
c. Then unpin them, when a guest is destroyed.

So I expose these two APIs. Do you have any better ideas to share? :)

And thanks for the comments. :)

-----Original Message-----
From: Chris Wilson [mailto:chris@chris-wilson.co.uk] 
Sent: Friday, March 11, 2016 8:43 PM
To: Wang, Zhi A
Cc: intel-gfx@lists.freedesktop.org; igvt-g@lists.01.org; Tian, Kevin; Lv, Zhiyuan; Niu, Bing; Song, Jike; daniel.vetter@ffwll.ch; Cowperthwaite, David J; joonas.lahtinen@linux.intel.com
Subject: Re: [RFCv3 14/15] drm/i915: factor out and expose i915_steal_fence()

On Fri, Mar 11, 2016 at 12:29:06PM +0000, Wang, Zhi A wrote:
> Hi Chris:
>     Do you mean I should also check the fence pin count in this API like i915_find_fence_reg, then it will be safe here? :) 

Along those lines. I don't like the prospect of exporting this API and
without seeing the consumer I cannot advise on a better method.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [RFCv3 14/15] drm/i915: factor out and expose i915_steal_fence()
  2016-03-11 12:42       ` Chris Wilson
  2016-03-11 12:53         ` Wang, Zhi A
@ 2016-03-11 12:55         ` Wang, Zhi A
  1 sibling, 0 replies; 29+ messages in thread
From: Wang, Zhi A @ 2016-03-11 12:55 UTC (permalink / raw)
  To: Chris Wilson
  Cc: daniel.vetter, intel-gfx, Cowperthwaite, David J, igvt-g, Lv, Zhiyuan

BTW, for better review, I didn't send out the whole GVT-g device model here. Just the patches related to i915... :)

-----Original Message-----
From: Wang, Zhi A 
Sent: Friday, March 11, 2016 8:54 PM
To: 'Chris Wilson'
Cc: intel-gfx@lists.freedesktop.org; igvt-g@lists.01.org; Tian, Kevin; Lv, Zhiyuan; Niu, Bing; Song, Jike; daniel.vetter@ffwll.ch; Cowperthwaite, David J; joonas.lahtinen@linux.intel.com
Subject: RE: [RFCv3 14/15] drm/i915: factor out and expose i915_steal_fence()

OK. I see. Previously the fence registers for host  is partitioned. For example, host i915 will only take 4 fence registers, others are kept by GVT-g resource allocator for vGPUs. Danile and Kevin, they thought we could use i915 fence stealing functionality to prevent this static partition. So my idea is:

a. When GVT create a guest, it will call i915_find_fence_regs for available physical fence registers.
b. Then it will call i915_steal_fence and pin these fence registers for vGPUs.
c. Then unpin them, when a guest is destroyed.

So I expose these two APIs. Do you have any better ideas to share? :)

And thanks for the comments. :)

-----Original Message-----
From: Chris Wilson [mailto:chris@chris-wilson.co.uk] 
Sent: Friday, March 11, 2016 8:43 PM
To: Wang, Zhi A
Cc: intel-gfx@lists.freedesktop.org; igvt-g@lists.01.org; Tian, Kevin; Lv, Zhiyuan; Niu, Bing; Song, Jike; daniel.vetter@ffwll.ch; Cowperthwaite, David J; joonas.lahtinen@linux.intel.com
Subject: Re: [RFCv3 14/15] drm/i915: factor out and expose i915_steal_fence()

On Fri, Mar 11, 2016 at 12:29:06PM +0000, Wang, Zhi A wrote:
> Hi Chris:
>     Do you mean I should also check the fence pin count in this API like i915_find_fence_reg, then it will be safe here? :) 

Along those lines. I don't like the prospect of exporting this API and
without seeing the consumer I cannot advise on a better method.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [RFCv3 10/15] drm/i915: update PDPs by condition when submit the LRC context
  2016-03-11 11:27   ` Chris Wilson
@ 2016-03-11 12:56     ` Wang, Zhi A
  2016-03-16  6:32       ` Zhi Wang
  0 siblings, 1 reply; 29+ messages in thread
From: Wang, Zhi A @ 2016-03-11 12:56 UTC (permalink / raw)
  To: Chris Wilson
  Cc: daniel.vetter, intel-gfx, Cowperthwaite, David J, igvt-g, Lv, Zhiyuan

OK. I will see. :) Thanks for the comments. 

-----Original Message-----
From: Chris Wilson [mailto:chris@chris-wilson.co.uk] 
Sent: Friday, March 11, 2016 7:28 PM
To: Wang, Zhi A
Cc: intel-gfx@lists.freedesktop.org; igvt-g@lists.01.org; Tian, Kevin; Lv, Zhiyuan; Niu, Bing; Song, Jike; daniel.vetter@ffwll.ch; Cowperthwaite, David J; joonas.lahtinen@linux.intel.com
Subject: Re: [RFCv3 10/15] drm/i915: update PDPs by condition when submit the LRC context

On Fri, Mar 11, 2016 at 06:59:41PM +0800, Zhi Wang wrote:
> Previously the PDPs inside the ring context will be updated
> 
> - When populating a LRC context
> - Before submitting a LRC context (only for 32 bit PPGTT, as the amount
> of used PDPs may be changed during PPGTT page table grow)
> 
> Under GVT-g, each VM owns a GVT context used as the shadow context. When
> guest submits a context, GVT-g will load guest context into the GVT
> context, and submit this context to i915 GEM submission system.
> 
> So this GVT context could be used by different guest context, and the
> PPGTT root pointer in guest contexts might be different as well, if guest
> is using full PPGTT mode.
> 
> In current i915, the root pointer in a LRC context will only be updated
> during the LRC context creation.
> 
> This patch postpones the root pointer upgrade to the time of submission,
> which will give GVT-g a chance to reload a new PPGTT page table root
> pointer into an existing GVT context.

Not explained is why you cannot use the existing dirty flags.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [RFCv3 10/15] drm/i915: update PDPs by condition when submit the LRC context
  2016-03-11 12:56     ` Wang, Zhi A
@ 2016-03-16  6:32       ` Zhi Wang
  0 siblings, 0 replies; 29+ messages in thread
From: Zhi Wang @ 2016-03-16  6:32 UTC (permalink / raw)
  To: Chris Wilson
  Cc: daniel.vetter, intel-gfx, Cowperthwaite, David J, igvt-g, Lv, Zhiyuan

Hi Chris:
     Your idea is good. :) We could emit PDP upgrade LRIs like i915 
before emit GVT worload under GVT context, then we can reuse the 
pd_dirty_ring bitmap.

But I have to expose intel_logical_ring_emit_pdps() function for GVT-g. 
Is it acceptable?

Thanks,
Zhi.

On 03/11/16 20:56, Wang, Zhi A wrote:
> OK. I will see. :) Thanks for the comments.
>
> -----Original Message-----
> From: Chris Wilson [mailto:chris@chris-wilson.co.uk]
> Sent: Friday, March 11, 2016 7:28 PM
> To: Wang, Zhi A
> Cc: intel-gfx@lists.freedesktop.org; igvt-g@lists.01.org; Tian, Kevin; Lv, Zhiyuan; Niu, Bing; Song, Jike; daniel.vetter@ffwll.ch; Cowperthwaite, David J; joonas.lahtinen@linux.intel.com
> Subject: Re: [RFCv3 10/15] drm/i915: update PDPs by condition when submit the LRC context
>
> On Fri, Mar 11, 2016 at 06:59:41PM +0800, Zhi Wang wrote:
>> Previously the PDPs inside the ring context will be updated
>>
>> - When populating a LRC context
>> - Before submitting a LRC context (only for 32 bit PPGTT, as the amount
>> of used PDPs may be changed during PPGTT page table grow)
>>
>> Under GVT-g, each VM owns a GVT context used as the shadow context. When
>> guest submits a context, GVT-g will load guest context into the GVT
>> context, and submit this context to i915 GEM submission system.
>>
>> So this GVT context could be used by different guest context, and the
>> PPGTT root pointer in guest contexts might be different as well, if guest
>> is using full PPGTT mode.
>>
>> In current i915, the root pointer in a LRC context will only be updated
>> during the LRC context creation.
>>
>> This patch postpones the root pointer upgrade to the time of submission,
>> which will give GVT-g a chance to reload a new PPGTT page table root
>> pointer into an existing GVT context.
>
> Not explained is why you cannot use the existing dirty flags.
> -Chris
>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 29+ messages in thread

end of thread, other threads:[~2016-03-16  6:35 UTC | newest]

Thread overview: 29+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-03-11 10:59 [RFCv3 00/15] Introduce GVT context support Zhi Wang
2016-03-11 10:59 ` [RFCv3 01/15] drm/i915: factor out i915_pvinfo.h Zhi Wang
2016-03-11 10:59 ` [RFCv3 02/15] drm/i915/gvt: Introduce the basic architecture of GVT-g Zhi Wang
2016-03-11 10:59 ` [RFCv3 03/15] drm/i915: Introduce host graphics memory partition for GVT-g Zhi Wang
2016-03-11 10:59 ` [RFCv3 04/15] drm/i915: factor out alloc_context_idr() and __i915_gem_create_context() Zhi Wang
2016-03-11 10:59 ` [RFCv3 05/15] drm/i915: factor out __create_legacy_hw_context() Zhi Wang
2016-03-11 10:59 ` [RFCv3 06/15] drm/i915: let __i915_gem_context_create() takes context creation params Zhi Wang
2016-03-11 10:59 ` [RFCv3 07/15] drm/i915: factor out __intel_lr_context_deferred_alloc() Zhi Wang
2016-03-11 10:59 ` [RFCv3 08/15] drm/i915: Support per-PPGTT address space mode Zhi Wang
2016-03-11 10:59 ` [RFCv3 09/15] drm/i915: generate address mode bit from PPGTT instance Zhi Wang
2016-03-11 10:59 ` [RFCv3 10/15] drm/i915: update PDPs by condition when submit the LRC context Zhi Wang
2016-03-11 11:27   ` Chris Wilson
2016-03-11 12:56     ` Wang, Zhi A
2016-03-16  6:32       ` Zhi Wang
2016-03-11 10:59 ` [RFCv3 11/15] drm/i915: Introduce execlist context status change notification Zhi Wang
2016-03-11 11:28   ` Chris Wilson
2016-03-11 12:47     ` Wang, Zhi A
2016-03-11 10:59 ` [RFCv3 12/15] drm/i915: Support context single submission Zhi Wang
2016-03-11 11:25   ` Chris Wilson
2016-03-11 12:42     ` Wang, Zhi A
2016-03-11 10:59 ` [RFCv3 13/15] drm/i915: Introduce GVT context creation API Zhi Wang
2016-03-11 10:59 ` [RFCv3 14/15] drm/i915: factor out and expose i915_steal_fence() Zhi Wang
2016-03-11 11:21   ` Chris Wilson
2016-03-11 12:29     ` Wang, Zhi A
2016-03-11 12:42       ` Chris Wilson
2016-03-11 12:53         ` Wang, Zhi A
2016-03-11 12:55         ` Wang, Zhi A
2016-03-11 10:59 ` [RFCv3 15/15] drm/i915: expose i915_find_fence_reg() Zhi Wang
2016-03-11 11:09 ` ✗ Fi.CI.BAT: failure for Introduce GVT context support Patchwork

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.