* [PATCH 02/13] drm/i915: Virtualize the ringbuffer signal func
2014-01-29 19:55 [PATCH 00/13] [REPOST] Broadwell HW semaphores Ben Widawsky
@ 2014-01-29 19:55 ` Ben Widawsky
0 siblings, 0 replies; 23+ messages in thread
From: Ben Widawsky @ 2014-01-29 19:55 UTC (permalink / raw)
To: Intel GFX; +Cc: Ben Widawsky, Ben Widawsky
This abstraction again is in preparation for gen8. Gen8 will bring new
semantics for doing this operation.
While here, make the writes of MI_NOOPs explicit for non-existent rings.
This should have been implicit before.
NOTE: This is going to be removed in a few patches.
Signed-off-by: Ben Widawsky <ben@bwidawsk.net>
---
drivers/gpu/drm/i915/intel_ringbuffer.c | 42 ++++++++++++++++++++-------------
drivers/gpu/drm/i915/intel_ringbuffer.h | 2 ++
2 files changed, 27 insertions(+), 17 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index 4588d7f..1ff3d9d 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -632,20 +632,32 @@ static void render_ring_cleanup(struct intel_ring_buffer *ring)
ring->scratch.obj = NULL;
}
-static void
-update_mboxes(struct intel_ring_buffer *ring,
- u32 mmio_offset)
+static void gen6_signal(struct intel_ring_buffer *signaller)
{
+ struct drm_i915_private *dev_priv = signaller->dev->dev_private;
+ struct intel_ring_buffer *useless;
+ int i;
+
/* NB: In order to be able to do semaphore MBOX updates for varying number
* of rings, it's easiest if we round up each individual update to a
* multiple of 2 (since ring updates must always be a multiple of 2)
* even though the actual update only requires 3 dwords.
*/
#define MBOX_UPDATE_DWORDS 4
- intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1));
- intel_ring_emit(ring, mmio_offset);
- intel_ring_emit(ring, ring->outstanding_lazy_seqno);
- intel_ring_emit(ring, MI_NOOP);
+ for_each_ring(useless, dev_priv, i) {
+ u32 mbox_reg = signaller->semaphore.signal_mbox[i];
+ if (mbox_reg != GEN6_NOSYNC) {
+ intel_ring_emit(signaller, MI_LOAD_REGISTER_IMM(1));
+ intel_ring_emit(signaller, mbox_reg);
+ intel_ring_emit(signaller, signaller->outstanding_lazy_seqno);
+ intel_ring_emit(signaller, MI_NOOP);
+ } else {
+ intel_ring_emit(signaller, MI_NOOP);
+ intel_ring_emit(signaller, MI_NOOP);
+ intel_ring_emit(signaller, MI_NOOP);
+ intel_ring_emit(signaller, MI_NOOP);
+ }
+ }
}
/**
@@ -661,9 +673,7 @@ static int
gen6_add_request(struct intel_ring_buffer *ring)
{
struct drm_device *dev = ring->dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_ring_buffer *useless;
- int i, ret, num_dwords = 4;
+ int ret, num_dwords = 4;
if (i915_semaphore_is_enabled(dev))
num_dwords += ((I915_NUM_RINGS-1) * MBOX_UPDATE_DWORDS);
@@ -673,13 +683,7 @@ gen6_add_request(struct intel_ring_buffer *ring)
if (ret)
return ret;
- if (i915_semaphore_is_enabled(dev)) {
- for_each_ring(useless, dev_priv, i) {
- u32 mbox_reg = ring->semaphore.signal_mbox[i];
- if (mbox_reg != GEN6_NOSYNC)
- update_mboxes(ring, mbox_reg);
- }
- }
+ ring->semaphore.signal(ring);
intel_ring_emit(ring, MI_STORE_DWORD_INDEX);
intel_ring_emit(ring, I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
@@ -1872,6 +1876,7 @@ int intel_init_render_ring_buffer(struct drm_device *dev)
ring->get_seqno = gen6_ring_get_seqno;
ring->set_seqno = ring_set_seqno;
ring->semaphore.sync_to = gen6_ring_sync;
+ ring->semaphore.signal = gen6_signal;
ring->semaphore.mbox[RCS] = MI_SEMAPHORE_SYNC_INVALID;
ring->semaphore.mbox[VCS] = MI_SEMAPHORE_SYNC_RV;
ring->semaphore.mbox[BCS] = MI_SEMAPHORE_SYNC_RB;
@@ -2048,6 +2053,7 @@ int intel_init_bsd_ring_buffer(struct drm_device *dev)
gen6_ring_dispatch_execbuffer;
}
ring->semaphore.sync_to = gen6_ring_sync;
+ ring->semaphore.signal = gen6_signal;
ring->semaphore.mbox[RCS] = MI_SEMAPHORE_SYNC_VR;
ring->semaphore.mbox[VCS] = MI_SEMAPHORE_SYNC_INVALID;
ring->semaphore.mbox[BCS] = MI_SEMAPHORE_SYNC_VB;
@@ -2105,6 +2111,7 @@ int intel_init_blt_ring_buffer(struct drm_device *dev)
ring->dispatch_execbuffer = gen6_ring_dispatch_execbuffer;
}
ring->semaphore.sync_to = gen6_ring_sync;
+ ring->semaphore.signal = gen6_signal;
ring->semaphore.mbox[RCS] = MI_SEMAPHORE_SYNC_BR;
ring->semaphore.mbox[VCS] = MI_SEMAPHORE_SYNC_BV;
ring->semaphore.mbox[BCS] = MI_SEMAPHORE_SYNC_INVALID;
@@ -2146,6 +2153,7 @@ int intel_init_vebox_ring_buffer(struct drm_device *dev)
ring->dispatch_execbuffer = gen6_ring_dispatch_execbuffer;
}
ring->semaphore.sync_to = gen6_ring_sync;
+ ring->semaphore.signal = gen6_signal;
ring->semaphore.mbox[RCS] = MI_SEMAPHORE_SYNC_VER;
ring->semaphore.mbox[VCS] = MI_SEMAPHORE_SYNC_VEV;
ring->semaphore.mbox[BCS] = MI_SEMAPHORE_SYNC_VEB;
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
index b5fc768..e01a1ff 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -121,6 +121,8 @@ struct intel_ring_buffer {
u32 mbox[I915_NUM_RINGS];
/* mboxes this ring signals to */
u32 signal_mbox[I915_NUM_RINGS];
+
+ void (*signal)(struct intel_ring_buffer *signaller);
} semaphore;
/**
--
1.8.5.3
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 01/13] drm/i915: Move semaphore specific ring members to struct
@ 2014-02-20 6:19 Ben Widawsky
2014-02-20 6:19 ` [PATCH 02/13] drm/i915: Virtualize the ringbuffer signal func Ben Widawsky
` (12 more replies)
0 siblings, 13 replies; 23+ messages in thread
From: Ben Widawsky @ 2014-02-20 6:19 UTC (permalink / raw)
To: Intel GFX; +Cc: Ben Widawsky, Ben Widawsky
This will be helpful in abstracting some of the code in preparation for
gen8 semaphores.
v2: Move mbox stuff to a separate struct
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> (v1)
Signed-off-by: Ben Widawsky <ben@bwidawsk.net>
---
drivers/gpu/drm/i915/i915_gem.c | 10 ++--
drivers/gpu/drm/i915/i915_gpu_error.c | 6 +--
drivers/gpu/drm/i915/intel_ringbuffer.c | 87 ++++++++++++++++-----------------
drivers/gpu/drm/i915/intel_ringbuffer.h | 19 ++++---
4 files changed, 63 insertions(+), 59 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 3618bb0..2981826 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2089,8 +2089,8 @@ i915_gem_init_seqno(struct drm_device *dev, u32 seqno)
for_each_ring(ring, dev_priv, i) {
intel_ring_init_seqno(ring, seqno);
- for (j = 0; j < ARRAY_SIZE(ring->sync_seqno); j++)
- ring->sync_seqno[j] = 0;
+ for (j = 0; j < ARRAY_SIZE(ring->semaphore.sync_seqno); j++)
+ ring->semaphore.sync_seqno[j] = 0;
}
return 0;
@@ -2661,7 +2661,7 @@ i915_gem_object_sync(struct drm_i915_gem_object *obj,
idx = intel_ring_sync_index(from, to);
seqno = obj->last_read_seqno;
- if (seqno <= from->sync_seqno[idx])
+ if (seqno <= from->semaphore.sync_seqno[idx])
return 0;
ret = i915_gem_check_olr(obj->ring, seqno);
@@ -2669,13 +2669,13 @@ i915_gem_object_sync(struct drm_i915_gem_object *obj,
return ret;
trace_i915_gem_ring_sync_to(from, to, seqno);
- ret = to->sync_to(to, from, seqno);
+ ret = to->semaphore.sync_to(to, from, seqno);
if (!ret)
/* We use last_read_seqno because sync_to()
* might have just caused seqno wrap under
* the radar.
*/
- from->sync_seqno[idx] = obj->last_read_seqno;
+ from->semaphore.sync_seqno[idx] = obj->last_read_seqno;
return ret;
}
diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c
index 000b369..bcab114 100644
--- a/drivers/gpu/drm/i915/i915_gpu_error.c
+++ b/drivers/gpu/drm/i915/i915_gpu_error.c
@@ -810,14 +810,14 @@ static void i915_record_ring_state(struct drm_device *dev,
= I915_READ(RING_SYNC_0(ring->mmio_base));
ering->semaphore_mboxes[1]
= I915_READ(RING_SYNC_1(ring->mmio_base));
- ering->semaphore_seqno[0] = ring->sync_seqno[0];
- ering->semaphore_seqno[1] = ring->sync_seqno[1];
+ ering->semaphore_seqno[0] = ring->semaphore.sync_seqno[0];
+ ering->semaphore_seqno[1] = ring->semaphore.sync_seqno[1];
}
if (HAS_VEBOX(dev)) {
ering->semaphore_mboxes[2] =
I915_READ(RING_SYNC_2(ring->mmio_base));
- ering->semaphore_seqno[2] = ring->sync_seqno[2];
+ ering->semaphore_seqno[2] = ring->semaphore.sync_seqno[2];
}
if (INTEL_INFO(dev)->gen >= 4) {
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index b340c75..626019a 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -677,7 +677,7 @@ gen6_add_request(struct intel_ring_buffer *ring)
if (i915_semaphore_is_enabled(dev)) {
for_each_ring(useless, dev_priv, i) {
- u32 mbox_reg = ring->signal_mbox[i];
+ u32 mbox_reg = ring->semaphore.mbox.signal[i];
if (mbox_reg != GEN6_NOSYNC)
update_mboxes(ring, mbox_reg);
}
@@ -711,10 +711,11 @@ gen6_ring_sync(struct intel_ring_buffer *waiter,
struct intel_ring_buffer *signaller,
u32 seqno)
{
- int ret;
u32 dw1 = MI_SEMAPHORE_MBOX |
MI_SEMAPHORE_COMPARE |
MI_SEMAPHORE_REGISTER;
+ u32 wait_mbox = signaller->semaphore.mbox.wait[waiter->id];
+ int ret;
/* Throughout all of the GEM code, seqno passed implies our current
* seqno is >= the last seqno executed. However for hardware the
@@ -722,8 +723,7 @@ gen6_ring_sync(struct intel_ring_buffer *waiter,
*/
seqno -= 1;
- WARN_ON(signaller->semaphore_register[waiter->id] ==
- MI_SEMAPHORE_SYNC_INVALID);
+ WARN_ON(wait_mbox == MI_SEMAPHORE_SYNC_INVALID);
ret = intel_ring_begin(waiter, 4);
if (ret)
@@ -731,9 +731,7 @@ gen6_ring_sync(struct intel_ring_buffer *waiter,
/* If seqno wrap happened, omit the wait with no-ops */
if (likely(!i915_gem_has_seqno_wrapped(waiter->dev, seqno))) {
- intel_ring_emit(waiter,
- dw1 |
- signaller->semaphore_register[waiter->id]);
+ intel_ring_emit(waiter, dw1 | wait_mbox);
intel_ring_emit(waiter, seqno);
intel_ring_emit(waiter, 0);
intel_ring_emit(waiter, MI_NOOP);
@@ -1331,7 +1329,8 @@ static int intel_init_ring_buffer(struct drm_device *dev,
INIT_LIST_HEAD(&ring->active_list);
INIT_LIST_HEAD(&ring->request_list);
ring->size = 32 * PAGE_SIZE;
- memset(ring->sync_seqno, 0, sizeof(ring->sync_seqno));
+ memset(ring->semaphore.sync_seqno, 0,
+ sizeof(ring->semaphore.sync_seqno));
init_waitqueue_head(&ring->irq_queue);
@@ -1881,15 +1880,15 @@ int intel_init_render_ring_buffer(struct drm_device *dev)
ring->irq_enable_mask = GT_RENDER_USER_INTERRUPT;
ring->get_seqno = gen6_ring_get_seqno;
ring->set_seqno = ring_set_seqno;
- ring->sync_to = gen6_ring_sync;
- ring->semaphore_register[RCS] = MI_SEMAPHORE_SYNC_INVALID;
- ring->semaphore_register[VCS] = MI_SEMAPHORE_SYNC_RV;
- ring->semaphore_register[BCS] = MI_SEMAPHORE_SYNC_RB;
- ring->semaphore_register[VECS] = MI_SEMAPHORE_SYNC_RVE;
- ring->signal_mbox[RCS] = GEN6_NOSYNC;
- ring->signal_mbox[VCS] = GEN6_VRSYNC;
- ring->signal_mbox[BCS] = GEN6_BRSYNC;
- ring->signal_mbox[VECS] = GEN6_VERSYNC;
+ ring->semaphore.sync_to = gen6_ring_sync;
+ ring->semaphore.mbox.wait[RCS] = MI_SEMAPHORE_SYNC_INVALID;
+ ring->semaphore.mbox.wait[VCS] = MI_SEMAPHORE_SYNC_RV;
+ ring->semaphore.mbox.wait[BCS] = MI_SEMAPHORE_SYNC_RB;
+ ring->semaphore.mbox.wait[VECS] = MI_SEMAPHORE_SYNC_RVE;
+ ring->semaphore.mbox.signal[RCS] = GEN6_NOSYNC;
+ ring->semaphore.mbox.signal[VCS] = GEN6_VRSYNC;
+ ring->semaphore.mbox.signal[BCS] = GEN6_BRSYNC;
+ ring->semaphore.mbox.signal[VECS] = GEN6_VERSYNC;
} else if (IS_GEN5(dev)) {
ring->add_request = pc_render_add_request;
ring->flush = gen4_render_ring_flush;
@@ -2057,15 +2056,15 @@ int intel_init_bsd_ring_buffer(struct drm_device *dev)
ring->dispatch_execbuffer =
gen6_ring_dispatch_execbuffer;
}
- ring->sync_to = gen6_ring_sync;
- ring->semaphore_register[RCS] = MI_SEMAPHORE_SYNC_VR;
- ring->semaphore_register[VCS] = MI_SEMAPHORE_SYNC_INVALID;
- ring->semaphore_register[BCS] = MI_SEMAPHORE_SYNC_VB;
- ring->semaphore_register[VECS] = MI_SEMAPHORE_SYNC_VVE;
- ring->signal_mbox[RCS] = GEN6_RVSYNC;
- ring->signal_mbox[VCS] = GEN6_NOSYNC;
- ring->signal_mbox[BCS] = GEN6_BVSYNC;
- ring->signal_mbox[VECS] = GEN6_VEVSYNC;
+ ring->semaphore.sync_to = gen6_ring_sync;
+ ring->semaphore.mbox.wait[RCS] = MI_SEMAPHORE_SYNC_VR;
+ ring->semaphore.mbox.wait[VCS] = MI_SEMAPHORE_SYNC_INVALID;
+ ring->semaphore.mbox.wait[BCS] = MI_SEMAPHORE_SYNC_VB;
+ ring->semaphore.mbox.wait[VECS] = MI_SEMAPHORE_SYNC_VVE;
+ ring->semaphore.mbox.signal[RCS] = GEN6_RVSYNC;
+ ring->semaphore.mbox.signal[VCS] = GEN6_NOSYNC;
+ ring->semaphore.mbox.signal[BCS] = GEN6_BVSYNC;
+ ring->semaphore.mbox.signal[VECS] = GEN6_VEVSYNC;
} else {
ring->mmio_base = BSD_RING_BASE;
ring->flush = bsd_ring_flush;
@@ -2114,15 +2113,15 @@ int intel_init_blt_ring_buffer(struct drm_device *dev)
ring->irq_put = gen6_ring_put_irq;
ring->dispatch_execbuffer = gen6_ring_dispatch_execbuffer;
}
- ring->sync_to = gen6_ring_sync;
- ring->semaphore_register[RCS] = MI_SEMAPHORE_SYNC_BR;
- ring->semaphore_register[VCS] = MI_SEMAPHORE_SYNC_BV;
- ring->semaphore_register[BCS] = MI_SEMAPHORE_SYNC_INVALID;
- ring->semaphore_register[VECS] = MI_SEMAPHORE_SYNC_BVE;
- ring->signal_mbox[RCS] = GEN6_RBSYNC;
- ring->signal_mbox[VCS] = GEN6_VBSYNC;
- ring->signal_mbox[BCS] = GEN6_NOSYNC;
- ring->signal_mbox[VECS] = GEN6_VEBSYNC;
+ ring->semaphore.sync_to = gen6_ring_sync;
+ ring->semaphore.mbox.wait[RCS] = MI_SEMAPHORE_SYNC_BR;
+ ring->semaphore.mbox.wait[VCS] = MI_SEMAPHORE_SYNC_BV;
+ ring->semaphore.mbox.wait[BCS] = MI_SEMAPHORE_SYNC_INVALID;
+ ring->semaphore.mbox.wait[VECS] = MI_SEMAPHORE_SYNC_BVE;
+ ring->semaphore.mbox.signal[RCS] = GEN6_RBSYNC;
+ ring->semaphore.mbox.signal[VCS] = GEN6_VBSYNC;
+ ring->semaphore.mbox.signal[BCS] = GEN6_NOSYNC;
+ ring->semaphore.mbox.signal[VECS] = GEN6_VEBSYNC;
ring->init = init_ring_common;
return intel_init_ring_buffer(dev, ring);
@@ -2155,15 +2154,15 @@ int intel_init_vebox_ring_buffer(struct drm_device *dev)
ring->irq_put = hsw_vebox_put_irq;
ring->dispatch_execbuffer = gen6_ring_dispatch_execbuffer;
}
- ring->sync_to = gen6_ring_sync;
- ring->semaphore_register[RCS] = MI_SEMAPHORE_SYNC_VER;
- ring->semaphore_register[VCS] = MI_SEMAPHORE_SYNC_VEV;
- ring->semaphore_register[BCS] = MI_SEMAPHORE_SYNC_VEB;
- ring->semaphore_register[VECS] = MI_SEMAPHORE_SYNC_INVALID;
- ring->signal_mbox[RCS] = GEN6_RVESYNC;
- ring->signal_mbox[VCS] = GEN6_VVESYNC;
- ring->signal_mbox[BCS] = GEN6_BVESYNC;
- ring->signal_mbox[VECS] = GEN6_NOSYNC;
+ ring->semaphore.sync_to = gen6_ring_sync;
+ ring->semaphore.mbox.wait[RCS] = MI_SEMAPHORE_SYNC_VER;
+ ring->semaphore.mbox.wait[VCS] = MI_SEMAPHORE_SYNC_VEV;
+ ring->semaphore.mbox.wait[BCS] = MI_SEMAPHORE_SYNC_VEB;
+ ring->semaphore.mbox.wait[VECS] = MI_SEMAPHORE_SYNC_INVALID;
+ ring->semaphore.mbox.signal[RCS] = GEN6_RVESYNC;
+ ring->semaphore.mbox.signal[VCS] = GEN6_VVESYNC;
+ ring->semaphore.mbox.signal[BCS] = GEN6_BVESYNC;
+ ring->semaphore.mbox.signal[VECS] = GEN6_NOSYNC;
ring->init = init_ring_common;
return intel_init_ring_buffer(dev, ring);
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
index 08b91c6..8e03c4c 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -85,7 +85,6 @@ struct intel_ring_buffer {
unsigned irq_refcount; /* protected by dev_priv->irq_lock */
u32 irq_enable_mask; /* bitmask to enable ring interrupt */
u32 trace_irq_seqno;
- u32 sync_seqno[I915_NUM_RINGS-1];
bool __must_check (*irq_get)(struct intel_ring_buffer *ring);
void (*irq_put)(struct intel_ring_buffer *ring);
@@ -113,14 +112,20 @@ struct intel_ring_buffer {
#define I915_DISPATCH_SECURE 0x1
#define I915_DISPATCH_PINNED 0x2
void (*cleanup)(struct intel_ring_buffer *ring);
- int (*sync_to)(struct intel_ring_buffer *ring,
+
+ struct {
+ u32 sync_seqno[I915_NUM_RINGS-1];
+ /* AKA wait() */
+ int (*sync_to)(struct intel_ring_buffer *ring,
struct intel_ring_buffer *to,
u32 seqno);
-
- /* our mbox written by others */
- u32 semaphore_register[I915_NUM_RINGS];
- /* mboxes this ring signals to */
- u32 signal_mbox[I915_NUM_RINGS];
+ struct {
+ /* our mbox written by others */
+ u32 wait[I915_NUM_RINGS];
+ /* mboxes this ring signals to */
+ u32 signal[I915_NUM_RINGS];
+ } mbox;
+ } semaphore;
/**
* List of objects currently involved in rendering from the
--
1.9.0
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 02/13] drm/i915: Virtualize the ringbuffer signal func
2014-02-20 6:19 [PATCH 01/13] drm/i915: Move semaphore specific ring members to struct Ben Widawsky
@ 2014-02-20 6:19 ` Ben Widawsky
2014-02-20 6:19 ` [PATCH 03/13] drm/i915: Move ring_begin to signal() Ben Widawsky
` (11 subsequent siblings)
12 siblings, 0 replies; 23+ messages in thread
From: Ben Widawsky @ 2014-02-20 6:19 UTC (permalink / raw)
To: Intel GFX; +Cc: Ben Widawsky, Ben Widawsky
This abstraction again is in preparation for gen8. Gen8 will bring new
semantics for doing this operation.
While here, make the writes of MI_NOOPs explicit for non-existent rings.
This should have been implicit before.
NOTE: This is going to be removed in a few patches.
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Ben Widawsky <ben@bwidawsk.net>
---
drivers/gpu/drm/i915/intel_ringbuffer.c | 42 ++++++++++++++++++++-------------
drivers/gpu/drm/i915/intel_ringbuffer.h | 11 +++++----
2 files changed, 32 insertions(+), 21 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index 626019a..558bddf 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -634,20 +634,32 @@ static void render_ring_cleanup(struct intel_ring_buffer *ring)
ring->scratch.obj = NULL;
}
-static void
-update_mboxes(struct intel_ring_buffer *ring,
- u32 mmio_offset)
+static void gen6_signal(struct intel_ring_buffer *signaller)
{
+ struct drm_i915_private *dev_priv = signaller->dev->dev_private;
+ struct intel_ring_buffer *useless;
+ int i;
+
/* NB: In order to be able to do semaphore MBOX updates for varying number
* of rings, it's easiest if we round up each individual update to a
* multiple of 2 (since ring updates must always be a multiple of 2)
* even though the actual update only requires 3 dwords.
*/
#define MBOX_UPDATE_DWORDS 4
- intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1));
- intel_ring_emit(ring, mmio_offset);
- intel_ring_emit(ring, ring->outstanding_lazy_seqno);
- intel_ring_emit(ring, MI_NOOP);
+ for_each_ring(useless, dev_priv, i) {
+ u32 mbox_reg = signaller->semaphore.mbox.signal[i];
+ if (mbox_reg != GEN6_NOSYNC) {
+ intel_ring_emit(signaller, MI_LOAD_REGISTER_IMM(1));
+ intel_ring_emit(signaller, mbox_reg);
+ intel_ring_emit(signaller, signaller->outstanding_lazy_seqno);
+ intel_ring_emit(signaller, MI_NOOP);
+ } else {
+ intel_ring_emit(signaller, MI_NOOP);
+ intel_ring_emit(signaller, MI_NOOP);
+ intel_ring_emit(signaller, MI_NOOP);
+ intel_ring_emit(signaller, MI_NOOP);
+ }
+ }
}
/**
@@ -663,9 +675,7 @@ static int
gen6_add_request(struct intel_ring_buffer *ring)
{
struct drm_device *dev = ring->dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_ring_buffer *useless;
- int i, ret, num_dwords = 4;
+ int ret, num_dwords = 4;
if (i915_semaphore_is_enabled(dev))
num_dwords += ((I915_NUM_RINGS-1) * MBOX_UPDATE_DWORDS);
@@ -675,13 +685,7 @@ gen6_add_request(struct intel_ring_buffer *ring)
if (ret)
return ret;
- if (i915_semaphore_is_enabled(dev)) {
- for_each_ring(useless, dev_priv, i) {
- u32 mbox_reg = ring->semaphore.mbox.signal[i];
- if (mbox_reg != GEN6_NOSYNC)
- update_mboxes(ring, mbox_reg);
- }
- }
+ ring->semaphore.signal(ring);
intel_ring_emit(ring, MI_STORE_DWORD_INDEX);
intel_ring_emit(ring, I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
@@ -1881,6 +1885,7 @@ int intel_init_render_ring_buffer(struct drm_device *dev)
ring->get_seqno = gen6_ring_get_seqno;
ring->set_seqno = ring_set_seqno;
ring->semaphore.sync_to = gen6_ring_sync;
+ ring->semaphore.signal = gen6_signal;
ring->semaphore.mbox.wait[RCS] = MI_SEMAPHORE_SYNC_INVALID;
ring->semaphore.mbox.wait[VCS] = MI_SEMAPHORE_SYNC_RV;
ring->semaphore.mbox.wait[BCS] = MI_SEMAPHORE_SYNC_RB;
@@ -2057,6 +2062,7 @@ int intel_init_bsd_ring_buffer(struct drm_device *dev)
gen6_ring_dispatch_execbuffer;
}
ring->semaphore.sync_to = gen6_ring_sync;
+ ring->semaphore.signal = gen6_signal;
ring->semaphore.mbox.wait[RCS] = MI_SEMAPHORE_SYNC_VR;
ring->semaphore.mbox.wait[VCS] = MI_SEMAPHORE_SYNC_INVALID;
ring->semaphore.mbox.wait[BCS] = MI_SEMAPHORE_SYNC_VB;
@@ -2114,6 +2120,7 @@ int intel_init_blt_ring_buffer(struct drm_device *dev)
ring->dispatch_execbuffer = gen6_ring_dispatch_execbuffer;
}
ring->semaphore.sync_to = gen6_ring_sync;
+ ring->semaphore.signal = gen6_signal;
ring->semaphore.mbox.wait[RCS] = MI_SEMAPHORE_SYNC_BR;
ring->semaphore.mbox.wait[VCS] = MI_SEMAPHORE_SYNC_BV;
ring->semaphore.mbox.wait[BCS] = MI_SEMAPHORE_SYNC_INVALID;
@@ -2155,6 +2162,7 @@ int intel_init_vebox_ring_buffer(struct drm_device *dev)
ring->dispatch_execbuffer = gen6_ring_dispatch_execbuffer;
}
ring->semaphore.sync_to = gen6_ring_sync;
+ ring->semaphore.signal = gen6_signal;
ring->semaphore.mbox.wait[RCS] = MI_SEMAPHORE_SYNC_VER;
ring->semaphore.mbox.wait[VCS] = MI_SEMAPHORE_SYNC_VEV;
ring->semaphore.mbox.wait[BCS] = MI_SEMAPHORE_SYNC_VEB;
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
index 8e03c4c..d270323 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -115,16 +115,19 @@ struct intel_ring_buffer {
struct {
u32 sync_seqno[I915_NUM_RINGS-1];
- /* AKA wait() */
- int (*sync_to)(struct intel_ring_buffer *ring,
- struct intel_ring_buffer *to,
- u32 seqno);
+
struct {
/* our mbox written by others */
u32 wait[I915_NUM_RINGS];
/* mboxes this ring signals to */
u32 signal[I915_NUM_RINGS];
} mbox;
+
+ /* AKA wait() */
+ int (*sync_to)(struct intel_ring_buffer *ring,
+ struct intel_ring_buffer *to,
+ u32 seqno);
+ void (*signal)(struct intel_ring_buffer *signaller);
} semaphore;
/**
--
1.9.0
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 03/13] drm/i915: Move ring_begin to signal()
2014-02-20 6:19 [PATCH 01/13] drm/i915: Move semaphore specific ring members to struct Ben Widawsky
2014-02-20 6:19 ` [PATCH 02/13] drm/i915: Virtualize the ringbuffer signal func Ben Widawsky
@ 2014-02-20 6:19 ` Ben Widawsky
2014-02-20 6:19 ` [PATCH 04/13] drm/i915: Make semaphore updates more precise Ben Widawsky
` (10 subsequent siblings)
12 siblings, 0 replies; 23+ messages in thread
From: Ben Widawsky @ 2014-02-20 6:19 UTC (permalink / raw)
To: Intel GFX; +Cc: Ben Widawsky, Ben Widawsky
Add_request has always contained both the semaphore mailbox updates as
well as the breadcrumb writes. Since the semaphore signal is the one
which actually knows about the number of dwords it needs to emit to the
ring, we move the ring_begin to that function. This allows us to remove
the hideously shared #define
On a related not, gen8 will use a different number of dwords for
semaphores, but not for add request.
v2: Make number of dwords an explicit part of signalling (via function
argument). (Chris)
v3: very slight comment change
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Ben Widawsky <ben@bwidawsk.net>
---
drivers/gpu/drm/i915/intel_ringbuffer.c | 39 +++++++++++++++++++--------------
drivers/gpu/drm/i915/intel_ringbuffer.h | 4 +++-
2 files changed, 25 insertions(+), 18 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index 558bddf..06d849a 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -634,18 +634,28 @@ static void render_ring_cleanup(struct intel_ring_buffer *ring)
ring->scratch.obj = NULL;
}
-static void gen6_signal(struct intel_ring_buffer *signaller)
+static int gen6_signal(struct intel_ring_buffer *signaller,
+ unsigned int num_dwords)
{
- struct drm_i915_private *dev_priv = signaller->dev->dev_private;
+ struct drm_device *dev = signaller->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_ring_buffer *useless;
- int i;
+ int i, ret;
-/* NB: In order to be able to do semaphore MBOX updates for varying number
- * of rings, it's easiest if we round up each individual update to a
- * multiple of 2 (since ring updates must always be a multiple of 2)
- * even though the actual update only requires 3 dwords.
- */
+ /* NB: In order to be able to do semaphore MBOX updates for varying
+ * number of rings, it's easiest if we round up each individual update
+ * to a multiple of 2 (since ring updates must always be a multiple of
+ * 2) even though the actual update only requires 3 dwords.
+ */
#define MBOX_UPDATE_DWORDS 4
+ if (i915_semaphore_is_enabled(dev))
+ num_dwords += ((I915_NUM_RINGS-1) * MBOX_UPDATE_DWORDS);
+
+ ret = intel_ring_begin(signaller, num_dwords);
+ if (ret)
+ return ret;
+#undef MBOX_UPDATE_DWORDS
+
for_each_ring(useless, dev_priv, i) {
u32 mbox_reg = signaller->semaphore.mbox.signal[i];
if (mbox_reg != GEN6_NOSYNC) {
@@ -660,6 +670,8 @@ static void gen6_signal(struct intel_ring_buffer *signaller)
intel_ring_emit(signaller, MI_NOOP);
}
}
+
+ return 0;
}
/**
@@ -674,19 +686,12 @@ static void gen6_signal(struct intel_ring_buffer *signaller)
static int
gen6_add_request(struct intel_ring_buffer *ring)
{
- struct drm_device *dev = ring->dev;
- int ret, num_dwords = 4;
-
- if (i915_semaphore_is_enabled(dev))
- num_dwords += ((I915_NUM_RINGS-1) * MBOX_UPDATE_DWORDS);
-#undef MBOX_UPDATE_DWORDS
+ int ret;
- ret = intel_ring_begin(ring, num_dwords);
+ ret = ring->semaphore.signal(ring, 4);
if (ret)
return ret;
- ring->semaphore.signal(ring);
-
intel_ring_emit(ring, MI_STORE_DWORD_INDEX);
intel_ring_emit(ring, I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
intel_ring_emit(ring, ring->outstanding_lazy_seqno);
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
index d270323..36b4462 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -127,7 +127,9 @@ struct intel_ring_buffer {
int (*sync_to)(struct intel_ring_buffer *ring,
struct intel_ring_buffer *to,
u32 seqno);
- void (*signal)(struct intel_ring_buffer *signaller);
+ int (*signal)(struct intel_ring_buffer *signaller,
+ /* num_dwords needed by caller */
+ unsigned int num_dwords);
} semaphore;
/**
--
1.9.0
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 04/13] drm/i915: Make semaphore updates more precise
2014-02-20 6:19 [PATCH 01/13] drm/i915: Move semaphore specific ring members to struct Ben Widawsky
2014-02-20 6:19 ` [PATCH 02/13] drm/i915: Virtualize the ringbuffer signal func Ben Widawsky
2014-02-20 6:19 ` [PATCH 03/13] drm/i915: Move ring_begin to signal() Ben Widawsky
@ 2014-02-20 6:19 ` Ben Widawsky
2014-02-24 13:09 ` Ville Syrjälä
2014-02-20 6:19 ` [PATCH 05/13] drm/i915: gen specific ring init Ben Widawsky
` (9 subsequent siblings)
12 siblings, 1 reply; 23+ messages in thread
From: Ben Widawsky @ 2014-02-20 6:19 UTC (permalink / raw)
To: Intel GFX; +Cc: Ben Widawsky, Ben Widawsky
With the ring mask we now have an easy way to know the number of rings
in the system, and therefore can accurately predict the number of dwords
to emit for semaphore signalling. This was not possible (easily)
previously.
There should be no functional impact, simply fewer instructions emitted.
While we're here, simply do the round up to 2 instead of the fancier
rounding we did before, which rounding up per mbox, ie 4. This also
allows us to drop the unnecessary MI_NOOP, so not really 4, 3.
v2: Use 3 dwords instead of 4 (Ville)
Do the proper calculation to get the number of dwords to emit (Ville)
Conditionally set .sync_to when semaphores are enabled (Ville)
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Ben Widawsky <ben@bwidawsk.net>
---
drivers/gpu/drm/i915/intel_ringbuffer.c | 119 +++++++++++++++++---------------
1 file changed, 62 insertions(+), 57 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index 06d849a..bf061dd 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -637,24 +637,19 @@ static void render_ring_cleanup(struct intel_ring_buffer *ring)
static int gen6_signal(struct intel_ring_buffer *signaller,
unsigned int num_dwords)
{
+#define MBOX_UPDATE_DWORDS 3
struct drm_device *dev = signaller->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_ring_buffer *useless;
- int i, ret;
+ int i, ret, num_rings;
- /* NB: In order to be able to do semaphore MBOX updates for varying
- * number of rings, it's easiest if we round up each individual update
- * to a multiple of 2 (since ring updates must always be a multiple of
- * 2) even though the actual update only requires 3 dwords.
- */
-#define MBOX_UPDATE_DWORDS 4
- if (i915_semaphore_is_enabled(dev))
- num_dwords += ((I915_NUM_RINGS-1) * MBOX_UPDATE_DWORDS);
+ num_rings = hweight_long(INTEL_INFO(dev)->ring_mask);
+ num_dwords += round_up((num_rings-1) * MBOX_UPDATE_DWORDS, 2);
+#undef MBOX_UPDATE_DWORDS
ret = intel_ring_begin(signaller, num_dwords);
if (ret)
return ret;
-#undef MBOX_UPDATE_DWORDS
for_each_ring(useless, dev_priv, i) {
u32 mbox_reg = signaller->semaphore.mbox.signal[i];
@@ -662,15 +657,13 @@ static int gen6_signal(struct intel_ring_buffer *signaller,
intel_ring_emit(signaller, MI_LOAD_REGISTER_IMM(1));
intel_ring_emit(signaller, mbox_reg);
intel_ring_emit(signaller, signaller->outstanding_lazy_seqno);
- intel_ring_emit(signaller, MI_NOOP);
- } else {
- intel_ring_emit(signaller, MI_NOOP);
- intel_ring_emit(signaller, MI_NOOP);
- intel_ring_emit(signaller, MI_NOOP);
- intel_ring_emit(signaller, MI_NOOP);
}
}
+ /* If num_dwords was rounded, make sure the tail pointer is correct */
+ if (num_rings % 2 == 0)
+ intel_ring_emit(signaller, MI_NOOP);
+
return 0;
}
@@ -688,7 +681,11 @@ gen6_add_request(struct intel_ring_buffer *ring)
{
int ret;
- ret = ring->semaphore.signal(ring, 4);
+ if (ring->semaphore.signal)
+ ret = ring->semaphore.signal(ring, 4);
+ else
+ ret = intel_ring_begin(ring, 4);
+
if (ret)
return ret;
@@ -1889,16 +1886,18 @@ int intel_init_render_ring_buffer(struct drm_device *dev)
ring->irq_enable_mask = GT_RENDER_USER_INTERRUPT;
ring->get_seqno = gen6_ring_get_seqno;
ring->set_seqno = ring_set_seqno;
- ring->semaphore.sync_to = gen6_ring_sync;
- ring->semaphore.signal = gen6_signal;
- ring->semaphore.mbox.wait[RCS] = MI_SEMAPHORE_SYNC_INVALID;
- ring->semaphore.mbox.wait[VCS] = MI_SEMAPHORE_SYNC_RV;
- ring->semaphore.mbox.wait[BCS] = MI_SEMAPHORE_SYNC_RB;
- ring->semaphore.mbox.wait[VECS] = MI_SEMAPHORE_SYNC_RVE;
- ring->semaphore.mbox.signal[RCS] = GEN6_NOSYNC;
- ring->semaphore.mbox.signal[VCS] = GEN6_VRSYNC;
- ring->semaphore.mbox.signal[BCS] = GEN6_BRSYNC;
- ring->semaphore.mbox.signal[VECS] = GEN6_VERSYNC;
+ if (i915_semaphore_is_enabled(dev)) {
+ ring->semaphore.sync_to = gen6_ring_sync;
+ ring->semaphore.signal = gen6_signal;
+ ring->semaphore.mbox.wait[RCS] = MI_SEMAPHORE_SYNC_INVALID;
+ ring->semaphore.mbox.wait[VCS] = MI_SEMAPHORE_SYNC_RV;
+ ring->semaphore.mbox.wait[BCS] = MI_SEMAPHORE_SYNC_RB;
+ ring->semaphore.mbox.wait[VECS] = MI_SEMAPHORE_SYNC_RVE;
+ ring->semaphore.mbox.signal[RCS] = GEN6_NOSYNC;
+ ring->semaphore.mbox.signal[VCS] = GEN6_VRSYNC;
+ ring->semaphore.mbox.signal[BCS] = GEN6_BRSYNC;
+ ring->semaphore.mbox.signal[VECS] = GEN6_VERSYNC;
+ }
} else if (IS_GEN5(dev)) {
ring->add_request = pc_render_add_request;
ring->flush = gen4_render_ring_flush;
@@ -2066,16 +2065,18 @@ int intel_init_bsd_ring_buffer(struct drm_device *dev)
ring->dispatch_execbuffer =
gen6_ring_dispatch_execbuffer;
}
- ring->semaphore.sync_to = gen6_ring_sync;
- ring->semaphore.signal = gen6_signal;
- ring->semaphore.mbox.wait[RCS] = MI_SEMAPHORE_SYNC_VR;
- ring->semaphore.mbox.wait[VCS] = MI_SEMAPHORE_SYNC_INVALID;
- ring->semaphore.mbox.wait[BCS] = MI_SEMAPHORE_SYNC_VB;
- ring->semaphore.mbox.wait[VECS] = MI_SEMAPHORE_SYNC_VVE;
- ring->semaphore.mbox.signal[RCS] = GEN6_RVSYNC;
- ring->semaphore.mbox.signal[VCS] = GEN6_NOSYNC;
- ring->semaphore.mbox.signal[BCS] = GEN6_BVSYNC;
- ring->semaphore.mbox.signal[VECS] = GEN6_VEVSYNC;
+ if (i915_semaphore_is_enabled(dev)) {
+ ring->semaphore.sync_to = gen6_ring_sync;
+ ring->semaphore.signal = gen6_signal;
+ ring->semaphore.mbox.wait[RCS] = MI_SEMAPHORE_SYNC_VR;
+ ring->semaphore.mbox.wait[VCS] = MI_SEMAPHORE_SYNC_INVALID;
+ ring->semaphore.mbox.wait[BCS] = MI_SEMAPHORE_SYNC_VB;
+ ring->semaphore.mbox.wait[VECS] = MI_SEMAPHORE_SYNC_VVE;
+ ring->semaphore.mbox.signal[RCS] = GEN6_RVSYNC;
+ ring->semaphore.mbox.signal[VCS] = GEN6_NOSYNC;
+ ring->semaphore.mbox.signal[BCS] = GEN6_BVSYNC;
+ ring->semaphore.mbox.signal[VECS] = GEN6_VEVSYNC;
+ }
} else {
ring->mmio_base = BSD_RING_BASE;
ring->flush = bsd_ring_flush;
@@ -2124,16 +2125,18 @@ int intel_init_blt_ring_buffer(struct drm_device *dev)
ring->irq_put = gen6_ring_put_irq;
ring->dispatch_execbuffer = gen6_ring_dispatch_execbuffer;
}
- ring->semaphore.sync_to = gen6_ring_sync;
- ring->semaphore.signal = gen6_signal;
- ring->semaphore.mbox.wait[RCS] = MI_SEMAPHORE_SYNC_BR;
- ring->semaphore.mbox.wait[VCS] = MI_SEMAPHORE_SYNC_BV;
- ring->semaphore.mbox.wait[BCS] = MI_SEMAPHORE_SYNC_INVALID;
- ring->semaphore.mbox.wait[VECS] = MI_SEMAPHORE_SYNC_BVE;
- ring->semaphore.mbox.signal[RCS] = GEN6_RBSYNC;
- ring->semaphore.mbox.signal[VCS] = GEN6_VBSYNC;
- ring->semaphore.mbox.signal[BCS] = GEN6_NOSYNC;
- ring->semaphore.mbox.signal[VECS] = GEN6_VEBSYNC;
+ if (i915_semaphore_is_enabled(dev)) {
+ ring->semaphore.signal = gen6_signal;
+ ring->semaphore.sync_to = gen6_ring_sync;
+ ring->semaphore.mbox.wait[RCS] = MI_SEMAPHORE_SYNC_BR;
+ ring->semaphore.mbox.wait[VCS] = MI_SEMAPHORE_SYNC_BV;
+ ring->semaphore.mbox.wait[BCS] = MI_SEMAPHORE_SYNC_INVALID;
+ ring->semaphore.mbox.wait[VECS] = MI_SEMAPHORE_SYNC_BVE;
+ ring->semaphore.mbox.signal[RCS] = GEN6_RBSYNC;
+ ring->semaphore.mbox.signal[VCS] = GEN6_VBSYNC;
+ ring->semaphore.mbox.signal[BCS] = GEN6_NOSYNC;
+ ring->semaphore.mbox.signal[VECS] = GEN6_VEBSYNC;
+ }
ring->init = init_ring_common;
return intel_init_ring_buffer(dev, ring);
@@ -2166,16 +2169,18 @@ int intel_init_vebox_ring_buffer(struct drm_device *dev)
ring->irq_put = hsw_vebox_put_irq;
ring->dispatch_execbuffer = gen6_ring_dispatch_execbuffer;
}
- ring->semaphore.sync_to = gen6_ring_sync;
- ring->semaphore.signal = gen6_signal;
- ring->semaphore.mbox.wait[RCS] = MI_SEMAPHORE_SYNC_VER;
- ring->semaphore.mbox.wait[VCS] = MI_SEMAPHORE_SYNC_VEV;
- ring->semaphore.mbox.wait[BCS] = MI_SEMAPHORE_SYNC_VEB;
- ring->semaphore.mbox.wait[VECS] = MI_SEMAPHORE_SYNC_INVALID;
- ring->semaphore.mbox.signal[RCS] = GEN6_RVESYNC;
- ring->semaphore.mbox.signal[VCS] = GEN6_VVESYNC;
- ring->semaphore.mbox.signal[BCS] = GEN6_BVESYNC;
- ring->semaphore.mbox.signal[VECS] = GEN6_NOSYNC;
+ if (i915_semaphore_is_enabled(dev)) {
+ ring->semaphore.sync_to = gen6_ring_sync;
+ ring->semaphore.signal = gen6_signal;
+ ring->semaphore.mbox.wait[RCS] = MI_SEMAPHORE_SYNC_VER;
+ ring->semaphore.mbox.wait[VCS] = MI_SEMAPHORE_SYNC_VEV;
+ ring->semaphore.mbox.wait[BCS] = MI_SEMAPHORE_SYNC_VEB;
+ ring->semaphore.mbox.wait[VECS] = MI_SEMAPHORE_SYNC_INVALID;
+ ring->semaphore.mbox.signal[RCS] = GEN6_RVESYNC;
+ ring->semaphore.mbox.signal[VCS] = GEN6_VVESYNC;
+ ring->semaphore.mbox.signal[BCS] = GEN6_BVESYNC;
+ ring->semaphore.mbox.signal[VECS] = GEN6_NOSYNC;
+ }
ring->init = init_ring_common;
return intel_init_ring_buffer(dev, ring);
--
1.9.0
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 05/13] drm/i915: gen specific ring init
2014-02-20 6:19 [PATCH 01/13] drm/i915: Move semaphore specific ring members to struct Ben Widawsky
` (2 preceding siblings ...)
2014-02-20 6:19 ` [PATCH 04/13] drm/i915: Make semaphore updates more precise Ben Widawsky
@ 2014-02-20 6:19 ` Ben Widawsky
2014-02-24 13:05 ` Ville Syrjälä
2014-02-20 6:19 ` [PATCH 06/13] drm/i915/bdw: implement semaphore signal Ben Widawsky
` (8 subsequent siblings)
12 siblings, 1 reply; 23+ messages in thread
From: Ben Widawsky @ 2014-02-20 6:19 UTC (permalink / raw)
To: Intel GFX; +Cc: Ben Widawsky, Ben Widawsky
Gen8 has already had some differentiation with how it handles rings.
Semaphores bring yet more differences, and now is as good a time as any
to do the split.
Also, since gen8 doesn't actually use semaphores up until this point,
put the proper "NULL" values in for the mbox info.
v2: v1 had a stale commit message
v3: Move everything in the is_semaphore_enabled() check
Signed-off-by: Ben Widawsky <ben@bwidawsk.net>
---
drivers/gpu/drm/i915/intel_ringbuffer.c | 142 ++++++++++++++++++++++----------
1 file changed, 97 insertions(+), 45 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index bf061dd..691da67 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -1870,19 +1870,34 @@ int intel_init_render_ring_buffer(struct drm_device *dev)
ring->id = RCS;
ring->mmio_base = RENDER_RING_BASE;
- if (INTEL_INFO(dev)->gen >= 6) {
+ if (INTEL_INFO(dev)->gen >= 8) {
+ ring->add_request = gen6_add_request;
+ ring->flush = gen8_render_ring_flush;
+ ring->irq_get = gen8_ring_get_irq;
+ ring->irq_put = gen8_ring_put_irq;
+ ring->irq_enable_mask = GT_RENDER_USER_INTERRUPT;
+ ring->get_seqno = gen6_ring_get_seqno;
+ ring->set_seqno = ring_set_seqno;
+ if (i915_semaphore_is_enabled(dev)) {
+ ring->semaphore.sync_to = gen6_ring_sync;
+ ring->semaphore.signal = gen6_signal;
+ ring->semaphore.signal = gen6_signal;
+ ring->semaphore.mbox.wait[RCS] = MI_SEMAPHORE_SYNC_INVALID;
+ ring->semaphore.mbox.wait[VCS] = MI_SEMAPHORE_SYNC_INVALID;
+ ring->semaphore.mbox.wait[BCS] = MI_SEMAPHORE_SYNC_INVALID;
+ ring->semaphore.mbox.wait[VECS] = MI_SEMAPHORE_SYNC_INVALID;
+ ring->semaphore.mbox.signal[RCS] = GEN6_NOSYNC;
+ ring->semaphore.mbox.signal[VCS] = GEN6_NOSYNC;
+ ring->semaphore.mbox.signal[BCS] = GEN6_NOSYNC;
+ ring->semaphore.mbox.signal[VECS] = GEN6_NOSYNC;
+ }
+ } else if (INTEL_INFO(dev)->gen >= 6) {
ring->add_request = gen6_add_request;
ring->flush = gen7_render_ring_flush;
if (INTEL_INFO(dev)->gen == 6)
ring->flush = gen6_render_ring_flush;
- if (INTEL_INFO(dev)->gen >= 8) {
- ring->flush = gen8_render_ring_flush;
- ring->irq_get = gen8_ring_get_irq;
- ring->irq_put = gen8_ring_put_irq;
- } else {
- ring->irq_get = gen6_ring_get_irq;
- ring->irq_put = gen6_ring_put_irq;
- }
+ ring->irq_get = gen6_ring_get_irq;
+ ring->irq_put = gen6_ring_put_irq;
ring->irq_enable_mask = GT_RENDER_USER_INTERRUPT;
ring->get_seqno = gen6_ring_get_seqno;
ring->set_seqno = ring_set_seqno;
@@ -1925,6 +1940,7 @@ int intel_init_render_ring_buffer(struct drm_device *dev)
ring->irq_enable_mask = I915_USER_INTERRUPT;
}
ring->write_tail = ring_write_tail;
+
if (IS_HASWELL(dev))
ring->dispatch_execbuffer = hsw_ring_dispatch_execbuffer;
else if (IS_GEN8(dev))
@@ -2058,24 +2074,36 @@ int intel_init_bsd_ring_buffer(struct drm_device *dev)
ring->irq_put = gen8_ring_put_irq;
ring->dispatch_execbuffer =
gen8_ring_dispatch_execbuffer;
+ if (i915_semaphore_is_enabled(dev)) {
+ ring->semaphore.sync_to = gen6_ring_sync;
+ ring->semaphore.signal = gen6_signal;
+ ring->semaphore.mbox.wait[RCS] = MI_SEMAPHORE_SYNC_INVALID;
+ ring->semaphore.mbox.wait[VCS] = MI_SEMAPHORE_SYNC_INVALID;
+ ring->semaphore.mbox.wait[BCS] = MI_SEMAPHORE_SYNC_INVALID;
+ ring->semaphore.mbox.wait[VECS] = MI_SEMAPHORE_SYNC_INVALID;
+ ring->semaphore.mbox.signal[RCS] = GEN6_NOSYNC;
+ ring->semaphore.mbox.signal[VCS] = GEN6_NOSYNC;
+ ring->semaphore.mbox.signal[BCS] = GEN6_NOSYNC;
+ ring->semaphore.mbox.signal[VECS] = GEN6_NOSYNC;
+ }
} else {
ring->irq_enable_mask = GT_BSD_USER_INTERRUPT;
ring->irq_get = gen6_ring_get_irq;
ring->irq_put = gen6_ring_put_irq;
ring->dispatch_execbuffer =
gen6_ring_dispatch_execbuffer;
- }
- if (i915_semaphore_is_enabled(dev)) {
- ring->semaphore.sync_to = gen6_ring_sync;
- ring->semaphore.signal = gen6_signal;
- ring->semaphore.mbox.wait[RCS] = MI_SEMAPHORE_SYNC_VR;
- ring->semaphore.mbox.wait[VCS] = MI_SEMAPHORE_SYNC_INVALID;
- ring->semaphore.mbox.wait[BCS] = MI_SEMAPHORE_SYNC_VB;
- ring->semaphore.mbox.wait[VECS] = MI_SEMAPHORE_SYNC_VVE;
- ring->semaphore.mbox.signal[RCS] = GEN6_RVSYNC;
- ring->semaphore.mbox.signal[VCS] = GEN6_NOSYNC;
- ring->semaphore.mbox.signal[BCS] = GEN6_BVSYNC;
- ring->semaphore.mbox.signal[VECS] = GEN6_VEVSYNC;
+ if (i915_semaphore_is_enabled(dev)) {
+ ring->semaphore.sync_to = gen6_ring_sync;
+ ring->semaphore.signal = gen6_signal;
+ ring->semaphore.mbox.wait[RCS] = MI_SEMAPHORE_SYNC_VR;
+ ring->semaphore.mbox.wait[VCS] = MI_SEMAPHORE_SYNC_INVALID;
+ ring->semaphore.mbox.wait[BCS] = MI_SEMAPHORE_SYNC_VB;
+ ring->semaphore.mbox.wait[VECS] = MI_SEMAPHORE_SYNC_VVE;
+ ring->semaphore.mbox.signal[RCS] = GEN6_RVSYNC;
+ ring->semaphore.mbox.signal[VCS] = GEN6_NOSYNC;
+ ring->semaphore.mbox.signal[BCS] = GEN6_BVSYNC;
+ ring->semaphore.mbox.signal[VECS] = GEN6_VEVSYNC;
+ }
}
} else {
ring->mmio_base = BSD_RING_BASE;
@@ -2119,23 +2147,35 @@ int intel_init_blt_ring_buffer(struct drm_device *dev)
ring->irq_get = gen8_ring_get_irq;
ring->irq_put = gen8_ring_put_irq;
ring->dispatch_execbuffer = gen8_ring_dispatch_execbuffer;
+ if (i915_semaphore_is_enabled(dev)) {
+ ring->semaphore.sync_to = gen6_ring_sync;
+ ring->semaphore.signal = gen6_signal;
+ ring->semaphore.mbox.wait[RCS] = MI_SEMAPHORE_SYNC_INVALID;
+ ring->semaphore.mbox.wait[VCS] = MI_SEMAPHORE_SYNC_INVALID;
+ ring->semaphore.mbox.wait[BCS] = MI_SEMAPHORE_SYNC_INVALID;
+ ring->semaphore.mbox.wait[VECS] = MI_SEMAPHORE_SYNC_INVALID;
+ ring->semaphore.mbox.signal[RCS] = GEN6_NOSYNC;
+ ring->semaphore.mbox.signal[VCS] = GEN6_NOSYNC;
+ ring->semaphore.mbox.signal[BCS] = GEN6_NOSYNC;
+ ring->semaphore.mbox.signal[VECS] = GEN6_NOSYNC;
+ }
} else {
ring->irq_enable_mask = GT_BLT_USER_INTERRUPT;
ring->irq_get = gen6_ring_get_irq;
ring->irq_put = gen6_ring_put_irq;
ring->dispatch_execbuffer = gen6_ring_dispatch_execbuffer;
- }
- if (i915_semaphore_is_enabled(dev)) {
- ring->semaphore.signal = gen6_signal;
- ring->semaphore.sync_to = gen6_ring_sync;
- ring->semaphore.mbox.wait[RCS] = MI_SEMAPHORE_SYNC_BR;
- ring->semaphore.mbox.wait[VCS] = MI_SEMAPHORE_SYNC_BV;
- ring->semaphore.mbox.wait[BCS] = MI_SEMAPHORE_SYNC_INVALID;
- ring->semaphore.mbox.wait[VECS] = MI_SEMAPHORE_SYNC_BVE;
- ring->semaphore.mbox.signal[RCS] = GEN6_RBSYNC;
- ring->semaphore.mbox.signal[VCS] = GEN6_VBSYNC;
- ring->semaphore.mbox.signal[BCS] = GEN6_NOSYNC;
- ring->semaphore.mbox.signal[VECS] = GEN6_VEBSYNC;
+ if (i915_semaphore_is_enabled(dev)) {
+ ring->semaphore.signal = gen6_signal;
+ ring->semaphore.sync_to = gen6_ring_sync;
+ ring->semaphore.mbox.wait[RCS] = MI_SEMAPHORE_SYNC_BR;
+ ring->semaphore.mbox.wait[VCS] = MI_SEMAPHORE_SYNC_BV;
+ ring->semaphore.mbox.wait[BCS] = MI_SEMAPHORE_SYNC_INVALID;
+ ring->semaphore.mbox.wait[VECS] = MI_SEMAPHORE_SYNC_BVE;
+ ring->semaphore.mbox.signal[RCS] = GEN6_RBSYNC;
+ ring->semaphore.mbox.signal[VCS] = GEN6_VBSYNC;
+ ring->semaphore.mbox.signal[BCS] = GEN6_NOSYNC;
+ ring->semaphore.mbox.signal[VECS] = GEN6_VEBSYNC;
+ }
}
ring->init = init_ring_common;
@@ -2163,23 +2203,35 @@ int intel_init_vebox_ring_buffer(struct drm_device *dev)
ring->irq_get = gen8_ring_get_irq;
ring->irq_put = gen8_ring_put_irq;
ring->dispatch_execbuffer = gen8_ring_dispatch_execbuffer;
+ if (i915_semaphore_is_enabled(dev)) {
+ ring->semaphore.sync_to = gen6_ring_sync;
+ ring->semaphore.signal = gen6_signal;
+ ring->semaphore.mbox.wait[RCS] = MI_SEMAPHORE_SYNC_INVALID;
+ ring->semaphore.mbox.wait[VCS] = MI_SEMAPHORE_SYNC_INVALID;
+ ring->semaphore.mbox.wait[BCS] = MI_SEMAPHORE_SYNC_INVALID;
+ ring->semaphore.mbox.wait[VECS] = MI_SEMAPHORE_SYNC_INVALID;
+ ring->semaphore.mbox.signal[RCS] = GEN6_NOSYNC;
+ ring->semaphore.mbox.signal[VCS] = GEN6_NOSYNC;
+ ring->semaphore.mbox.signal[BCS] = GEN6_NOSYNC;
+ ring->semaphore.mbox.signal[VECS] = GEN6_NOSYNC;
+ }
} else {
ring->irq_enable_mask = PM_VEBOX_USER_INTERRUPT;
ring->irq_get = hsw_vebox_get_irq;
ring->irq_put = hsw_vebox_put_irq;
ring->dispatch_execbuffer = gen6_ring_dispatch_execbuffer;
- }
- if (i915_semaphore_is_enabled(dev)) {
- ring->semaphore.sync_to = gen6_ring_sync;
- ring->semaphore.signal = gen6_signal;
- ring->semaphore.mbox.wait[RCS] = MI_SEMAPHORE_SYNC_VER;
- ring->semaphore.mbox.wait[VCS] = MI_SEMAPHORE_SYNC_VEV;
- ring->semaphore.mbox.wait[BCS] = MI_SEMAPHORE_SYNC_VEB;
- ring->semaphore.mbox.wait[VECS] = MI_SEMAPHORE_SYNC_INVALID;
- ring->semaphore.mbox.signal[RCS] = GEN6_RVESYNC;
- ring->semaphore.mbox.signal[VCS] = GEN6_VVESYNC;
- ring->semaphore.mbox.signal[BCS] = GEN6_BVESYNC;
- ring->semaphore.mbox.signal[VECS] = GEN6_NOSYNC;
+ if (i915_semaphore_is_enabled(dev)) {
+ ring->semaphore.sync_to = gen6_ring_sync;
+ ring->semaphore.signal = gen6_signal;
+ ring->semaphore.mbox.wait[RCS] = MI_SEMAPHORE_SYNC_VER;
+ ring->semaphore.mbox.wait[VCS] = MI_SEMAPHORE_SYNC_VEV;
+ ring->semaphore.mbox.wait[BCS] = MI_SEMAPHORE_SYNC_VEB;
+ ring->semaphore.mbox.wait[VECS] = MI_SEMAPHORE_SYNC_INVALID;
+ ring->semaphore.mbox.signal[RCS] = GEN6_RVESYNC;
+ ring->semaphore.mbox.signal[VCS] = GEN6_VVESYNC;
+ ring->semaphore.mbox.signal[BCS] = GEN6_BVESYNC;
+ ring->semaphore.mbox.signal[VECS] = GEN6_NOSYNC;
+ }
}
ring->init = init_ring_common;
--
1.9.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 06/13] drm/i915/bdw: implement semaphore signal
2014-02-20 6:19 [PATCH 01/13] drm/i915: Move semaphore specific ring members to struct Ben Widawsky
` (3 preceding siblings ...)
2014-02-20 6:19 ` [PATCH 05/13] drm/i915: gen specific ring init Ben Widawsky
@ 2014-02-20 6:19 ` Ben Widawsky
2014-02-24 13:10 ` Ville Syrjälä
2014-02-20 6:19 ` [PATCH 07/13] drm/i915/bdw: implement semaphore wait Ben Widawsky
` (7 subsequent siblings)
12 siblings, 1 reply; 23+ messages in thread
From: Ben Widawsky @ 2014-02-20 6:19 UTC (permalink / raw)
To: Intel GFX; +Cc: Ben Widawsky, Ben Widawsky
Semaphore signalling works similarly to previous GENs with the exception
that the per ring mailboxes no longer exist. Instead you must define
your own space, somewhere in the GTT.
The comments in the code define the layout I've opted for, which should
be fairly future proof. Ie. I tried to define offsets in abstract terms
(NUM_RINGS, seqno size, etc).
NOTE: If one wanted to move this to the HWSP they could. I've decided
one 4k object would be easier to deal with, and provide potential wins
with cache locality, but that's all speculative.
v2: Update the macro to not need the other ring's ring->id (Chris)
Update the comment to use the correct formula (Chris)
v3: Move the macros the ringbuffer.h to prevent churn in next patch
(Ville)
v4: Fixed compilation rebase conflict
commit 1ec9e26ddab06459e89a890431b2de064c5d1056
Author: Daniel Vetter <daniel.vetter@ffwll.ch>
Date: Fri Feb 14 14:01:11 2014 +0100
drm/i915: Consolidate binding parameters into flags
Signed-off-by: Ben Widawsky <ben@bwidawsk.net>
---
drivers/gpu/drm/i915/i915_drv.h | 1 +
drivers/gpu/drm/i915/i915_reg.h | 5 +-
drivers/gpu/drm/i915/intel_ringbuffer.c | 153 +++++++++++++++++++++++---------
drivers/gpu/drm/i915/intel_ringbuffer.h | 73 +++++++++++++--
4 files changed, 185 insertions(+), 47 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 8c64831..028ce5a 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1419,6 +1419,7 @@ typedef struct drm_i915_private {
struct pci_dev *bridge_dev;
struct intel_ring_buffer ring[I915_NUM_RINGS];
+ struct drm_i915_gem_object *semaphore_obj;
uint32_t last_seqno, next_seqno;
drm_dma_handle_t *status_page_dmah;
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 2f564ce..4e36d03 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -215,7 +215,7 @@
#define MI_DISPLAY_FLIP_IVB_SPRITE_B (3 << 19)
#define MI_DISPLAY_FLIP_IVB_PLANE_C (4 << 19)
#define MI_DISPLAY_FLIP_IVB_SPRITE_C (5 << 19)
-#define MI_SEMAPHORE_MBOX MI_INSTR(0x16, 1) /* gen6+ */
+#define MI_SEMAPHORE_MBOX MI_INSTR(0x16, 1) /* gen6, gen7 */
#define MI_SEMAPHORE_GLOBAL_GTT (1<<22)
#define MI_SEMAPHORE_UPDATE (1<<21)
#define MI_SEMAPHORE_COMPARE (1<<20)
@@ -240,6 +240,8 @@
#define MI_RESTORE_EXT_STATE_EN (1<<2)
#define MI_FORCE_RESTORE (1<<1)
#define MI_RESTORE_INHIBIT (1<<0)
+#define MI_SEMAPHORE_SIGNAL MI_INSTR(0x1b, 0) /* GEN8+ */
+#define MI_SEMAPHORE_TARGET(engine) ((engine)<<15)
#define MI_STORE_DWORD_IMM MI_INSTR(0x20, 1)
#define MI_MEM_VIRTUAL (1 << 22) /* 965+ only */
#define MI_STORE_DWORD_INDEX MI_INSTR(0x21, 1)
@@ -328,6 +330,7 @@
#define PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE (1<<10) /* GM45+ only */
#define PIPE_CONTROL_INDIRECT_STATE_DISABLE (1<<9)
#define PIPE_CONTROL_NOTIFY (1<<8)
+#define PIPE_CONTROL_FLUSH_ENABLE (1<<7) /* gen7+ */
#define PIPE_CONTROL_VF_CACHE_INVALIDATE (1<<4)
#define PIPE_CONTROL_CONST_CACHE_INVALIDATE (1<<3)
#define PIPE_CONTROL_STATE_CACHE_INVALIDATE (1<<2)
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index 691da67..717976b 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -621,6 +621,13 @@ static int init_render_ring(struct intel_ring_buffer *ring)
static void render_ring_cleanup(struct intel_ring_buffer *ring)
{
struct drm_device *dev = ring->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+
+ if (dev_priv->semaphore_obj) {
+ i915_gem_object_ggtt_unpin(dev_priv->semaphore_obj);
+ drm_gem_object_unreference(&dev_priv->semaphore_obj->base);
+ dev_priv->semaphore_obj = NULL;
+ }
if (ring->scratch.obj == NULL)
return;
@@ -634,6 +641,85 @@ static void render_ring_cleanup(struct intel_ring_buffer *ring)
ring->scratch.obj = NULL;
}
+static int gen8_rcs_signal(struct intel_ring_buffer *signaller,
+ unsigned int num_dwords)
+{
+#define MBOX_UPDATE_DWORDS 8
+ struct drm_device *dev = signaller->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_ring_buffer *waiter;
+ int i, ret, num_rings;
+
+ num_rings = hweight_long(INTEL_INFO(dev)->ring_mask);
+ num_dwords += (num_rings-1) * MBOX_UPDATE_DWORDS;
+#undef MBOX_UPDATE_DWORDS
+
+ ret = intel_ring_begin(signaller, num_dwords);
+ if (ret)
+ return ret;
+
+ for_each_ring(waiter, dev_priv, i) {
+ u64 gtt_offset = signaller->semaphore.signal_ggtt[i];
+ if (gtt_offset == MI_SEMAPHORE_SYNC_INVALID)
+ continue;
+
+ intel_ring_emit(signaller, GFX_OP_PIPE_CONTROL(6));
+ intel_ring_emit(signaller, PIPE_CONTROL_GLOBAL_GTT_IVB |
+ PIPE_CONTROL_QW_WRITE |
+ PIPE_CONTROL_FLUSH_ENABLE);
+ intel_ring_emit(signaller, lower_32_bits(gtt_offset));
+ intel_ring_emit(signaller, upper_32_bits(gtt_offset));
+ intel_ring_emit(signaller, signaller->outstanding_lazy_seqno);
+ intel_ring_emit(signaller, 0);
+ intel_ring_emit(signaller, MI_SEMAPHORE_SIGNAL |
+ MI_SEMAPHORE_TARGET(waiter->id));
+ intel_ring_emit(signaller, 0);
+ }
+
+ WARN_ON(i != num_rings);
+
+ return 0;
+}
+
+static int gen8_xcs_signal(struct intel_ring_buffer *signaller,
+ unsigned int num_dwords)
+{
+#define MBOX_UPDATE_DWORDS 6
+ struct drm_device *dev = signaller->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_ring_buffer *waiter;
+ int i, ret, num_rings;
+
+ num_rings = hweight_long(INTEL_INFO(dev)->ring_mask);
+ num_dwords = (num_rings-1) * MBOX_UPDATE_DWORDS;
+#undef MBOX_UPDATE_DWORDS
+
+ /* XXX: + 4 for the caller */
+ ret = intel_ring_begin(signaller, num_dwords + 4);
+ if (ret)
+ return ret;
+
+ for_each_ring(waiter, dev_priv, i) {
+ u64 gtt_offset = signaller->semaphore.signal_ggtt[i];
+ if (gtt_offset == MI_SEMAPHORE_SYNC_INVALID)
+ continue;
+
+ intel_ring_emit(signaller, (MI_FLUSH_DW + 1) |
+ MI_FLUSH_DW_OP_STOREDW);
+ intel_ring_emit(signaller, lower_32_bits(gtt_offset) |
+ MI_FLUSH_DW_USE_GTT);
+ intel_ring_emit(signaller, upper_32_bits(gtt_offset));
+ intel_ring_emit(signaller, signaller->outstanding_lazy_seqno);
+ intel_ring_emit(signaller, MI_SEMAPHORE_SIGNAL |
+ MI_SEMAPHORE_TARGET(waiter->id));
+ intel_ring_emit(signaller, 0);
+ }
+
+ WARN_ON(i != num_rings);
+
+ return 0;
+}
+
static int gen6_signal(struct intel_ring_buffer *signaller,
unsigned int num_dwords)
{
@@ -1865,12 +1951,30 @@ int intel_init_render_ring_buffer(struct drm_device *dev)
{
drm_i915_private_t *dev_priv = dev->dev_private;
struct intel_ring_buffer *ring = &dev_priv->ring[RCS];
+ struct drm_i915_gem_object *obj;
+ int ret;
ring->name = "render ring";
ring->id = RCS;
ring->mmio_base = RENDER_RING_BASE;
if (INTEL_INFO(dev)->gen >= 8) {
+ if (i915_semaphore_is_enabled(dev)) {
+ obj = i915_gem_alloc_object(dev, 4096);
+ if (obj == NULL) {
+ DRM_ERROR("Failed to allocate semaphore bo. Disabling semaphores\n");
+ i915.semaphores = 0;
+ } else {
+ i915_gem_object_set_cache_level(obj, I915_CACHE_LLC);
+ ret = i915_gem_obj_ggtt_pin(obj, 0, PIN_NONBLOCK);
+ if (ret != 0) {
+ drm_gem_object_unreference(&obj->base);
+ DRM_ERROR("Failed to pin semaphore bo. Disabling semaphores\n");
+ i915.semaphores = 0;
+ } else
+ dev_priv->semaphore_obj = obj;
+ }
+ }
ring->add_request = gen6_add_request;
ring->flush = gen8_render_ring_flush;
ring->irq_get = gen8_ring_get_irq;
@@ -1879,17 +1983,10 @@ int intel_init_render_ring_buffer(struct drm_device *dev)
ring->get_seqno = gen6_ring_get_seqno;
ring->set_seqno = ring_set_seqno;
if (i915_semaphore_is_enabled(dev)) {
+ BUG_ON(!dev_priv->semaphore_obj);
ring->semaphore.sync_to = gen6_ring_sync;
- ring->semaphore.signal = gen6_signal;
- ring->semaphore.signal = gen6_signal;
- ring->semaphore.mbox.wait[RCS] = MI_SEMAPHORE_SYNC_INVALID;
- ring->semaphore.mbox.wait[VCS] = MI_SEMAPHORE_SYNC_INVALID;
- ring->semaphore.mbox.wait[BCS] = MI_SEMAPHORE_SYNC_INVALID;
- ring->semaphore.mbox.wait[VECS] = MI_SEMAPHORE_SYNC_INVALID;
- ring->semaphore.mbox.signal[RCS] = GEN6_NOSYNC;
- ring->semaphore.mbox.signal[VCS] = GEN6_NOSYNC;
- ring->semaphore.mbox.signal[BCS] = GEN6_NOSYNC;
- ring->semaphore.mbox.signal[VECS] = GEN6_NOSYNC;
+ ring->semaphore.signal = gen8_rcs_signal;
+ GEN8_RING_SEMAPHORE_INIT;
}
} else if (INTEL_INFO(dev)->gen >= 6) {
ring->add_request = gen6_add_request;
@@ -1958,9 +2055,6 @@ int intel_init_render_ring_buffer(struct drm_device *dev)
/* Workaround batchbuffer to combat CS tlb bug. */
if (HAS_BROKEN_CS_TLB(dev)) {
- struct drm_i915_gem_object *obj;
- int ret;
-
obj = i915_gem_alloc_object(dev, I830_BATCH_LIMIT);
if (obj == NULL) {
DRM_ERROR("Failed to allocate batch bo\n");
@@ -2076,15 +2170,8 @@ int intel_init_bsd_ring_buffer(struct drm_device *dev)
gen8_ring_dispatch_execbuffer;
if (i915_semaphore_is_enabled(dev)) {
ring->semaphore.sync_to = gen6_ring_sync;
- ring->semaphore.signal = gen6_signal;
- ring->semaphore.mbox.wait[RCS] = MI_SEMAPHORE_SYNC_INVALID;
- ring->semaphore.mbox.wait[VCS] = MI_SEMAPHORE_SYNC_INVALID;
- ring->semaphore.mbox.wait[BCS] = MI_SEMAPHORE_SYNC_INVALID;
- ring->semaphore.mbox.wait[VECS] = MI_SEMAPHORE_SYNC_INVALID;
- ring->semaphore.mbox.signal[RCS] = GEN6_NOSYNC;
- ring->semaphore.mbox.signal[VCS] = GEN6_NOSYNC;
- ring->semaphore.mbox.signal[BCS] = GEN6_NOSYNC;
- ring->semaphore.mbox.signal[VECS] = GEN6_NOSYNC;
+ ring->semaphore.signal = gen8_xcs_signal;
+ GEN8_RING_SEMAPHORE_INIT;
}
} else {
ring->irq_enable_mask = GT_BSD_USER_INTERRUPT;
@@ -2149,15 +2236,8 @@ int intel_init_blt_ring_buffer(struct drm_device *dev)
ring->dispatch_execbuffer = gen8_ring_dispatch_execbuffer;
if (i915_semaphore_is_enabled(dev)) {
ring->semaphore.sync_to = gen6_ring_sync;
- ring->semaphore.signal = gen6_signal;
- ring->semaphore.mbox.wait[RCS] = MI_SEMAPHORE_SYNC_INVALID;
- ring->semaphore.mbox.wait[VCS] = MI_SEMAPHORE_SYNC_INVALID;
- ring->semaphore.mbox.wait[BCS] = MI_SEMAPHORE_SYNC_INVALID;
- ring->semaphore.mbox.wait[VECS] = MI_SEMAPHORE_SYNC_INVALID;
- ring->semaphore.mbox.signal[RCS] = GEN6_NOSYNC;
- ring->semaphore.mbox.signal[VCS] = GEN6_NOSYNC;
- ring->semaphore.mbox.signal[BCS] = GEN6_NOSYNC;
- ring->semaphore.mbox.signal[VECS] = GEN6_NOSYNC;
+ ring->semaphore.signal = gen8_xcs_signal;
+ GEN8_RING_SEMAPHORE_INIT;
}
} else {
ring->irq_enable_mask = GT_BLT_USER_INTERRUPT;
@@ -2205,15 +2285,8 @@ int intel_init_vebox_ring_buffer(struct drm_device *dev)
ring->dispatch_execbuffer = gen8_ring_dispatch_execbuffer;
if (i915_semaphore_is_enabled(dev)) {
ring->semaphore.sync_to = gen6_ring_sync;
- ring->semaphore.signal = gen6_signal;
- ring->semaphore.mbox.wait[RCS] = MI_SEMAPHORE_SYNC_INVALID;
- ring->semaphore.mbox.wait[VCS] = MI_SEMAPHORE_SYNC_INVALID;
- ring->semaphore.mbox.wait[BCS] = MI_SEMAPHORE_SYNC_INVALID;
- ring->semaphore.mbox.wait[VECS] = MI_SEMAPHORE_SYNC_INVALID;
- ring->semaphore.mbox.signal[RCS] = GEN6_NOSYNC;
- ring->semaphore.mbox.signal[VCS] = GEN6_NOSYNC;
- ring->semaphore.mbox.signal[BCS] = GEN6_NOSYNC;
- ring->semaphore.mbox.signal[VECS] = GEN6_NOSYNC;
+ ring->semaphore.signal = gen8_xcs_signal;
+ GEN8_RING_SEMAPHORE_INIT;
}
} else {
ring->irq_enable_mask = PM_VEBOX_USER_INTERRUPT;
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
index 36b4462..38a50c3 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -33,6 +33,31 @@ struct intel_hw_status_page {
#define I915_READ_IMR(ring) I915_READ(RING_IMR((ring)->mmio_base))
#define I915_WRITE_IMR(ring, val) I915_WRITE(RING_IMR((ring)->mmio_base), val)
+/* seqno size is actually only a uint32, but since we plan to use MI_FLUSH_DW to
+ * do the writes, and that must have qw aligned offsets, simply pretend it's 8b.
+ */
+#define i915_semaphore_seqno_size sizeof(uint64_t)
+#define GEN8_SIGNAL_OFFSET(to) \
+ (i915_gem_obj_ggtt_offset(dev_priv->semaphore_obj) + \
+ (ring->id * I915_NUM_RINGS * i915_semaphore_seqno_size) + \
+ (i915_semaphore_seqno_size * (to)))
+
+#define GEN8_WAIT_OFFSET(from) \
+ (i915_gem_obj_ggtt_offset(dev_priv->semaphore_obj) + \
+ ((from) * I915_NUM_RINGS * i915_semaphore_seqno_size) + \
+ (i915_semaphore_seqno_size * ring->id))
+
+#define GEN8_RING_SEMAPHORE_INIT do { \
+ if (!dev_priv->semaphore_obj) { \
+ break; \
+ } \
+ ring->semaphore.signal_ggtt[RCS] = GEN8_SIGNAL_OFFSET(RCS); \
+ ring->semaphore.signal_ggtt[VCS] = GEN8_SIGNAL_OFFSET(VCS); \
+ ring->semaphore.signal_ggtt[BCS] = GEN8_SIGNAL_OFFSET(BCS); \
+ ring->semaphore.signal_ggtt[VECS] = GEN8_SIGNAL_OFFSET(VECS); \
+ ring->semaphore.signal_ggtt[ring->id] = MI_SEMAPHORE_SYNC_INVALID; \
+ } while(0)
+
enum intel_ring_hangcheck_action {
HANGCHECK_IDLE = 0,
HANGCHECK_WAIT,
@@ -113,15 +138,51 @@ struct intel_ring_buffer {
#define I915_DISPATCH_PINNED 0x2
void (*cleanup)(struct intel_ring_buffer *ring);
+ /* GEN8 signal/wait table
+ * signal to signal to signal to signal to
+ * RCS VCS BCS VECS
+ * ------------------------------------------------------
+ * RCS | NOP (0x00) | BCS (0x08) | VCS (0x10) | VECS (0x18) |
+ * |-----------------------------------------------------
+ * VCS | RCS (0x20) | NOP (0x28) | BCS (0x30) | VECS (0x38) |
+ * |-----------------------------------------------------
+ * BCS | RCS (0x40) | VCS (0x48) | NOP (0x50) | VECS (0x58) |
+ * |-----------------------------------------------------
+ * VECS | RCS (0x60) | VCS (0x68) | BCS (0x70) | NOP (0x78) |
+ * |-----------------------------------------------------
+ *
+ * Generalization:
+ * f(x, y) := (x->id * NUM_RINGS * seqno_size) + (seqno_size * y->id)
+ * ie. transpose of g(x, y)
+ *
+ * sync from sync from sync from sync from
+ * RCS VCS BCS VECS
+ * ------------------------------------------------------
+ * RCS | NOP (0x00) | BCS (0x20) | VCS (0x40) | VECS (0x60) |
+ * |-----------------------------------------------------
+ * VCS | RCS (0x08) | NOP (0x28) | BCS (0x48) | VECS (0x68) |
+ * |-----------------------------------------------------
+ * BCS | RCS (0x10) | VCS (0x30) | NOP (0x50) | VECS (0x60) |
+ * |-----------------------------------------------------
+ * VECS | RCS (0x18) | VCS (0x38) | BCS (0x58) | NOP (0x78) |
+ * |-----------------------------------------------------
+ *
+ * Generalization:
+ * g(x, y) := (y->id * NUM_RINGS * seqno_size) + (seqno_size * x->id)
+ * ie. transpose of f(x, y)
+ */
struct {
u32 sync_seqno[I915_NUM_RINGS-1];
- struct {
- /* our mbox written by others */
- u32 wait[I915_NUM_RINGS];
- /* mboxes this ring signals to */
- u32 signal[I915_NUM_RINGS];
- } mbox;
+ union {
+ struct {
+ /* our mbox written by others */
+ u32 wait[I915_NUM_RINGS];
+ /* mboxes this ring signals to */
+ u32 signal[I915_NUM_RINGS];
+ } mbox;
+ u64 signal_ggtt[I915_NUM_RINGS];
+ };
/* AKA wait() */
int (*sync_to)(struct intel_ring_buffer *ring,
--
1.9.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 07/13] drm/i915/bdw: implement semaphore wait
2014-02-20 6:19 [PATCH 01/13] drm/i915: Move semaphore specific ring members to struct Ben Widawsky
` (4 preceding siblings ...)
2014-02-20 6:19 ` [PATCH 06/13] drm/i915/bdw: implement semaphore signal Ben Widawsky
@ 2014-02-20 6:19 ` Ben Widawsky
2014-02-20 6:19 ` [PATCH 08/13] drm/i915/bdw: poll semaphores Ben Widawsky
` (6 subsequent siblings)
12 siblings, 0 replies; 23+ messages in thread
From: Ben Widawsky @ 2014-02-20 6:19 UTC (permalink / raw)
To: Intel GFX; +Cc: Ben Widawsky, Ben Widawsky
Semaphore waits use a new instruction, MI_SEMAPHORE_WAIT. The seqno to
wait on is all well defined by the table in the previous patch. There is
nothing else different from previous GEN's semaphore synchronization
code.
v2: Update macros to not require the other ring's ring->id (Chris)
Signed-off-by: Ben Widawsky <ben@bwidawsk.net>
---
drivers/gpu/drm/i915/i915_reg.h | 3 +++
drivers/gpu/drm/i915/intel_ringbuffer.c | 33 +++++++++++++++++++++++++++++----
drivers/gpu/drm/i915/intel_ringbuffer.h | 4 ++--
3 files changed, 34 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 4e36d03..d02b856 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -242,6 +242,9 @@
#define MI_RESTORE_INHIBIT (1<<0)
#define MI_SEMAPHORE_SIGNAL MI_INSTR(0x1b, 0) /* GEN8+ */
#define MI_SEMAPHORE_TARGET(engine) ((engine)<<15)
+#define MI_SEMAPHORE_WAIT MI_INSTR(0x1c, 2) /* GEN8+ */
+#define MI_SEMAPHORE_POLL (1<<15)
+#define MI_SEMAPHORE_SAD_GTE_SDD (1<<12)
#define MI_STORE_DWORD_IMM MI_INSTR(0x20, 1)
#define MI_MEM_VIRTUAL (1 << 22) /* 965+ only */
#define MI_STORE_DWORD_INDEX MI_INSTR(0x21, 1)
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index 717976b..3d5dd4a 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -798,6 +798,31 @@ static inline bool i915_gem_has_seqno_wrapped(struct drm_device *dev,
* @signaller - ring which has, or will signal
* @seqno - seqno which the waiter will block on
*/
+
+static int
+gen8_ring_sync(struct intel_ring_buffer *waiter,
+ struct intel_ring_buffer *signaller,
+ u32 seqno)
+{
+ struct drm_i915_private *dev_priv = waiter->dev->dev_private;
+ int ret;
+
+ ret = intel_ring_begin(waiter, 4);
+ if (ret)
+ return ret;
+
+ intel_ring_emit(waiter, MI_SEMAPHORE_WAIT |
+ MI_SEMAPHORE_GLOBAL_GTT |
+ MI_SEMAPHORE_SAD_GTE_SDD);
+ intel_ring_emit(waiter, seqno);
+ intel_ring_emit(waiter,
+ lower_32_bits(GEN8_WAIT_OFFSET(waiter, signaller->id)));
+ intel_ring_emit(waiter,
+ upper_32_bits(GEN8_WAIT_OFFSET(waiter, signaller->id)));
+ intel_ring_advance(waiter);
+ return 0;
+}
+
static int
gen6_ring_sync(struct intel_ring_buffer *waiter,
struct intel_ring_buffer *signaller,
@@ -1984,7 +2009,7 @@ int intel_init_render_ring_buffer(struct drm_device *dev)
ring->set_seqno = ring_set_seqno;
if (i915_semaphore_is_enabled(dev)) {
BUG_ON(!dev_priv->semaphore_obj);
- ring->semaphore.sync_to = gen6_ring_sync;
+ ring->semaphore.sync_to = gen8_ring_sync;
ring->semaphore.signal = gen8_rcs_signal;
GEN8_RING_SEMAPHORE_INIT;
}
@@ -2169,7 +2194,7 @@ int intel_init_bsd_ring_buffer(struct drm_device *dev)
ring->dispatch_execbuffer =
gen8_ring_dispatch_execbuffer;
if (i915_semaphore_is_enabled(dev)) {
- ring->semaphore.sync_to = gen6_ring_sync;
+ ring->semaphore.sync_to = gen8_ring_sync;
ring->semaphore.signal = gen8_xcs_signal;
GEN8_RING_SEMAPHORE_INIT;
}
@@ -2235,7 +2260,7 @@ int intel_init_blt_ring_buffer(struct drm_device *dev)
ring->irq_put = gen8_ring_put_irq;
ring->dispatch_execbuffer = gen8_ring_dispatch_execbuffer;
if (i915_semaphore_is_enabled(dev)) {
- ring->semaphore.sync_to = gen6_ring_sync;
+ ring->semaphore.sync_to = gen8_ring_sync;
ring->semaphore.signal = gen8_xcs_signal;
GEN8_RING_SEMAPHORE_INIT;
}
@@ -2284,7 +2309,7 @@ int intel_init_vebox_ring_buffer(struct drm_device *dev)
ring->irq_put = gen8_ring_put_irq;
ring->dispatch_execbuffer = gen8_ring_dispatch_execbuffer;
if (i915_semaphore_is_enabled(dev)) {
- ring->semaphore.sync_to = gen6_ring_sync;
+ ring->semaphore.sync_to = gen8_ring_sync;
ring->semaphore.signal = gen8_xcs_signal;
GEN8_RING_SEMAPHORE_INIT;
}
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
index 38a50c3..5d56c95 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -42,10 +42,10 @@ struct intel_hw_status_page {
(ring->id * I915_NUM_RINGS * i915_semaphore_seqno_size) + \
(i915_semaphore_seqno_size * (to)))
-#define GEN8_WAIT_OFFSET(from) \
+#define GEN8_WAIT_OFFSET(__ring, from) \
(i915_gem_obj_ggtt_offset(dev_priv->semaphore_obj) + \
((from) * I915_NUM_RINGS * i915_semaphore_seqno_size) + \
- (i915_semaphore_seqno_size * ring->id))
+ (i915_semaphore_seqno_size * (__ring)->id))
#define GEN8_RING_SEMAPHORE_INIT do { \
if (!dev_priv->semaphore_obj) { \
--
1.9.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 08/13] drm/i915/bdw: poll semaphores
2014-02-20 6:19 [PATCH 01/13] drm/i915: Move semaphore specific ring members to struct Ben Widawsky
` (5 preceding siblings ...)
2014-02-20 6:19 ` [PATCH 07/13] drm/i915/bdw: implement semaphore wait Ben Widawsky
@ 2014-02-20 6:19 ` Ben Widawsky
2014-02-24 13:06 ` Ville Syrjälä
2014-02-20 6:19 ` [PATCH 09/13] drm/i915: Extract semaphore error collection Ben Widawsky
` (5 subsequent siblings)
12 siblings, 1 reply; 23+ messages in thread
From: Ben Widawsky @ 2014-02-20 6:19 UTC (permalink / raw)
To: Intel GFX; +Cc: Ben Widawsky, Ben Widawsky
Signed-off-by: Ben Widawsky <ben@bwidawsk.net>
---
drivers/gpu/drm/i915/intel_ringbuffer.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index 3d5dd4a..5f7bee8 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -813,6 +813,7 @@ gen8_ring_sync(struct intel_ring_buffer *waiter,
intel_ring_emit(waiter, MI_SEMAPHORE_WAIT |
MI_SEMAPHORE_GLOBAL_GTT |
+ MI_SEMAPHORE_POLL |
MI_SEMAPHORE_SAD_GTE_SDD);
intel_ring_emit(waiter, seqno);
intel_ring_emit(waiter,
--
1.9.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 09/13] drm/i915: Extract semaphore error collection
2014-02-20 6:19 [PATCH 01/13] drm/i915: Move semaphore specific ring members to struct Ben Widawsky
` (6 preceding siblings ...)
2014-02-20 6:19 ` [PATCH 08/13] drm/i915/bdw: poll semaphores Ben Widawsky
@ 2014-02-20 6:19 ` Ben Widawsky
2014-02-20 6:19 ` [PATCH 10/13] drm/i915/bdw: collect semaphore error state Ben Widawsky
` (4 subsequent siblings)
12 siblings, 0 replies; 23+ messages in thread
From: Ben Widawsky @ 2014-02-20 6:19 UTC (permalink / raw)
To: Intel GFX; +Cc: Ben Widawsky, Ben Widawsky
Signed-off-by: Ben Widawsky <ben@bwidawsk.net>
---
drivers/gpu/drm/i915/i915_gpu_error.c | 29 +++++++++++++++++------------
1 file changed, 17 insertions(+), 12 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c
index bcab114..2b64493 100644
--- a/drivers/gpu/drm/i915/i915_gpu_error.c
+++ b/drivers/gpu/drm/i915/i915_gpu_error.c
@@ -797,6 +797,22 @@ i915_error_first_batchbuffer(struct drm_i915_private *dev_priv,
return NULL;
}
+static void gen6_record_semaphore_state(struct drm_i915_private *dev_priv,
+ struct intel_ring_buffer *ring,
+ struct drm_i915_error_ring *ering)
+{
+ ering->semaphore_mboxes[0] = I915_READ(RING_SYNC_0(ring->mmio_base));
+ ering->semaphore_mboxes[1] = I915_READ(RING_SYNC_1(ring->mmio_base));
+ ering->semaphore_seqno[0] = ring->semaphore.sync_seqno[0];
+ ering->semaphore_seqno[1] = ring->semaphore.sync_seqno[1];
+
+ if (HAS_VEBOX(dev_priv->dev)) {
+ ering->semaphore_mboxes[2] =
+ I915_READ(RING_SYNC_2(ring->mmio_base));
+ ering->semaphore_seqno[2] = ring->semaphore.sync_seqno[2];
+ }
+}
+
static void i915_record_ring_state(struct drm_device *dev,
struct intel_ring_buffer *ring,
struct drm_i915_error_ring *ering)
@@ -806,18 +822,7 @@ static void i915_record_ring_state(struct drm_device *dev,
if (INTEL_INFO(dev)->gen >= 6) {
ering->rc_psmi = I915_READ(ring->mmio_base + 0x50);
ering->fault_reg = I915_READ(RING_FAULT_REG(ring));
- ering->semaphore_mboxes[0]
- = I915_READ(RING_SYNC_0(ring->mmio_base));
- ering->semaphore_mboxes[1]
- = I915_READ(RING_SYNC_1(ring->mmio_base));
- ering->semaphore_seqno[0] = ring->semaphore.sync_seqno[0];
- ering->semaphore_seqno[1] = ring->semaphore.sync_seqno[1];
- }
-
- if (HAS_VEBOX(dev)) {
- ering->semaphore_mboxes[2] =
- I915_READ(RING_SYNC_2(ring->mmio_base));
- ering->semaphore_seqno[2] = ring->semaphore.sync_seqno[2];
+ gen6_record_semaphore_state(dev_priv, ring, ering);
}
if (INTEL_INFO(dev)->gen >= 4) {
--
1.9.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 10/13] drm/i915/bdw: collect semaphore error state
2014-02-20 6:19 [PATCH 01/13] drm/i915: Move semaphore specific ring members to struct Ben Widawsky
` (7 preceding siblings ...)
2014-02-20 6:19 ` [PATCH 09/13] drm/i915: Extract semaphore error collection Ben Widawsky
@ 2014-02-20 6:19 ` Ben Widawsky
2014-02-24 13:08 ` Ville Syrjälä
2014-02-20 6:19 ` [PATCH 11/13] drm/i915: unleash semaphores on gen8 Ben Widawsky
` (3 subsequent siblings)
12 siblings, 1 reply; 23+ messages in thread
From: Ben Widawsky @ 2014-02-20 6:19 UTC (permalink / raw)
To: Intel GFX; +Cc: Ben Widawsky, Ben Widawsky
Since the semaphore information is in an object, just dump it, and let
the user parse it later.
NOTE: The page being used for the semaphores are incoherent with the
CPU. No matter what I do, I cannot figure out a way to read anything but
0s. Note that the semaphore waits are indeed working.
v2: Don't print signal, and wait (they should be the same). Instead,
print sync_seqno (Chris)
v3: Free the semaphore error object (Chris)
v4: Fix semaphore offset calculation during error state collection
(Ville)
Signed-off-by: Ben Widawsky <ben@bwidawsk.net>
---
drivers/gpu/drm/i915/i915_drv.h | 1 +
drivers/gpu/drm/i915/i915_gpu_error.c | 52 ++++++++++++++++++++++++++++++---
drivers/gpu/drm/i915/intel_ringbuffer.h | 12 ++++----
3 files changed, 55 insertions(+), 10 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 028ce5a..9b86874 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -322,6 +322,7 @@ struct drm_i915_error_state {
u64 fence[I915_MAX_NUM_FENCES];
struct intel_overlay_error_state *overlay;
struct intel_display_error_state *display;
+ struct drm_i915_error_object *semaphore_obj;
struct drm_i915_error_ring {
bool valid;
diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c
index 2b64493..25fc2ea 100644
--- a/drivers/gpu/drm/i915/i915_gpu_error.c
+++ b/drivers/gpu/drm/i915/i915_gpu_error.c
@@ -310,6 +310,7 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m,
struct drm_device *dev = error_priv->dev;
drm_i915_private_t *dev_priv = dev->dev_private;
struct drm_i915_error_state *error = error_priv->error;
+ struct drm_i915_error_object *obj;
int i, j, page, offset, elt;
if (!error) {
@@ -360,8 +361,6 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m,
error->pinned_bo_count[0]);
for (i = 0; i < ARRAY_SIZE(error->ring); i++) {
- struct drm_i915_error_object *obj;
-
if ((obj = error->ring[i].batchbuffer)) {
err_printf(m, "%s --- gtt_offset = 0x%08x\n",
dev_priv->ring[i].name,
@@ -436,6 +435,19 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m,
}
}
+ obj = error->semaphore_obj;
+ if (obj) {
+ err_printf(m, "Semaphore page = 0x%08x\n", obj->gtt_offset);
+ for (elt = 0; elt < PAGE_SIZE/16; elt += 4) {
+ err_printf(m, "[%04x] %08x %08x %08x %08x\n",
+ elt * 4,
+ obj->pages[0][elt],
+ obj->pages[0][elt+1],
+ obj->pages[0][elt+2],
+ obj->pages[0][elt+3]);
+ }
+ }
+
if (error->overlay)
intel_overlay_print_error_state(m, error->overlay);
@@ -506,6 +518,7 @@ static void i915_error_state_free(struct kref *error_ref)
kfree(error->ring[i].requests);
}
+ i915_error_object_free(error->semaphore_obj);
kfree(error->active_bo);
kfree(error->overlay);
kfree(error->display);
@@ -797,6 +810,33 @@ i915_error_first_batchbuffer(struct drm_i915_private *dev_priv,
return NULL;
}
+static void gen8_record_semaphore_state(struct drm_i915_private *dev_priv,
+ struct drm_i915_error_state *error,
+ struct intel_ring_buffer *ring,
+ struct drm_i915_error_ring *ering)
+{
+ struct intel_ring_buffer *useless;
+ int i;
+
+ if (!i915_semaphore_is_enabled(dev_priv->dev))
+ return;
+
+ if (!error->semaphore_obj)
+ error->semaphore_obj =
+ i915_error_object_create(dev_priv,
+ dev_priv->semaphore_obj,
+ &dev_priv->gtt.base);
+
+ for_each_ring(useless, dev_priv, i) {
+ u16 signal_offset =
+ (GEN8_SIGNAL_OFFSET(ring, i) / 4) & PAGE_MASK;
+ u32 *tmp = error->semaphore_obj->pages[0];
+
+ ering->semaphore_mboxes[i] = tmp[signal_offset];
+ ering->semaphore_seqno[i] = ring->semaphore.sync_seqno[i];
+ }
+}
+
static void gen6_record_semaphore_state(struct drm_i915_private *dev_priv,
struct intel_ring_buffer *ring,
struct drm_i915_error_ring *ering)
@@ -814,6 +854,7 @@ static void gen6_record_semaphore_state(struct drm_i915_private *dev_priv,
}
static void i915_record_ring_state(struct drm_device *dev,
+ struct drm_i915_error_state *error,
struct intel_ring_buffer *ring,
struct drm_i915_error_ring *ering)
{
@@ -822,7 +863,10 @@ static void i915_record_ring_state(struct drm_device *dev,
if (INTEL_INFO(dev)->gen >= 6) {
ering->rc_psmi = I915_READ(ring->mmio_base + 0x50);
ering->fault_reg = I915_READ(RING_FAULT_REG(ring));
- gen6_record_semaphore_state(dev_priv, ring, ering);
+ if (INTEL_INFO(dev)->gen >= 8)
+ gen8_record_semaphore_state(dev_priv, error, ring, ering);
+ else
+ gen6_record_semaphore_state(dev_priv, ring, ering);
}
if (INTEL_INFO(dev)->gen >= 4) {
@@ -948,7 +992,7 @@ static void i915_gem_record_rings(struct drm_device *dev,
error->ring[i].valid = true;
- i915_record_ring_state(dev, ring, &error->ring[i]);
+ i915_record_ring_state(dev, error, ring, &error->ring[i]);
error->ring[i].batchbuffer =
i915_error_first_batchbuffer(dev_priv, ring);
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
index 5d56c95..01aad54 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -37,9 +37,9 @@ struct intel_hw_status_page {
* do the writes, and that must have qw aligned offsets, simply pretend it's 8b.
*/
#define i915_semaphore_seqno_size sizeof(uint64_t)
-#define GEN8_SIGNAL_OFFSET(to) \
+#define GEN8_SIGNAL_OFFSET(__ring, to) \
(i915_gem_obj_ggtt_offset(dev_priv->semaphore_obj) + \
- (ring->id * I915_NUM_RINGS * i915_semaphore_seqno_size) + \
+ ((__ring)->id * I915_NUM_RINGS * i915_semaphore_seqno_size) + \
(i915_semaphore_seqno_size * (to)))
#define GEN8_WAIT_OFFSET(__ring, from) \
@@ -51,10 +51,10 @@ struct intel_hw_status_page {
if (!dev_priv->semaphore_obj) { \
break; \
} \
- ring->semaphore.signal_ggtt[RCS] = GEN8_SIGNAL_OFFSET(RCS); \
- ring->semaphore.signal_ggtt[VCS] = GEN8_SIGNAL_OFFSET(VCS); \
- ring->semaphore.signal_ggtt[BCS] = GEN8_SIGNAL_OFFSET(BCS); \
- ring->semaphore.signal_ggtt[VECS] = GEN8_SIGNAL_OFFSET(VECS); \
+ ring->semaphore.signal_ggtt[RCS] = GEN8_SIGNAL_OFFSET(ring, RCS); \
+ ring->semaphore.signal_ggtt[VCS] = GEN8_SIGNAL_OFFSET(ring, VCS); \
+ ring->semaphore.signal_ggtt[BCS] = GEN8_SIGNAL_OFFSET(ring, BCS); \
+ ring->semaphore.signal_ggtt[VECS] = GEN8_SIGNAL_OFFSET(ring, VECS); \
ring->semaphore.signal_ggtt[ring->id] = MI_SEMAPHORE_SYNC_INVALID; \
} while(0)
--
1.9.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 11/13] drm/i915: unleash semaphores on gen8
2014-02-20 6:19 [PATCH 01/13] drm/i915: Move semaphore specific ring members to struct Ben Widawsky
` (8 preceding siblings ...)
2014-02-20 6:19 ` [PATCH 10/13] drm/i915/bdw: collect semaphore error state Ben Widawsky
@ 2014-02-20 6:19 ` Ben Widawsky
2014-02-20 6:19 ` [PATCH 12/13] drm/i915: semaphore debugfs Ben Widawsky
` (2 subsequent siblings)
12 siblings, 0 replies; 23+ messages in thread
From: Ben Widawsky @ 2014-02-20 6:19 UTC (permalink / raw)
To: Intel GFX; +Cc: Ben Widawsky, Ben Widawsky
Everything should be lined up now to make gen8 semaphores work like they
did on previous generations, so just do it.
Signed-off-by: Ben Widawsky <ben@bwidawsk.net>
---
drivers/gpu/drm/i915/i915_drv.c | 6 ------
1 file changed, 6 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 2d05d7c..ebeefdd 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -401,12 +401,6 @@ bool i915_semaphore_is_enabled(struct drm_device *dev)
if (INTEL_INFO(dev)->gen < 6)
return false;
- /* Until we get further testing... */
- if (IS_GEN8(dev)) {
- WARN_ON(!i915.preliminary_hw_support);
- return false;
- }
-
if (i915.semaphores >= 0)
return i915.semaphores;
--
1.9.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 12/13] drm/i915: semaphore debugfs
2014-02-20 6:19 [PATCH 01/13] drm/i915: Move semaphore specific ring members to struct Ben Widawsky
` (9 preceding siblings ...)
2014-02-20 6:19 ` [PATCH 11/13] drm/i915: unleash semaphores on gen8 Ben Widawsky
@ 2014-02-20 6:19 ` Ben Widawsky
2014-02-20 6:19 ` [PATCH 13/13] DONT_MERGE drm/i915: FORCE_RESTORE for gen8 semaphores Ben Widawsky
2014-03-05 12:29 ` [PATCH 01/13] drm/i915: Move semaphore specific ring members to struct Ville Syrjälä
12 siblings, 0 replies; 23+ messages in thread
From: Ben Widawsky @ 2014-02-20 6:19 UTC (permalink / raw)
To: Intel GFX; +Cc: Ben Widawsky, Ben Widawsky
Simple debugfs file to display the current state of semaphores. This is
useful if you want to see the state without hanging the GPU.
NOTE: This patch is optional to the series.
NOTE2: Like the GPU error state collection, the reads are currently
incoherent.
Signed-off-by: Ben Widawsky <ben@bwidawsk.net>
---
drivers/gpu/drm/i915/i915_debugfs.c | 70 +++++++++++++++++++++++++++++++++++++
1 file changed, 70 insertions(+)
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index d90a707..6f3ecb6 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -2235,6 +2235,75 @@ static int i915_display_info(struct seq_file *m, void *unused)
return 0;
}
+static int i915_semaphore_status(struct seq_file *m, void *unused)
+{
+ struct drm_info_node *node = (struct drm_info_node *) m->private;
+ struct drm_device *dev = node->minor->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_ring_buffer *ring;
+ int i, j, ret;
+
+ if (!i915_semaphore_is_enabled(dev)) {
+ seq_puts(m, "Semaphores are disabled\n");
+ return 0;
+ }
+
+ ret = mutex_lock_interruptible(&dev->struct_mutex);
+ if (ret)
+ return ret;
+
+ if (IS_BROADWELL(dev)) {
+ struct page *page;
+ uint64_t *seqno;
+
+ page = i915_gem_object_get_page(dev_priv->semaphore_obj, 0);
+
+ seqno = (uint64_t *)kmap_atomic(page);
+ for_each_ring(ring, dev_priv, i) {
+ uint64_t offset;
+
+ seq_printf(m, "%s\n", ring->name);
+
+ seq_puts(m, " Last signal:");
+ for (j = 0; j < I915_NUM_RINGS; j++) {
+ offset = i * I915_NUM_RINGS + j;
+ seq_printf(m, "0x%08llx (0x%02llx) ",
+ seqno[offset], offset * 8);
+ }
+ seq_putc(m, '\n');
+
+ seq_puts(m, " Last wait: ");
+ for (j = 0; j < I915_NUM_RINGS; j++) {
+ offset = i + (j * I915_NUM_RINGS);
+ seq_printf(m, "0x%08llx (0x%02llx) ",
+ seqno[offset], offset * 8);
+ }
+ seq_putc(m, '\n');
+
+ }
+ kunmap_atomic(seqno);
+ } else {
+ seq_puts(m, " Last signal:");
+ for_each_ring(ring, dev_priv, i)
+ for (j = 0; j < I915_NUM_RINGS; j++)
+ seq_printf(m, "0x%08x\n",
+ I915_READ(ring->semaphore.mbox.signal[j]));
+ seq_putc(m, '\n');
+ }
+
+ seq_puts(m, "\nSync seqno:\n");
+ for_each_ring(ring, dev_priv, i) {
+ for (j = 0; j < I915_NUM_RINGS; j++) {
+ seq_printf(m, " 0x%08x ", ring->semaphore.sync_seqno[j]);
+ }
+ seq_putc(m, '\n');
+ }
+ seq_putc(m, '\n');
+
+ mutex_unlock(&dev->struct_mutex);
+ return 0;
+}
+
struct pipe_crc_info {
const char *name;
struct drm_device *dev;
@@ -3681,6 +3750,7 @@ static const struct drm_info_list i915_debugfs_list[] = {
{"i915_pc8_status", i915_pc8_status, 0},
{"i915_power_domain_info", i915_power_domain_info, 0},
{"i915_display_info", i915_display_info, 0},
+ {"i915_semaphore_status", i915_semaphore_status, 0},
};
#define I915_DEBUGFS_ENTRIES ARRAY_SIZE(i915_debugfs_list)
--
1.9.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 13/13] DONT_MERGE drm/i915: FORCE_RESTORE for gen8 semaphores
2014-02-20 6:19 [PATCH 01/13] drm/i915: Move semaphore specific ring members to struct Ben Widawsky
` (10 preceding siblings ...)
2014-02-20 6:19 ` [PATCH 12/13] drm/i915: semaphore debugfs Ben Widawsky
@ 2014-02-20 6:19 ` Ben Widawsky
2014-03-05 12:29 ` [PATCH 01/13] drm/i915: Move semaphore specific ring members to struct Ville Syrjälä
12 siblings, 0 replies; 23+ messages in thread
From: Ben Widawsky @ 2014-02-20 6:19 UTC (permalink / raw)
To: Intel GFX; +Cc: Ben Widawsky, Ben Widawsky
This appears to not actually be needed on the current code. Just putting
it on the ML so we can point bug reports at it later.
Signed-off-by: Ben Widawsky <ben@bwidawsk.net>
---
drivers/gpu/drm/i915/i915_gem_context.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
index f8c21a6..782f633 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -655,6 +655,13 @@ static int do_switch(struct intel_ring_buffer *ring,
if (!to->is_initialized || i915_gem_context_is_default(to))
hw_flags |= MI_RESTORE_INHIBIT;
+ /* When SW intends to use semaphore signaling between Command streamers,
+ * it must avoid lite restores in HW by programming "Force Restore" bit
+ * to ‘1’ in context descriptor during context submission
+ */
+ if (IS_GEN8(ring->dev) && i915_semaphore_is_enabled(ring->dev))
+ hw_flags |= MI_FORCE_RESTORE;
+
ret = mi_set_context(ring, to, hw_flags);
if (ret)
goto unpin_out;
--
1.9.0
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 23+ messages in thread
* Re: [PATCH 05/13] drm/i915: gen specific ring init
2014-02-20 6:19 ` [PATCH 05/13] drm/i915: gen specific ring init Ben Widawsky
@ 2014-02-24 13:05 ` Ville Syrjälä
0 siblings, 0 replies; 23+ messages in thread
From: Ville Syrjälä @ 2014-02-24 13:05 UTC (permalink / raw)
To: Ben Widawsky; +Cc: Intel GFX, Ben Widawsky
On Wed, Feb 19, 2014 at 10:19:18PM -0800, Ben Widawsky wrote:
> Gen8 has already had some differentiation with how it handles rings.
> Semaphores bring yet more differences, and now is as good a time as any
> to do the split.
>
> Also, since gen8 doesn't actually use semaphores up until this point,
> put the proper "NULL" values in for the mbox info.
>
> v2: v1 had a stale commit message
>
> v3: Move everything in the is_semaphore_enabled() check
>
> Signed-off-by: Ben Widawsky <ben@bwidawsk.net>
> ---
> drivers/gpu/drm/i915/intel_ringbuffer.c | 142 ++++++++++++++++++++++----------
> 1 file changed, 97 insertions(+), 45 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
> index bf061dd..691da67 100644
> --- a/drivers/gpu/drm/i915/intel_ringbuffer.c
> +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
> @@ -1870,19 +1870,34 @@ int intel_init_render_ring_buffer(struct drm_device *dev)
> ring->id = RCS;
> ring->mmio_base = RENDER_RING_BASE;
>
> - if (INTEL_INFO(dev)->gen >= 6) {
> + if (INTEL_INFO(dev)->gen >= 8) {
> + ring->add_request = gen6_add_request;
> + ring->flush = gen8_render_ring_flush;
> + ring->irq_get = gen8_ring_get_irq;
> + ring->irq_put = gen8_ring_put_irq;
> + ring->irq_enable_mask = GT_RENDER_USER_INTERRUPT;
> + ring->get_seqno = gen6_ring_get_seqno;
> + ring->set_seqno = ring_set_seqno;
> + if (i915_semaphore_is_enabled(dev)) {
> + ring->semaphore.sync_to = gen6_ring_sync;
> + ring->semaphore.signal = gen6_signal;
> + ring->semaphore.signal = gen6_signal;
Double assignment.
> + ring->semaphore.mbox.wait[RCS] = MI_SEMAPHORE_SYNC_INVALID;
> + ring->semaphore.mbox.wait[VCS] = MI_SEMAPHORE_SYNC_INVALID;
> + ring->semaphore.mbox.wait[BCS] = MI_SEMAPHORE_SYNC_INVALID;
> + ring->semaphore.mbox.wait[VECS] = MI_SEMAPHORE_SYNC_INVALID;
> + ring->semaphore.mbox.signal[RCS] = GEN6_NOSYNC;
> + ring->semaphore.mbox.signal[VCS] = GEN6_NOSYNC;
> + ring->semaphore.mbox.signal[BCS] = GEN6_NOSYNC;
> + ring->semaphore.mbox.signal[VECS] = GEN6_NOSYNC;
> + }
> + } else if (INTEL_INFO(dev)->gen >= 6) {
> ring->add_request = gen6_add_request;
> ring->flush = gen7_render_ring_flush;
> if (INTEL_INFO(dev)->gen == 6)
> ring->flush = gen6_render_ring_flush;
> - if (INTEL_INFO(dev)->gen >= 8) {
> - ring->flush = gen8_render_ring_flush;
> - ring->irq_get = gen8_ring_get_irq;
> - ring->irq_put = gen8_ring_put_irq;
> - } else {
> - ring->irq_get = gen6_ring_get_irq;
> - ring->irq_put = gen6_ring_put_irq;
> - }
> + ring->irq_get = gen6_ring_get_irq;
> + ring->irq_put = gen6_ring_put_irq;
> ring->irq_enable_mask = GT_RENDER_USER_INTERRUPT;
> ring->get_seqno = gen6_ring_get_seqno;
> ring->set_seqno = ring_set_seqno;
> @@ -1925,6 +1940,7 @@ int intel_init_render_ring_buffer(struct drm_device *dev)
> ring->irq_enable_mask = I915_USER_INTERRUPT;
> }
> ring->write_tail = ring_write_tail;
> +
> if (IS_HASWELL(dev))
> ring->dispatch_execbuffer = hsw_ring_dispatch_execbuffer;
> else if (IS_GEN8(dev))
> @@ -2058,24 +2074,36 @@ int intel_init_bsd_ring_buffer(struct drm_device *dev)
> ring->irq_put = gen8_ring_put_irq;
> ring->dispatch_execbuffer =
> gen8_ring_dispatch_execbuffer;
> + if (i915_semaphore_is_enabled(dev)) {
> + ring->semaphore.sync_to = gen6_ring_sync;
> + ring->semaphore.signal = gen6_signal;
> + ring->semaphore.mbox.wait[RCS] = MI_SEMAPHORE_SYNC_INVALID;
> + ring->semaphore.mbox.wait[VCS] = MI_SEMAPHORE_SYNC_INVALID;
> + ring->semaphore.mbox.wait[BCS] = MI_SEMAPHORE_SYNC_INVALID;
> + ring->semaphore.mbox.wait[VECS] = MI_SEMAPHORE_SYNC_INVALID;
> + ring->semaphore.mbox.signal[RCS] = GEN6_NOSYNC;
> + ring->semaphore.mbox.signal[VCS] = GEN6_NOSYNC;
> + ring->semaphore.mbox.signal[BCS] = GEN6_NOSYNC;
> + ring->semaphore.mbox.signal[VECS] = GEN6_NOSYNC;
> + }
> } else {
> ring->irq_enable_mask = GT_BSD_USER_INTERRUPT;
> ring->irq_get = gen6_ring_get_irq;
> ring->irq_put = gen6_ring_put_irq;
> ring->dispatch_execbuffer =
> gen6_ring_dispatch_execbuffer;
> - }
> - if (i915_semaphore_is_enabled(dev)) {
> - ring->semaphore.sync_to = gen6_ring_sync;
> - ring->semaphore.signal = gen6_signal;
> - ring->semaphore.mbox.wait[RCS] = MI_SEMAPHORE_SYNC_VR;
> - ring->semaphore.mbox.wait[VCS] = MI_SEMAPHORE_SYNC_INVALID;
> - ring->semaphore.mbox.wait[BCS] = MI_SEMAPHORE_SYNC_VB;
> - ring->semaphore.mbox.wait[VECS] = MI_SEMAPHORE_SYNC_VVE;
> - ring->semaphore.mbox.signal[RCS] = GEN6_RVSYNC;
> - ring->semaphore.mbox.signal[VCS] = GEN6_NOSYNC;
> - ring->semaphore.mbox.signal[BCS] = GEN6_BVSYNC;
> - ring->semaphore.mbox.signal[VECS] = GEN6_VEVSYNC;
> + if (i915_semaphore_is_enabled(dev)) {
> + ring->semaphore.sync_to = gen6_ring_sync;
> + ring->semaphore.signal = gen6_signal;
> + ring->semaphore.mbox.wait[RCS] = MI_SEMAPHORE_SYNC_VR;
> + ring->semaphore.mbox.wait[VCS] = MI_SEMAPHORE_SYNC_INVALID;
> + ring->semaphore.mbox.wait[BCS] = MI_SEMAPHORE_SYNC_VB;
> + ring->semaphore.mbox.wait[VECS] = MI_SEMAPHORE_SYNC_VVE;
> + ring->semaphore.mbox.signal[RCS] = GEN6_RVSYNC;
> + ring->semaphore.mbox.signal[VCS] = GEN6_NOSYNC;
> + ring->semaphore.mbox.signal[BCS] = GEN6_BVSYNC;
> + ring->semaphore.mbox.signal[VECS] = GEN6_VEVSYNC;
> + }
> }
> } else {
> ring->mmio_base = BSD_RING_BASE;
> @@ -2119,23 +2147,35 @@ int intel_init_blt_ring_buffer(struct drm_device *dev)
> ring->irq_get = gen8_ring_get_irq;
> ring->irq_put = gen8_ring_put_irq;
> ring->dispatch_execbuffer = gen8_ring_dispatch_execbuffer;
> + if (i915_semaphore_is_enabled(dev)) {
> + ring->semaphore.sync_to = gen6_ring_sync;
> + ring->semaphore.signal = gen6_signal;
> + ring->semaphore.mbox.wait[RCS] = MI_SEMAPHORE_SYNC_INVALID;
> + ring->semaphore.mbox.wait[VCS] = MI_SEMAPHORE_SYNC_INVALID;
> + ring->semaphore.mbox.wait[BCS] = MI_SEMAPHORE_SYNC_INVALID;
> + ring->semaphore.mbox.wait[VECS] = MI_SEMAPHORE_SYNC_INVALID;
> + ring->semaphore.mbox.signal[RCS] = GEN6_NOSYNC;
> + ring->semaphore.mbox.signal[VCS] = GEN6_NOSYNC;
> + ring->semaphore.mbox.signal[BCS] = GEN6_NOSYNC;
> + ring->semaphore.mbox.signal[VECS] = GEN6_NOSYNC;
> + }
> } else {
> ring->irq_enable_mask = GT_BLT_USER_INTERRUPT;
> ring->irq_get = gen6_ring_get_irq;
> ring->irq_put = gen6_ring_put_irq;
> ring->dispatch_execbuffer = gen6_ring_dispatch_execbuffer;
> - }
> - if (i915_semaphore_is_enabled(dev)) {
> - ring->semaphore.signal = gen6_signal;
> - ring->semaphore.sync_to = gen6_ring_sync;
> - ring->semaphore.mbox.wait[RCS] = MI_SEMAPHORE_SYNC_BR;
> - ring->semaphore.mbox.wait[VCS] = MI_SEMAPHORE_SYNC_BV;
> - ring->semaphore.mbox.wait[BCS] = MI_SEMAPHORE_SYNC_INVALID;
> - ring->semaphore.mbox.wait[VECS] = MI_SEMAPHORE_SYNC_BVE;
> - ring->semaphore.mbox.signal[RCS] = GEN6_RBSYNC;
> - ring->semaphore.mbox.signal[VCS] = GEN6_VBSYNC;
> - ring->semaphore.mbox.signal[BCS] = GEN6_NOSYNC;
> - ring->semaphore.mbox.signal[VECS] = GEN6_VEBSYNC;
> + if (i915_semaphore_is_enabled(dev)) {
> + ring->semaphore.signal = gen6_signal;
> + ring->semaphore.sync_to = gen6_ring_sync;
> + ring->semaphore.mbox.wait[RCS] = MI_SEMAPHORE_SYNC_BR;
> + ring->semaphore.mbox.wait[VCS] = MI_SEMAPHORE_SYNC_BV;
> + ring->semaphore.mbox.wait[BCS] = MI_SEMAPHORE_SYNC_INVALID;
> + ring->semaphore.mbox.wait[VECS] = MI_SEMAPHORE_SYNC_BVE;
> + ring->semaphore.mbox.signal[RCS] = GEN6_RBSYNC;
> + ring->semaphore.mbox.signal[VCS] = GEN6_VBSYNC;
> + ring->semaphore.mbox.signal[BCS] = GEN6_NOSYNC;
> + ring->semaphore.mbox.signal[VECS] = GEN6_VEBSYNC;
> + }
> }
> ring->init = init_ring_common;
>
> @@ -2163,23 +2203,35 @@ int intel_init_vebox_ring_buffer(struct drm_device *dev)
> ring->irq_get = gen8_ring_get_irq;
> ring->irq_put = gen8_ring_put_irq;
> ring->dispatch_execbuffer = gen8_ring_dispatch_execbuffer;
> + if (i915_semaphore_is_enabled(dev)) {
> + ring->semaphore.sync_to = gen6_ring_sync;
> + ring->semaphore.signal = gen6_signal;
> + ring->semaphore.mbox.wait[RCS] = MI_SEMAPHORE_SYNC_INVALID;
> + ring->semaphore.mbox.wait[VCS] = MI_SEMAPHORE_SYNC_INVALID;
> + ring->semaphore.mbox.wait[BCS] = MI_SEMAPHORE_SYNC_INVALID;
> + ring->semaphore.mbox.wait[VECS] = MI_SEMAPHORE_SYNC_INVALID;
> + ring->semaphore.mbox.signal[RCS] = GEN6_NOSYNC;
> + ring->semaphore.mbox.signal[VCS] = GEN6_NOSYNC;
> + ring->semaphore.mbox.signal[BCS] = GEN6_NOSYNC;
> + ring->semaphore.mbox.signal[VECS] = GEN6_NOSYNC;
> + }
> } else {
> ring->irq_enable_mask = PM_VEBOX_USER_INTERRUPT;
> ring->irq_get = hsw_vebox_get_irq;
> ring->irq_put = hsw_vebox_put_irq;
> ring->dispatch_execbuffer = gen6_ring_dispatch_execbuffer;
> - }
> - if (i915_semaphore_is_enabled(dev)) {
> - ring->semaphore.sync_to = gen6_ring_sync;
> - ring->semaphore.signal = gen6_signal;
> - ring->semaphore.mbox.wait[RCS] = MI_SEMAPHORE_SYNC_VER;
> - ring->semaphore.mbox.wait[VCS] = MI_SEMAPHORE_SYNC_VEV;
> - ring->semaphore.mbox.wait[BCS] = MI_SEMAPHORE_SYNC_VEB;
> - ring->semaphore.mbox.wait[VECS] = MI_SEMAPHORE_SYNC_INVALID;
> - ring->semaphore.mbox.signal[RCS] = GEN6_RVESYNC;
> - ring->semaphore.mbox.signal[VCS] = GEN6_VVESYNC;
> - ring->semaphore.mbox.signal[BCS] = GEN6_BVESYNC;
> - ring->semaphore.mbox.signal[VECS] = GEN6_NOSYNC;
> + if (i915_semaphore_is_enabled(dev)) {
> + ring->semaphore.sync_to = gen6_ring_sync;
> + ring->semaphore.signal = gen6_signal;
> + ring->semaphore.mbox.wait[RCS] = MI_SEMAPHORE_SYNC_VER;
> + ring->semaphore.mbox.wait[VCS] = MI_SEMAPHORE_SYNC_VEV;
> + ring->semaphore.mbox.wait[BCS] = MI_SEMAPHORE_SYNC_VEB;
> + ring->semaphore.mbox.wait[VECS] = MI_SEMAPHORE_SYNC_INVALID;
> + ring->semaphore.mbox.signal[RCS] = GEN6_RVESYNC;
> + ring->semaphore.mbox.signal[VCS] = GEN6_VVESYNC;
> + ring->semaphore.mbox.signal[BCS] = GEN6_BVESYNC;
> + ring->semaphore.mbox.signal[VECS] = GEN6_NOSYNC;
> + }
> }
> ring->init = init_ring_common;
>
> --
> 1.9.0
--
Ville Syrjälä
Intel OTC
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 08/13] drm/i915/bdw: poll semaphores
2014-02-20 6:19 ` [PATCH 08/13] drm/i915/bdw: poll semaphores Ben Widawsky
@ 2014-02-24 13:06 ` Ville Syrjälä
0 siblings, 0 replies; 23+ messages in thread
From: Ville Syrjälä @ 2014-02-24 13:06 UTC (permalink / raw)
To: Ben Widawsky; +Cc: Intel GFX, Ben Widawsky
On Wed, Feb 19, 2014 at 10:19:21PM -0800, Ben Widawsky wrote:
> Signed-off-by: Ben Widawsky <ben@bwidawsk.net>
> ---
> drivers/gpu/drm/i915/intel_ringbuffer.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
> index 3d5dd4a..5f7bee8 100644
> --- a/drivers/gpu/drm/i915/intel_ringbuffer.c
> +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
> @@ -813,6 +813,7 @@ gen8_ring_sync(struct intel_ring_buffer *waiter,
>
> intel_ring_emit(waiter, MI_SEMAPHORE_WAIT |
> MI_SEMAPHORE_GLOBAL_GTT |
> + MI_SEMAPHORE_POLL |
I discussed this on irc w/ Ben, and I was suggesting we don't need to
poll. Polling apparently can be used as a workaround for certain
hardware issues, but it looks like those issues shouldn't affect us,
for the momemnt at least. So my suggestion was to try w/o polling first
(since there could be some power cost to polling) and add the poll bit
if problems arise.
> MI_SEMAPHORE_SAD_GTE_SDD);
> intel_ring_emit(waiter, seqno);
> intel_ring_emit(waiter,
> --
> 1.9.0
--
Ville Syrjälä
Intel OTC
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 10/13] drm/i915/bdw: collect semaphore error state
2014-02-20 6:19 ` [PATCH 10/13] drm/i915/bdw: collect semaphore error state Ben Widawsky
@ 2014-02-24 13:08 ` Ville Syrjälä
2014-04-29 21:43 ` Ben Widawsky
0 siblings, 1 reply; 23+ messages in thread
From: Ville Syrjälä @ 2014-02-24 13:08 UTC (permalink / raw)
To: Ben Widawsky; +Cc: Intel GFX, Ben Widawsky
On Wed, Feb 19, 2014 at 10:19:23PM -0800, Ben Widawsky wrote:
> Since the semaphore information is in an object, just dump it, and let
> the user parse it later.
>
> NOTE: The page being used for the semaphores are incoherent with the
> CPU. No matter what I do, I cannot figure out a way to read anything but
> 0s. Note that the semaphore waits are indeed working.
>
> v2: Don't print signal, and wait (they should be the same). Instead,
> print sync_seqno (Chris)
>
> v3: Free the semaphore error object (Chris)
>
> v4: Fix semaphore offset calculation during error state collection
> (Ville)
>
> Signed-off-by: Ben Widawsky <ben@bwidawsk.net>
> ---
> drivers/gpu/drm/i915/i915_drv.h | 1 +
> drivers/gpu/drm/i915/i915_gpu_error.c | 52 ++++++++++++++++++++++++++++++---
> drivers/gpu/drm/i915/intel_ringbuffer.h | 12 ++++----
> 3 files changed, 55 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 028ce5a..9b86874 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -322,6 +322,7 @@ struct drm_i915_error_state {
> u64 fence[I915_MAX_NUM_FENCES];
> struct intel_overlay_error_state *overlay;
> struct intel_display_error_state *display;
> + struct drm_i915_error_object *semaphore_obj;
>
> struct drm_i915_error_ring {
> bool valid;
> diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c
> index 2b64493..25fc2ea 100644
> --- a/drivers/gpu/drm/i915/i915_gpu_error.c
> +++ b/drivers/gpu/drm/i915/i915_gpu_error.c
> @@ -310,6 +310,7 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m,
> struct drm_device *dev = error_priv->dev;
> drm_i915_private_t *dev_priv = dev->dev_private;
> struct drm_i915_error_state *error = error_priv->error;
> + struct drm_i915_error_object *obj;
> int i, j, page, offset, elt;
>
> if (!error) {
> @@ -360,8 +361,6 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m,
> error->pinned_bo_count[0]);
>
> for (i = 0; i < ARRAY_SIZE(error->ring); i++) {
> - struct drm_i915_error_object *obj;
> -
> if ((obj = error->ring[i].batchbuffer)) {
> err_printf(m, "%s --- gtt_offset = 0x%08x\n",
> dev_priv->ring[i].name,
> @@ -436,6 +435,19 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m,
> }
> }
>
> + obj = error->semaphore_obj;
> + if (obj) {
Still won't pass under Chris's consitency radar.
> + err_printf(m, "Semaphore page = 0x%08x\n", obj->gtt_offset);
> + for (elt = 0; elt < PAGE_SIZE/16; elt += 4) {
> + err_printf(m, "[%04x] %08x %08x %08x %08x\n",
> + elt * 4,
> + obj->pages[0][elt],
> + obj->pages[0][elt+1],
> + obj->pages[0][elt+2],
> + obj->pages[0][elt+3]);
> + }
> + }
> +
> if (error->overlay)
> intel_overlay_print_error_state(m, error->overlay);
>
> @@ -506,6 +518,7 @@ static void i915_error_state_free(struct kref *error_ref)
> kfree(error->ring[i].requests);
> }
>
> + i915_error_object_free(error->semaphore_obj);
> kfree(error->active_bo);
> kfree(error->overlay);
> kfree(error->display);
> @@ -797,6 +810,33 @@ i915_error_first_batchbuffer(struct drm_i915_private *dev_priv,
> return NULL;
> }
>
> +static void gen8_record_semaphore_state(struct drm_i915_private *dev_priv,
> + struct drm_i915_error_state *error,
> + struct intel_ring_buffer *ring,
> + struct drm_i915_error_ring *ering)
> +{
> + struct intel_ring_buffer *useless;
> + int i;
> +
> + if (!i915_semaphore_is_enabled(dev_priv->dev))
> + return;
> +
> + if (!error->semaphore_obj)
> + error->semaphore_obj =
> + i915_error_object_create(dev_priv,
> + dev_priv->semaphore_obj,
> + &dev_priv->gtt.base);
> +
> + for_each_ring(useless, dev_priv, i) {
> + u16 signal_offset =
> + (GEN8_SIGNAL_OFFSET(ring, i) / 4) & PAGE_MASK;
(... & PAGE_MASK) / 4;
> + u32 *tmp = error->semaphore_obj->pages[0];
> +
> + ering->semaphore_mboxes[i] = tmp[signal_offset];
> + ering->semaphore_seqno[i] = ring->semaphore.sync_seqno[i];
> + }
> +}
> +
> static void gen6_record_semaphore_state(struct drm_i915_private *dev_priv,
> struct intel_ring_buffer *ring,
> struct drm_i915_error_ring *ering)
> @@ -814,6 +854,7 @@ static void gen6_record_semaphore_state(struct drm_i915_private *dev_priv,
> }
>
> static void i915_record_ring_state(struct drm_device *dev,
> + struct drm_i915_error_state *error,
> struct intel_ring_buffer *ring,
> struct drm_i915_error_ring *ering)
> {
> @@ -822,7 +863,10 @@ static void i915_record_ring_state(struct drm_device *dev,
> if (INTEL_INFO(dev)->gen >= 6) {
> ering->rc_psmi = I915_READ(ring->mmio_base + 0x50);
> ering->fault_reg = I915_READ(RING_FAULT_REG(ring));
> - gen6_record_semaphore_state(dev_priv, ring, ering);
> + if (INTEL_INFO(dev)->gen >= 8)
> + gen8_record_semaphore_state(dev_priv, error, ring, ering);
> + else
> + gen6_record_semaphore_state(dev_priv, ring, ering);
> }
>
> if (INTEL_INFO(dev)->gen >= 4) {
> @@ -948,7 +992,7 @@ static void i915_gem_record_rings(struct drm_device *dev,
>
> error->ring[i].valid = true;
>
> - i915_record_ring_state(dev, ring, &error->ring[i]);
> + i915_record_ring_state(dev, error, ring, &error->ring[i]);
>
> error->ring[i].batchbuffer =
> i915_error_first_batchbuffer(dev_priv, ring);
> diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
> index 5d56c95..01aad54 100644
> --- a/drivers/gpu/drm/i915/intel_ringbuffer.h
> +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
> @@ -37,9 +37,9 @@ struct intel_hw_status_page {
> * do the writes, and that must have qw aligned offsets, simply pretend it's 8b.
> */
> #define i915_semaphore_seqno_size sizeof(uint64_t)
> -#define GEN8_SIGNAL_OFFSET(to) \
> +#define GEN8_SIGNAL_OFFSET(__ring, to) \
> (i915_gem_obj_ggtt_offset(dev_priv->semaphore_obj) + \
> - (ring->id * I915_NUM_RINGS * i915_semaphore_seqno_size) + \
> + ((__ring)->id * I915_NUM_RINGS * i915_semaphore_seqno_size) + \
> (i915_semaphore_seqno_size * (to)))
>
> #define GEN8_WAIT_OFFSET(__ring, from) \
> @@ -51,10 +51,10 @@ struct intel_hw_status_page {
> if (!dev_priv->semaphore_obj) { \
> break; \
> } \
> - ring->semaphore.signal_ggtt[RCS] = GEN8_SIGNAL_OFFSET(RCS); \
> - ring->semaphore.signal_ggtt[VCS] = GEN8_SIGNAL_OFFSET(VCS); \
> - ring->semaphore.signal_ggtt[BCS] = GEN8_SIGNAL_OFFSET(BCS); \
> - ring->semaphore.signal_ggtt[VECS] = GEN8_SIGNAL_OFFSET(VECS); \
> + ring->semaphore.signal_ggtt[RCS] = GEN8_SIGNAL_OFFSET(ring, RCS); \
> + ring->semaphore.signal_ggtt[VCS] = GEN8_SIGNAL_OFFSET(ring, VCS); \
> + ring->semaphore.signal_ggtt[BCS] = GEN8_SIGNAL_OFFSET(ring, BCS); \
> + ring->semaphore.signal_ggtt[VECS] = GEN8_SIGNAL_OFFSET(ring, VECS); \
> ring->semaphore.signal_ggtt[ring->id] = MI_SEMAPHORE_SYNC_INVALID; \
> } while(0)
>
> --
> 1.9.0
--
Ville Syrjälä
Intel OTC
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 04/13] drm/i915: Make semaphore updates more precise
2014-02-20 6:19 ` [PATCH 04/13] drm/i915: Make semaphore updates more precise Ben Widawsky
@ 2014-02-24 13:09 ` Ville Syrjälä
0 siblings, 0 replies; 23+ messages in thread
From: Ville Syrjälä @ 2014-02-24 13:09 UTC (permalink / raw)
To: Ben Widawsky; +Cc: Intel GFX, Ben Widawsky
On Wed, Feb 19, 2014 at 10:19:17PM -0800, Ben Widawsky wrote:
> With the ring mask we now have an easy way to know the number of rings
> in the system, and therefore can accurately predict the number of dwords
> to emit for semaphore signalling. This was not possible (easily)
> previously.
>
> There should be no functional impact, simply fewer instructions emitted.
>
> While we're here, simply do the round up to 2 instead of the fancier
> rounding we did before, which rounding up per mbox, ie 4. This also
> allows us to drop the unnecessary MI_NOOP, so not really 4, 3.
>
> v2: Use 3 dwords instead of 4 (Ville)
> Do the proper calculation to get the number of dwords to emit (Ville)
> Conditionally set .sync_to when semaphores are enabled (Ville)
>
> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Signed-off-by: Ben Widawsky <ben@bwidawsk.net>
> ---
> drivers/gpu/drm/i915/intel_ringbuffer.c | 119 +++++++++++++++++---------------
> 1 file changed, 62 insertions(+), 57 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
> index 06d849a..bf061dd 100644
> --- a/drivers/gpu/drm/i915/intel_ringbuffer.c
> +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
> @@ -637,24 +637,19 @@ static void render_ring_cleanup(struct intel_ring_buffer *ring)
> static int gen6_signal(struct intel_ring_buffer *signaller,
> unsigned int num_dwords)
> {
> +#define MBOX_UPDATE_DWORDS 3
> struct drm_device *dev = signaller->dev;
> struct drm_i915_private *dev_priv = dev->dev_private;
> struct intel_ring_buffer *useless;
> - int i, ret;
> + int i, ret, num_rings;
>
> - /* NB: In order to be able to do semaphore MBOX updates for varying
> - * number of rings, it's easiest if we round up each individual update
> - * to a multiple of 2 (since ring updates must always be a multiple of
> - * 2) even though the actual update only requires 3 dwords.
> - */
> -#define MBOX_UPDATE_DWORDS 4
> - if (i915_semaphore_is_enabled(dev))
> - num_dwords += ((I915_NUM_RINGS-1) * MBOX_UPDATE_DWORDS);
> + num_rings = hweight_long(INTEL_INFO(dev)->ring_mask);
hweight32() would be enough.
<snip>
--
Ville Syrjälä
Intel OTC
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 06/13] drm/i915/bdw: implement semaphore signal
2014-02-20 6:19 ` [PATCH 06/13] drm/i915/bdw: implement semaphore signal Ben Widawsky
@ 2014-02-24 13:10 ` Ville Syrjälä
2014-03-05 12:24 ` Ville Syrjälä
0 siblings, 1 reply; 23+ messages in thread
From: Ville Syrjälä @ 2014-02-24 13:10 UTC (permalink / raw)
To: Ben Widawsky; +Cc: Intel GFX, Ben Widawsky
On Wed, Feb 19, 2014 at 10:19:19PM -0800, Ben Widawsky wrote:
<snip>
> @@ -634,6 +641,85 @@ static void render_ring_cleanup(struct intel_ring_buffer *ring)
> ring->scratch.obj = NULL;
> }
>
> +static int gen8_rcs_signal(struct intel_ring_buffer *signaller,
> + unsigned int num_dwords)
> +{
> +#define MBOX_UPDATE_DWORDS 8
> + struct drm_device *dev = signaller->dev;
> + struct drm_i915_private *dev_priv = dev->dev_private;
> + struct intel_ring_buffer *waiter;
> + int i, ret, num_rings;
> +
> + num_rings = hweight_long(INTEL_INFO(dev)->ring_mask);
Again hweight32() would be enough.
<snip>
--
Ville Syrjälä
Intel OTC
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 06/13] drm/i915/bdw: implement semaphore signal
2014-02-24 13:10 ` Ville Syrjälä
@ 2014-03-05 12:24 ` Ville Syrjälä
0 siblings, 0 replies; 23+ messages in thread
From: Ville Syrjälä @ 2014-03-05 12:24 UTC (permalink / raw)
To: Ben Widawsky; +Cc: Intel GFX, Ben Widawsky
On Mon, Feb 24, 2014 at 03:10:26PM +0200, Ville Syrjälä wrote:
> On Wed, Feb 19, 2014 at 10:19:19PM -0800, Ben Widawsky wrote:
> <snip>
> > @@ -634,6 +641,85 @@ static void render_ring_cleanup(struct intel_ring_buffer *ring)
> > ring->scratch.obj = NULL;
> > }
> >
> > +static int gen8_rcs_signal(struct intel_ring_buffer *signaller,
> > + unsigned int num_dwords)
> > +{
> > +#define MBOX_UPDATE_DWORDS 8
> > + struct drm_device *dev = signaller->dev;
> > + struct drm_i915_private *dev_priv = dev->dev_private;
> > + struct intel_ring_buffer *waiter;
> > + int i, ret, num_rings;
> > +
> > + num_rings = hweight_long(INTEL_INFO(dev)->ring_mask);
>
> Again hweight32() would be enough.
And I noticed there's even a hweight8() if we want to micro optimize,
but I don't really care that much, so even leaving these as hweight_long()
is fine by me.
--
Ville Syrjälä
Intel OTC
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 01/13] drm/i915: Move semaphore specific ring members to struct
2014-02-20 6:19 [PATCH 01/13] drm/i915: Move semaphore specific ring members to struct Ben Widawsky
` (11 preceding siblings ...)
2014-02-20 6:19 ` [PATCH 13/13] DONT_MERGE drm/i915: FORCE_RESTORE for gen8 semaphores Ben Widawsky
@ 2014-03-05 12:29 ` Ville Syrjälä
12 siblings, 0 replies; 23+ messages in thread
From: Ville Syrjälä @ 2014-03-05 12:29 UTC (permalink / raw)
To: Ben Widawsky; +Cc: Intel GFX, Ben Widawsky
Looks like I neglected to give any kind of final conclusion on this series.
It looks like it should do the right thing, apart from the PAGE_MASK vs.
/4 bug. The other things I commented on were just minor nits. And if we
drop the poll and force restore patches, I'm happy with the result ;)
--
Ville Syrjälä
Intel OTC
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 10/13] drm/i915/bdw: collect semaphore error state
2014-02-24 13:08 ` Ville Syrjälä
@ 2014-04-29 21:43 ` Ben Widawsky
0 siblings, 0 replies; 23+ messages in thread
From: Ben Widawsky @ 2014-04-29 21:43 UTC (permalink / raw)
To: Ville Syrjälä; +Cc: Intel GFX, Ben Widawsky
On Mon, Feb 24, 2014 at 03:08:04PM +0200, Ville Syrjälä wrote:
> On Wed, Feb 19, 2014 at 10:19:23PM -0800, Ben Widawsky wrote:
> > Since the semaphore information is in an object, just dump it, and let
> > the user parse it later.
> >
> > NOTE: The page being used for the semaphores are incoherent with the
> > CPU. No matter what I do, I cannot figure out a way to read anything but
> > 0s. Note that the semaphore waits are indeed working.
> >
> > v2: Don't print signal, and wait (they should be the same). Instead,
> > print sync_seqno (Chris)
> >
> > v3: Free the semaphore error object (Chris)
> >
> > v4: Fix semaphore offset calculation during error state collection
> > (Ville)
> >
> > Signed-off-by: Ben Widawsky <ben@bwidawsk.net>
> > ---
> > drivers/gpu/drm/i915/i915_drv.h | 1 +
> > drivers/gpu/drm/i915/i915_gpu_error.c | 52 ++++++++++++++++++++++++++++++---
> > drivers/gpu/drm/i915/intel_ringbuffer.h | 12 ++++----
> > 3 files changed, 55 insertions(+), 10 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> > index 028ce5a..9b86874 100644
> > --- a/drivers/gpu/drm/i915/i915_drv.h
> > +++ b/drivers/gpu/drm/i915/i915_drv.h
> > @@ -322,6 +322,7 @@ struct drm_i915_error_state {
> > u64 fence[I915_MAX_NUM_FENCES];
> > struct intel_overlay_error_state *overlay;
> > struct intel_display_error_state *display;
> > + struct drm_i915_error_object *semaphore_obj;
> >
> > struct drm_i915_error_ring {
> > bool valid;
> > diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c
> > index 2b64493..25fc2ea 100644
> > --- a/drivers/gpu/drm/i915/i915_gpu_error.c
> > +++ b/drivers/gpu/drm/i915/i915_gpu_error.c
> > @@ -310,6 +310,7 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m,
> > struct drm_device *dev = error_priv->dev;
> > drm_i915_private_t *dev_priv = dev->dev_private;
> > struct drm_i915_error_state *error = error_priv->error;
> > + struct drm_i915_error_object *obj;
> > int i, j, page, offset, elt;
> >
> > if (!error) {
> > @@ -360,8 +361,6 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m,
> > error->pinned_bo_count[0]);
> >
> > for (i = 0; i < ARRAY_SIZE(error->ring); i++) {
> > - struct drm_i915_error_object *obj;
> > -
> > if ((obj = error->ring[i].batchbuffer)) {
> > err_printf(m, "%s --- gtt_offset = 0x%08x\n",
> > dev_priv->ring[i].name,
> > @@ -436,6 +435,19 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m,
> > }
> > }
> >
> > + obj = error->semaphore_obj;
> > + if (obj) {
>
> Still won't pass under Chris's consitency radar.
>
> > + err_printf(m, "Semaphore page = 0x%08x\n", obj->gtt_offset);
> > + for (elt = 0; elt < PAGE_SIZE/16; elt += 4) {
> > + err_printf(m, "[%04x] %08x %08x %08x %08x\n",
> > + elt * 4,
> > + obj->pages[0][elt],
> > + obj->pages[0][elt+1],
> > + obj->pages[0][elt+2],
> > + obj->pages[0][elt+3]);
> > + }
> > + }
> > +
> > if (error->overlay)
> > intel_overlay_print_error_state(m, error->overlay);
> >
> > @@ -506,6 +518,7 @@ static void i915_error_state_free(struct kref *error_ref)
> > kfree(error->ring[i].requests);
> > }
> >
> > + i915_error_object_free(error->semaphore_obj);
> > kfree(error->active_bo);
> > kfree(error->overlay);
> > kfree(error->display);
> > @@ -797,6 +810,33 @@ i915_error_first_batchbuffer(struct drm_i915_private *dev_priv,
> > return NULL;
> > }
> >
> > +static void gen8_record_semaphore_state(struct drm_i915_private *dev_priv,
> > + struct drm_i915_error_state *error,
> > + struct intel_ring_buffer *ring,
> > + struct drm_i915_error_ring *ering)
> > +{
> > + struct intel_ring_buffer *useless;
> > + int i;
> > +
> > + if (!i915_semaphore_is_enabled(dev_priv->dev))
> > + return;
> > +
> > + if (!error->semaphore_obj)
> > + error->semaphore_obj =
> > + i915_error_object_create(dev_priv,
> > + dev_priv->semaphore_obj,
> > + &dev_priv->gtt.base);
> > +
> > + for_each_ring(useless, dev_priv, i) {
> > + u16 signal_offset =
> > + (GEN8_SIGNAL_OFFSET(ring, i) / 4) & PAGE_MASK;
>
> (... & PAGE_MASK) / 4;
>
Nice catch.
> > + u32 *tmp = error->semaphore_obj->pages[0];
> > +
> > + ering->semaphore_mboxes[i] = tmp[signal_offset];
> > + ering->semaphore_seqno[i] = ring->semaphore.sync_seqno[i];
> > + }
> > +}
> > +
> > static void gen6_record_semaphore_state(struct drm_i915_private *dev_priv,
> > struct intel_ring_buffer *ring,
> > struct drm_i915_error_ring *ering)
> > @@ -814,6 +854,7 @@ static void gen6_record_semaphore_state(struct drm_i915_private *dev_priv,
> > }
> >
> > static void i915_record_ring_state(struct drm_device *dev,
> > + struct drm_i915_error_state *error,
> > struct intel_ring_buffer *ring,
> > struct drm_i915_error_ring *ering)
> > {
> > @@ -822,7 +863,10 @@ static void i915_record_ring_state(struct drm_device *dev,
> > if (INTEL_INFO(dev)->gen >= 6) {
> > ering->rc_psmi = I915_READ(ring->mmio_base + 0x50);
> > ering->fault_reg = I915_READ(RING_FAULT_REG(ring));
> > - gen6_record_semaphore_state(dev_priv, ring, ering);
> > + if (INTEL_INFO(dev)->gen >= 8)
> > + gen8_record_semaphore_state(dev_priv, error, ring, ering);
> > + else
> > + gen6_record_semaphore_state(dev_priv, ring, ering);
> > }
> >
> > if (INTEL_INFO(dev)->gen >= 4) {
> > @@ -948,7 +992,7 @@ static void i915_gem_record_rings(struct drm_device *dev,
> >
> > error->ring[i].valid = true;
> >
> > - i915_record_ring_state(dev, ring, &error->ring[i]);
> > + i915_record_ring_state(dev, error, ring, &error->ring[i]);
> >
> > error->ring[i].batchbuffer =
> > i915_error_first_batchbuffer(dev_priv, ring);
> > diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
> > index 5d56c95..01aad54 100644
> > --- a/drivers/gpu/drm/i915/intel_ringbuffer.h
> > +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
> > @@ -37,9 +37,9 @@ struct intel_hw_status_page {
> > * do the writes, and that must have qw aligned offsets, simply pretend it's 8b.
> > */
> > #define i915_semaphore_seqno_size sizeof(uint64_t)
> > -#define GEN8_SIGNAL_OFFSET(to) \
> > +#define GEN8_SIGNAL_OFFSET(__ring, to) \
> > (i915_gem_obj_ggtt_offset(dev_priv->semaphore_obj) + \
> > - (ring->id * I915_NUM_RINGS * i915_semaphore_seqno_size) + \
> > + ((__ring)->id * I915_NUM_RINGS * i915_semaphore_seqno_size) + \
> > (i915_semaphore_seqno_size * (to)))
> >
> > #define GEN8_WAIT_OFFSET(__ring, from) \
> > @@ -51,10 +51,10 @@ struct intel_hw_status_page {
> > if (!dev_priv->semaphore_obj) { \
> > break; \
> > } \
> > - ring->semaphore.signal_ggtt[RCS] = GEN8_SIGNAL_OFFSET(RCS); \
> > - ring->semaphore.signal_ggtt[VCS] = GEN8_SIGNAL_OFFSET(VCS); \
> > - ring->semaphore.signal_ggtt[BCS] = GEN8_SIGNAL_OFFSET(BCS); \
> > - ring->semaphore.signal_ggtt[VECS] = GEN8_SIGNAL_OFFSET(VECS); \
> > + ring->semaphore.signal_ggtt[RCS] = GEN8_SIGNAL_OFFSET(ring, RCS); \
> > + ring->semaphore.signal_ggtt[VCS] = GEN8_SIGNAL_OFFSET(ring, VCS); \
> > + ring->semaphore.signal_ggtt[BCS] = GEN8_SIGNAL_OFFSET(ring, BCS); \
> > + ring->semaphore.signal_ggtt[VECS] = GEN8_SIGNAL_OFFSET(ring, VECS); \
> > ring->semaphore.signal_ggtt[ring->id] = MI_SEMAPHORE_SYNC_INVALID; \
> > } while(0)
> >
> > --
> > 1.9.0
>
> --
> Ville Syrjälä
> Intel OTC
--
Ben Widawsky, Intel Open Source Technology Center
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH 02/13] drm/i915: Virtualize the ringbuffer signal func
2014-04-29 21:52 [PATCH 00/13] [REPOST] BDW Semaphores Ben Widawsky
@ 2014-04-29 21:52 ` Ben Widawsky
0 siblings, 0 replies; 23+ messages in thread
From: Ben Widawsky @ 2014-04-29 21:52 UTC (permalink / raw)
To: Intel GFX
This abstraction again is in preparation for gen8. Gen8 will bring new
semantics for doing this operation.
While here, make the writes of MI_NOOPs explicit for non-existent rings.
This should have been implicit before.
NOTE: This is going to be removed in a few patches.
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Ben Widawsky <ben@bwidawsk.net>
---
drivers/gpu/drm/i915/intel_ringbuffer.c | 42 ++++++++++++++++++++-------------
drivers/gpu/drm/i915/intel_ringbuffer.h | 11 +++++----
2 files changed, 32 insertions(+), 21 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index 3076a99..ea81b54 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -663,20 +663,32 @@ static void render_ring_cleanup(struct intel_ring_buffer *ring)
ring->scratch.obj = NULL;
}
-static void
-update_mboxes(struct intel_ring_buffer *ring,
- u32 mmio_offset)
+static void gen6_signal(struct intel_ring_buffer *signaller)
{
+ struct drm_i915_private *dev_priv = signaller->dev->dev_private;
+ struct intel_ring_buffer *useless;
+ int i;
+
/* NB: In order to be able to do semaphore MBOX updates for varying number
* of rings, it's easiest if we round up each individual update to a
* multiple of 2 (since ring updates must always be a multiple of 2)
* even though the actual update only requires 3 dwords.
*/
#define MBOX_UPDATE_DWORDS 4
- intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1));
- intel_ring_emit(ring, mmio_offset);
- intel_ring_emit(ring, ring->outstanding_lazy_seqno);
- intel_ring_emit(ring, MI_NOOP);
+ for_each_ring(useless, dev_priv, i) {
+ u32 mbox_reg = signaller->semaphore.mbox.signal[i];
+ if (mbox_reg != GEN6_NOSYNC) {
+ intel_ring_emit(signaller, MI_LOAD_REGISTER_IMM(1));
+ intel_ring_emit(signaller, mbox_reg);
+ intel_ring_emit(signaller, signaller->outstanding_lazy_seqno);
+ intel_ring_emit(signaller, MI_NOOP);
+ } else {
+ intel_ring_emit(signaller, MI_NOOP);
+ intel_ring_emit(signaller, MI_NOOP);
+ intel_ring_emit(signaller, MI_NOOP);
+ intel_ring_emit(signaller, MI_NOOP);
+ }
+ }
}
/**
@@ -692,9 +704,7 @@ static int
gen6_add_request(struct intel_ring_buffer *ring)
{
struct drm_device *dev = ring->dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_ring_buffer *useless;
- int i, ret, num_dwords = 4;
+ int ret, num_dwords = 4;
if (i915_semaphore_is_enabled(dev))
num_dwords += ((I915_NUM_RINGS-1) * MBOX_UPDATE_DWORDS);
@@ -704,13 +714,7 @@ gen6_add_request(struct intel_ring_buffer *ring)
if (ret)
return ret;
- if (i915_semaphore_is_enabled(dev)) {
- for_each_ring(useless, dev_priv, i) {
- u32 mbox_reg = ring->semaphore.mbox.signal[i];
- if (mbox_reg != GEN6_NOSYNC)
- update_mboxes(ring, mbox_reg);
- }
- }
+ ring->semaphore.signal(ring);
intel_ring_emit(ring, MI_STORE_DWORD_INDEX);
intel_ring_emit(ring, I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
@@ -1920,6 +1924,7 @@ int intel_init_render_ring_buffer(struct drm_device *dev)
ring->get_seqno = gen6_ring_get_seqno;
ring->set_seqno = ring_set_seqno;
ring->semaphore.sync_to = gen6_ring_sync;
+ ring->semaphore.signal = gen6_signal;
/*
* The current semaphore is only applied on pre-gen8 platform.
* And there is no VCS2 ring on the pre-gen8 platform. So the
@@ -2104,6 +2109,7 @@ int intel_init_bsd_ring_buffer(struct drm_device *dev)
gen6_ring_dispatch_execbuffer;
}
ring->semaphore.sync_to = gen6_ring_sync;
+ ring->semaphore.signal = gen6_signal;
/*
* The current semaphore is only applied on pre-gen8 platform.
* And there is no VCS2 ring on the pre-gen8 platform. So the
@@ -2221,6 +2227,7 @@ int intel_init_blt_ring_buffer(struct drm_device *dev)
ring->dispatch_execbuffer = gen6_ring_dispatch_execbuffer;
}
ring->semaphore.sync_to = gen6_ring_sync;
+ ring->semaphore.signal = gen6_signal;
/*
* The current semaphore is only applied on pre-gen8 platform. And
* there is no VCS2 ring on the pre-gen8 platform. So the semaphore
@@ -2270,6 +2277,7 @@ int intel_init_vebox_ring_buffer(struct drm_device *dev)
ring->dispatch_execbuffer = gen6_ring_dispatch_execbuffer;
}
ring->semaphore.sync_to = gen6_ring_sync;
+ ring->semaphore.signal = gen6_signal;
ring->semaphore.mbox.wait[RCS] = MI_SEMAPHORE_SYNC_VER;
ring->semaphore.mbox.wait[VCS] = MI_SEMAPHORE_SYNC_VEV;
ring->semaphore.mbox.wait[BCS] = MI_SEMAPHORE_SYNC_VEB;
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
index 6a44a64..830ff26 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -120,16 +120,19 @@ struct intel_ring_buffer {
struct {
u32 sync_seqno[I915_NUM_RINGS-1];
- /* AKA wait() */
- int (*sync_to)(struct intel_ring_buffer *ring,
- struct intel_ring_buffer *to,
- u32 seqno);
+
struct {
/* our mbox written by others */
u32 wait[I915_NUM_RINGS];
/* mboxes this ring signals to */
u32 signal[I915_NUM_RINGS];
} mbox;
+
+ /* AKA wait() */
+ int (*sync_to)(struct intel_ring_buffer *ring,
+ struct intel_ring_buffer *to,
+ u32 seqno);
+ void (*signal)(struct intel_ring_buffer *signaller);
} semaphore;
/**
--
1.9.2
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 23+ messages in thread
end of thread, other threads:[~2014-04-29 21:52 UTC | newest]
Thread overview: 23+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-02-20 6:19 [PATCH 01/13] drm/i915: Move semaphore specific ring members to struct Ben Widawsky
2014-02-20 6:19 ` [PATCH 02/13] drm/i915: Virtualize the ringbuffer signal func Ben Widawsky
2014-02-20 6:19 ` [PATCH 03/13] drm/i915: Move ring_begin to signal() Ben Widawsky
2014-02-20 6:19 ` [PATCH 04/13] drm/i915: Make semaphore updates more precise Ben Widawsky
2014-02-24 13:09 ` Ville Syrjälä
2014-02-20 6:19 ` [PATCH 05/13] drm/i915: gen specific ring init Ben Widawsky
2014-02-24 13:05 ` Ville Syrjälä
2014-02-20 6:19 ` [PATCH 06/13] drm/i915/bdw: implement semaphore signal Ben Widawsky
2014-02-24 13:10 ` Ville Syrjälä
2014-03-05 12:24 ` Ville Syrjälä
2014-02-20 6:19 ` [PATCH 07/13] drm/i915/bdw: implement semaphore wait Ben Widawsky
2014-02-20 6:19 ` [PATCH 08/13] drm/i915/bdw: poll semaphores Ben Widawsky
2014-02-24 13:06 ` Ville Syrjälä
2014-02-20 6:19 ` [PATCH 09/13] drm/i915: Extract semaphore error collection Ben Widawsky
2014-02-20 6:19 ` [PATCH 10/13] drm/i915/bdw: collect semaphore error state Ben Widawsky
2014-02-24 13:08 ` Ville Syrjälä
2014-04-29 21:43 ` Ben Widawsky
2014-02-20 6:19 ` [PATCH 11/13] drm/i915: unleash semaphores on gen8 Ben Widawsky
2014-02-20 6:19 ` [PATCH 12/13] drm/i915: semaphore debugfs Ben Widawsky
2014-02-20 6:19 ` [PATCH 13/13] DONT_MERGE drm/i915: FORCE_RESTORE for gen8 semaphores Ben Widawsky
2014-03-05 12:29 ` [PATCH 01/13] drm/i915: Move semaphore specific ring members to struct Ville Syrjälä
-- strict thread matches above, loose matches on Subject: below --
2014-04-29 21:52 [PATCH 00/13] [REPOST] BDW Semaphores Ben Widawsky
2014-04-29 21:52 ` [PATCH 02/13] drm/i915: Virtualize the ringbuffer signal func Ben Widawsky
2014-01-29 19:55 [PATCH 00/13] [REPOST] Broadwell HW semaphores Ben Widawsky
2014-01-29 19:55 ` [PATCH 02/13] drm/i915: Virtualize the ringbuffer signal func Ben Widawsky
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox