diff mbox series

[v2,4/5] drm/i915: master irq pvmmio optimization

Message ID 1539934034-31343-5-git-send-email-xiaolin.zhang@intel.com (mailing list archive)
State New, archived
Headers show
Series i915 pvmmio to improve GVTg performance | expand

Commit Message

Xiaolin Zhang Oct. 19, 2018, 7:27 a.m. UTC
Master irq register is accessed twice every irq handling, then trapped
to SOS very frequently. Optimize it by moving master irq register
to share page, writing don't need be trapped.

When need enable irq to let SOS inject irq timely, use another pvmmio
register to achieve this purpose. So avoid one trap when we disable
master irq.

Use PVMMIO_MASTER_IRQ to control this level of pvmmio optimization.

v0: RFC
v1: rebase
v2: added pv version callbacks for irq_{irq_handler, irq_preinstall,
irq_postinstall}

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

Comments

Xiaolin Zhang Oct. 31, 2018, 9:18 a.m. UTC | #1
Ping review. Thanks very much. 

BRs, Xiaolin

-----Original Message-----
From: Zhang, Xiaolin 
Sent: Friday, October 19, 2018 3:27 PM
To: intel-gfx@lists.freedesktop.org
Cc: intel-gvt-dev@lists.freedesktop.org; Zhang, Xiaolin <xiaolin.zhang@intel.com>; Zhenyu Wang <zhenyuw@linux.intel.com>; Wang, Zhi A <zhi.a.wang@intel.com>; Chris Wilson <chris@chris-wilson.co.uk>; Joonas Lahtinen <joonas.lahtinen@linux.intel.com>; He; He, Min <min.he@intel.com>; Jiang; Jiang, Fei <fei.jiang@intel.com>; Gong; Gong, Zhipeng <zhipeng.gong@intel.com>; Yuan; Yuan, Hang <hang.yuan@intel.com>; Lv, Zhiyuan <zhiyuan.lv@intel.com>
Subject: [PATCH v2 4/5] drm/i915: master irq pvmmio optimization

Master irq register is accessed twice every irq handling, then trapped to SOS very frequently. Optimize it by moving master irq register to share page, writing don't need be trapped.

When need enable irq to let SOS inject irq timely, use another pvmmio register to achieve this purpose. So avoid one trap when we disable master irq.

Use PVMMIO_MASTER_IRQ to control this level of pvmmio optimization.

v0: RFC
v1: rebase
v2: added pv version callbacks for irq_{irq_handler, irq_preinstall, irq_postinstall}

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

diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 5d1f537..95ed2e7 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -2938,6 +2938,40 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg)
 	return IRQ_HANDLED;
 }
 
+static irqreturn_t gen8_irq_handler_pv(int irq, void *arg) {
+	struct drm_i915_private *dev_priv = to_i915(arg);
+	u32 master_ctl;
+	u32 gt_iir[4];
+
+	if (!intel_irqs_enabled(dev_priv))
+		return IRQ_NONE;
+
+	master_ctl = I915_READ_FW(GEN8_MASTER_IRQ);
+	master_ctl &= ~GEN8_MASTER_IRQ_CONTROL;
+	if (!master_ctl)
+		return IRQ_NONE;
+
+	dev_priv->vgpu.shared_page->disable_irq = 1;
+
+	/* Find, clear, then process each source of interrupt */
+	gen8_gt_irq_ack(dev_priv, master_ctl, gt_iir);
+
+	/* IRQs are synced during runtime_suspend, we don't require a wakeref */
+	if (master_ctl & ~GEN8_GT_IRQS) {
+		disable_rpm_wakeref_asserts(dev_priv);
+		gen8_de_irq_handler(dev_priv, master_ctl);
+		enable_rpm_wakeref_asserts(dev_priv);
+	}
+
+	dev_priv->vgpu.shared_page->disable_irq = 0;
+	__raw_i915_write32(dev_priv, vgtif_reg(check_pending_irq), 1);
+
+	gen8_gt_irq_handler(dev_priv, master_ctl, gt_iir);
+
+	return IRQ_HANDLED;
+}
+
 struct wedge_me {
 	struct delayed_work work;
 	struct drm_i915_private *i915;
@@ -3626,13 +3660,11 @@ static void gen8_gt_irq_reset(struct drm_i915_private *dev_priv)
 	GEN8_IRQ_RESET_NDX(GT, 3);
 }
 
-static void gen8_irq_reset(struct drm_device *dev)
+static void gen8_irq_reset_common(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = to_i915(dev);
 	int pipe;
 
-	gen8_master_intr_disable(dev_priv->regs);
-
 	gen8_gt_irq_reset(dev_priv);
 
 	I915_WRITE(EDP_PSR_IMR, 0xffffffff);
@@ -3651,6 +3683,22 @@ static void gen8_irq_reset(struct drm_device *dev)
 		ibx_irq_reset(dev_priv);
 }
 
+static void gen8_irq_reset(struct drm_device *dev) {
+	struct drm_i915_private *dev_priv = to_i915(dev);
+
+	gen8_master_intr_disable(dev_priv->regs);
+	gen8_irq_reset_common(dev);
+}
+
+static void gen8_irq_reset_pv(struct drm_device *dev) {
+	struct drm_i915_private *dev_priv = to_i915(dev);
+
+	dev_priv->vgpu.shared_page->disable_irq = 1;
+	gen8_irq_reset_common(dev);
+}
+
 static void gen11_gt_irq_reset(struct drm_i915_private *dev_priv)  {
 	/* Disable RCS, BCS, VCS and VECS class engines. */ @@ -4262,7 +4310,7 @@ static void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv)
 	}
 }
 
-static int gen8_irq_postinstall(struct drm_device *dev)
+static int gen8_irq_postinstall_common(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = to_i915(dev);
 
@@ -4275,11 +4323,32 @@ static int gen8_irq_postinstall(struct drm_device *dev)
 	if (HAS_PCH_SPLIT(dev_priv))
 		ibx_irq_postinstall(dev);
 
+	return 0;
+}
+
+static int gen8_irq_postinstall(struct drm_device *dev) {
+	struct drm_i915_private *dev_priv = to_i915(dev);
+
+	gen8_irq_postinstall_common(dev);
+
 	gen8_master_intr_enable(dev_priv->regs);
 
 	return 0;
 }
 
+static int gen8_irq_postinstall_pv(struct drm_device *dev) {
+	struct drm_i915_private *dev_priv = to_i915(dev);
+
+	gen8_irq_postinstall_common(dev);
+
+	dev_priv->vgpu.shared_page->disable_irq = 0;
+	__raw_i915_write32(dev_priv, vgtif_reg(check_pending_irq), 1);
+
+	return 0;
+}
+
 static void gen11_gt_irq_postinstall(struct drm_i915_private *dev_priv)  {
 	const u32 irqs = GT_RENDER_USER_INTERRUPT | GT_CONTEXT_SWITCH_INTERRUPT; @@ -4895,6 +4964,11 @@ void intel_irq_init(struct drm_i915_private *dev_priv)
 		dev->driver->irq_handler = gen8_irq_handler;
 		dev->driver->irq_preinstall = gen8_irq_reset;
 		dev->driver->irq_postinstall = gen8_irq_postinstall;
+		if (PVMMIO_LEVEL_ENABLE(dev_priv, PVMMIO_MASTER_IRQ)) {
+			dev->driver->irq_handler = gen8_irq_handler_pv;
+			dev->driver->irq_preinstall = gen8_irq_reset_pv;
+			dev->driver->irq_postinstall = gen8_irq_postinstall_pv;
+		}
 		dev->driver->irq_uninstall = gen8_irq_reset;
 		dev->driver->enable_vblank = gen8_enable_vblank;
 		dev->driver->disable_vblank = gen8_disable_vblank; diff --git a/drivers/gpu/drm/i915/i915_pvinfo.h b/drivers/gpu/drm/i915/i915_pvinfo.h
index 179d558..1e24c45 100644
--- a/drivers/gpu/drm/i915/i915_pvinfo.h
+++ b/drivers/gpu/drm/i915/i915_pvinfo.h
@@ -143,8 +143,9 @@ struct vgt_if {
 		u32 lo;
 		u32 hi;
 	} shared_page_gpa;
+	u32 check_pending_irq;
 
-	u32  rsv7[0x200 - 27];    /* pad to one page */
+	u32  rsv7[0x200 - 28];    /* pad to one page */
 } __packed;
 
 #define vgtif_reg(x) \
diff --git a/drivers/gpu/drm/i915/i915_vgpu.c b/drivers/gpu/drm/i915/i915_vgpu.c
index 9870ea6..013d329 100644
--- a/drivers/gpu/drm/i915/i915_vgpu.c
+++ b/drivers/gpu/drm/i915/i915_vgpu.c
@@ -66,7 +66,7 @@ void i915_check_vgpu(struct drm_i915_private *dev_priv)
 
 	BUILD_BUG_ON(sizeof(struct vgt_if) != VGT_PVINFO_SIZE);
 
-	dev_priv->vgpu.pv_caps = PVMMIO_ELSP_SUBMIT;
+	dev_priv->vgpu.pv_caps = PVMMIO_ELSP_SUBMIT | PVMMIO_MASTER_IRQ;
 
 	magic = __raw_i915_read64(dev_priv, vgtif_reg(magic));
 	if (magic != VGT_MAGIC)
--
2.7.4
diff mbox series

Patch

diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 5d1f537..95ed2e7 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -2938,6 +2938,40 @@  static irqreturn_t gen8_irq_handler(int irq, void *arg)
 	return IRQ_HANDLED;
 }
 
+static irqreturn_t gen8_irq_handler_pv(int irq, void *arg)
+{
+	struct drm_i915_private *dev_priv = to_i915(arg);
+	u32 master_ctl;
+	u32 gt_iir[4];
+
+	if (!intel_irqs_enabled(dev_priv))
+		return IRQ_NONE;
+
+	master_ctl = I915_READ_FW(GEN8_MASTER_IRQ);
+	master_ctl &= ~GEN8_MASTER_IRQ_CONTROL;
+	if (!master_ctl)
+		return IRQ_NONE;
+
+	dev_priv->vgpu.shared_page->disable_irq = 1;
+
+	/* Find, clear, then process each source of interrupt */
+	gen8_gt_irq_ack(dev_priv, master_ctl, gt_iir);
+
+	/* IRQs are synced during runtime_suspend, we don't require a wakeref */
+	if (master_ctl & ~GEN8_GT_IRQS) {
+		disable_rpm_wakeref_asserts(dev_priv);
+		gen8_de_irq_handler(dev_priv, master_ctl);
+		enable_rpm_wakeref_asserts(dev_priv);
+	}
+
+	dev_priv->vgpu.shared_page->disable_irq = 0;
+	__raw_i915_write32(dev_priv, vgtif_reg(check_pending_irq), 1);
+
+	gen8_gt_irq_handler(dev_priv, master_ctl, gt_iir);
+
+	return IRQ_HANDLED;
+}
+
 struct wedge_me {
 	struct delayed_work work;
 	struct drm_i915_private *i915;
@@ -3626,13 +3660,11 @@  static void gen8_gt_irq_reset(struct drm_i915_private *dev_priv)
 	GEN8_IRQ_RESET_NDX(GT, 3);
 }
 
-static void gen8_irq_reset(struct drm_device *dev)
+static void gen8_irq_reset_common(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = to_i915(dev);
 	int pipe;
 
-	gen8_master_intr_disable(dev_priv->regs);
-
 	gen8_gt_irq_reset(dev_priv);
 
 	I915_WRITE(EDP_PSR_IMR, 0xffffffff);
@@ -3651,6 +3683,22 @@  static void gen8_irq_reset(struct drm_device *dev)
 		ibx_irq_reset(dev_priv);
 }
 
+static void gen8_irq_reset(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = to_i915(dev);
+
+	gen8_master_intr_disable(dev_priv->regs);
+	gen8_irq_reset_common(dev);
+}
+
+static void gen8_irq_reset_pv(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = to_i915(dev);
+
+	dev_priv->vgpu.shared_page->disable_irq = 1;
+	gen8_irq_reset_common(dev);
+}
+
 static void gen11_gt_irq_reset(struct drm_i915_private *dev_priv)
 {
 	/* Disable RCS, BCS, VCS and VECS class engines. */
@@ -4262,7 +4310,7 @@  static void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv)
 	}
 }
 
-static int gen8_irq_postinstall(struct drm_device *dev)
+static int gen8_irq_postinstall_common(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = to_i915(dev);
 
@@ -4275,11 +4323,32 @@  static int gen8_irq_postinstall(struct drm_device *dev)
 	if (HAS_PCH_SPLIT(dev_priv))
 		ibx_irq_postinstall(dev);
 
+	return 0;
+}
+
+static int gen8_irq_postinstall(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = to_i915(dev);
+
+	gen8_irq_postinstall_common(dev);
+
 	gen8_master_intr_enable(dev_priv->regs);
 
 	return 0;
 }
 
+static int gen8_irq_postinstall_pv(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = to_i915(dev);
+
+	gen8_irq_postinstall_common(dev);
+
+	dev_priv->vgpu.shared_page->disable_irq = 0;
+	__raw_i915_write32(dev_priv, vgtif_reg(check_pending_irq), 1);
+
+	return 0;
+}
+
 static void gen11_gt_irq_postinstall(struct drm_i915_private *dev_priv)
 {
 	const u32 irqs = GT_RENDER_USER_INTERRUPT | GT_CONTEXT_SWITCH_INTERRUPT;
@@ -4895,6 +4964,11 @@  void intel_irq_init(struct drm_i915_private *dev_priv)
 		dev->driver->irq_handler = gen8_irq_handler;
 		dev->driver->irq_preinstall = gen8_irq_reset;
 		dev->driver->irq_postinstall = gen8_irq_postinstall;
+		if (PVMMIO_LEVEL_ENABLE(dev_priv, PVMMIO_MASTER_IRQ)) {
+			dev->driver->irq_handler = gen8_irq_handler_pv;
+			dev->driver->irq_preinstall = gen8_irq_reset_pv;
+			dev->driver->irq_postinstall = gen8_irq_postinstall_pv;
+		}
 		dev->driver->irq_uninstall = gen8_irq_reset;
 		dev->driver->enable_vblank = gen8_enable_vblank;
 		dev->driver->disable_vblank = gen8_disable_vblank;
diff --git a/drivers/gpu/drm/i915/i915_pvinfo.h b/drivers/gpu/drm/i915/i915_pvinfo.h
index 179d558..1e24c45 100644
--- a/drivers/gpu/drm/i915/i915_pvinfo.h
+++ b/drivers/gpu/drm/i915/i915_pvinfo.h
@@ -143,8 +143,9 @@  struct vgt_if {
 		u32 lo;
 		u32 hi;
 	} shared_page_gpa;
+	u32 check_pending_irq;
 
-	u32  rsv7[0x200 - 27];    /* pad to one page */
+	u32  rsv7[0x200 - 28];    /* pad to one page */
 } __packed;
 
 #define vgtif_reg(x) \
diff --git a/drivers/gpu/drm/i915/i915_vgpu.c b/drivers/gpu/drm/i915/i915_vgpu.c
index 9870ea6..013d329 100644
--- a/drivers/gpu/drm/i915/i915_vgpu.c
+++ b/drivers/gpu/drm/i915/i915_vgpu.c
@@ -66,7 +66,7 @@  void i915_check_vgpu(struct drm_i915_private *dev_priv)
 
 	BUILD_BUG_ON(sizeof(struct vgt_if) != VGT_PVINFO_SIZE);
 
-	dev_priv->vgpu.pv_caps = PVMMIO_ELSP_SUBMIT;
+	dev_priv->vgpu.pv_caps = PVMMIO_ELSP_SUBMIT | PVMMIO_MASTER_IRQ;
 
 	magic = __raw_i915_read64(dev_priv, vgtif_reg(magic));
 	if (magic != VGT_MAGIC)