Re: [Intel-gfx] More crashes with intel driver 1.10.4 and corrupted stack traces for GM45
On Tue, 13 Dec 2011 19:05:34 -0800, Marc MERLIN marc_x...@merlins.org wrote: Since I'm a newbie at thie, there isn't a 'head' per se, and I see that not all patches are production ready. Could you point me on what I could sync from and that would be reasonably likely to work? :) If you checkout the master branch of both git://anongit.freedesktop.org/mesa/drm and git://anongit.freedesktop.org/xorg/driver/xf86-video-intel You should have a working driver. -Chris -- Chris Wilson, Intel Open Source Technology Centre ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH] uxa/glamor: Enable the rest glamor rendering functions.
On Wed, 14 Dec 2011 12:08:30 +0800, Zhigang Gong zhigang.g...@linux.intel.com wrote: -Original Message- From: Chris Wilson [mailto:ch...@chris-wilson.co.uk] Sent: Wednesday, December 14, 2011 2:45 AM To: zhigang.g...@linux.intel.com Cc: intel-gfx@lists.freedesktop.org; zhigang.g...@gmail.com; zhigang.g...@linux.intel.com Subject: Re: [PATCH] uxa/glamor: Enable the rest glamor rendering functions. On Tue, 13 Dec 2011 22:31:41 +0800, zhigang.g...@linux.intel.com wrote: From: Zhigang Gong zhigang.g...@linux.intel.com This commit enable all the rest glamor rendering functions. Tested with latest glamor master branch, can pass rendercheck. Hmm, it exposes an issue with keeping a bo cache independent of mesa and trying to feed it our own handles: Region for name 6 already exists but is not compatible The w/a for this would be: diff --git a/src/intel_glamor.c b/src/intel_glamor.c index 0cf8ed7..2757fd6 100644 --- a/src/intel_glamor.c +++ b/src/intel_glamor.c @@ -91,6 +91,7 @@ intel_glamor_create_textured_pixmap(PixmapPtr pixmap) priv = intel_get_pixmap_private(pixmap); if (glamor_egl_create_textured_pixmap(pixmap, priv-bo-handle, priv-stride)) { + drm_intel_bo_disable_reuse(priv-bo); priv-pinned = 1; return TRUE; } else but that gives up all pretense of maintaining a bo cache. Yes, I think this impacts the performance. Actually, I noticed this problem and I spent some time to track the root cause. If everything is ok, this error should not be triggered. Although the same BO maybe reused to create a new pixmap, the previous pixmap which own this BO should be already destroyed. And the previous image created with the previous pixmap should be destroyed either. Certainly it looks like glamor is taking all necessary steps to decouple the bo from the textures and renderbuffer upon pixmap finish. There is one other potential race here in that the ddx will mark the bo as purgeable as soon as it releases it back to the cache, but it may not yet have been submitted by mesa in its execbuffer. The kernel may choose to free the memory associated with the bo before that happens, and may rightfully complain the userspace is doing something silly. And then, when we create a new pixmap/image with this BO, MESA should not find any exist image/region for this BO. But it does happen. I tracked further into mesa internal and found that the previous image was not destroyed when we call eglDestroyImageKHR, as its reference count is decreased to zero. It's weird for me. Further tracking shows that the root cause is when I use the texture(bind to the image) as a shader's source texture, and call glDrawArrays to perform the rendering, the texture's reference count will be increased by 1 before return from glDrawArrays. And I failed to find any API to decrease it. Then this texture can't be freed when destroy that texture and thus the image's reference count will also remain 1 and can't be freed either. I'm looking at update_texture_state() which appears to hold onto a reference to the texobj until its slot is reused. If the object is simply destroyed and the unit disabled, the slot is skipped and the old reference remains. _mesa_update_state (which calls into update_texture_state) would seem to be only invoked upon a draw primitives. Binding a dummy texture/fb and doing a dummy render might be a little extreme as a workaround! -Chris -- Chris Wilson, Intel Open Source Technology Centre ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH] uxa/glamor: Enable the rest glamor rendering functions.
-Original Message- From: Chris Wilson [mailto:ch...@chris-wilson.co.uk] Sent: Wednesday, December 14, 2011 7:12 PM To: Zhigang Gong Cc: intel-gfx@lists.freedesktop.org; zhigang.g...@gmail.com Subject: RE: [PATCH] uxa/glamor: Enable the rest glamor rendering functions. On Wed, 14 Dec 2011 12:08:30 +0800, Zhigang Gong zhigang.g...@linux.intel.com wrote: -Original Message- From: Chris Wilson [mailto:ch...@chris-wilson.co.uk] Sent: Wednesday, December 14, 2011 2:45 AM To: zhigang.g...@linux.intel.com Cc: intel-gfx@lists.freedesktop.org; zhigang.g...@gmail.com; zhigang.g...@linux.intel.com Subject: Re: [PATCH] uxa/glamor: Enable the rest glamor rendering functions. On Tue, 13 Dec 2011 22:31:41 +0800, zhigang.g...@linux.intel.com wrote: From: Zhigang Gong zhigang.g...@linux.intel.com This commit enable all the rest glamor rendering functions. Tested with latest glamor master branch, can pass rendercheck. Hmm, it exposes an issue with keeping a bo cache independent of mesa and trying to feed it our own handles: Region for name 6 already exists but is not compatible The w/a for this would be: diff --git a/src/intel_glamor.c b/src/intel_glamor.c index 0cf8ed7..2757fd6 100644 --- a/src/intel_glamor.c +++ b/src/intel_glamor.c @@ -91,6 +91,7 @@ intel_glamor_create_textured_pixmap(PixmapPtr pixmap) priv = intel_get_pixmap_private(pixmap); if (glamor_egl_create_textured_pixmap(pixmap, priv-bo-handle, priv-stride)) { + drm_intel_bo_disable_reuse(priv-bo); priv-pinned = 1; return TRUE; } else but that gives up all pretense of maintaining a bo cache. Yes, I think this impacts the performance. Actually, I noticed this problem and I spent some time to track the root cause. If everything is ok, this error should not be triggered. Although the same BO maybe reused to create a new pixmap, the previous pixmap which own this BO should be already destroyed. And the previous image created with the previous pixmap should be destroyed either. Certainly it looks like glamor is taking all necessary steps to decouple the bo from the textures and renderbuffer upon pixmap finish. There is one other potential race here in that the ddx will mark the bo as purgeable as soon as it releases it back to the cache, but it may not yet have been submitted by mesa in its execbuffer. The kernel may choose to free the memory associated with the bo before that happens, and may rightfully complain the userspace is doing something silly. Right, we do have this race if the kernel free the BO's memory prior to The mesa submit its execbuffer. Hmm. But I think that may not be a real problem, as once we call intel_set_pixmap_bo(pixmap, NULL) to unlink the bo from the pixmap, the BO will not be released at DRM layer immediately, instead, it will be put on a in_flight list. And intel_batch_submit will empty the list, considering after switching to glamor, each pixmap's batch buffer should be empty, then the driver will only call intel_batch_submit at intel_flush_rendering which is called from intel_uxa_block_handler and is after the intel_glamor_flush. At intel_glamor_flush, it will do a glFlush, my understanding is glFlush should make sure the execbuffer was submitted to GPU. But I'm not very sure. Can you confirm that? Thanks. And then, when we create a new pixmap/image with this BO, MESA should not find any exist image/region for this BO. But it does happen. I tracked further into mesa internal and found that the previous image was not destroyed when we call eglDestroyImageKHR, as its reference count is decreased to zero. It's weird for me. Further tracking shows that the root cause is when I use the texture(bind to the image) as a shader's source texture, and call glDrawArrays to perform the rendering, the texture's reference count will be increased by 1 before return from glDrawArrays. And I failed to find any API to decrease it. Then this texture can't be freed when destroy that texture and thus the image's reference count will also remain 1 and can't be freed either. I'm looking at update_texture_state() which appears to hold onto a reference to the texobj until its slot is reused. If the object is simply destroyed and the unit disabled, the slot is skipped and the old reference remains. _mesa_update_state (which calls into update_texture_state) would seem to be only invoked upon a draw primitives. Binding a dummy texture/fb and doing a dummy render might be a little extreme as a workaround! Thanks for providing this workaround, I did try that way with my simple test case, it works. I just wonder whether this is a bug of MESA. I will implement it in glamor before we get a better solution. -Chris -- Chris Wilson, Intel
Re: [Intel-gfx] [PATCH] uxa/glamor: Enable the rest glamor rendering functions.
On Tue, 13 Dec 2011 22:31:41 +0800, zhigang.g...@linux.intel.com wrote: From: Zhigang Gong zhigang.g...@linux.intel.com This commit enable all the rest glamor rendering functions. Tested with latest glamor master branch, can pass rendercheck. Sure enough, it passes rendercheck. Well done! However, glyph rendering is off, the characters look incorrectly scaled and slightly out-of-position. And it will eventually chase a NULL pointer inside glamor's glyph cache. -Chris -- Chris Wilson, Intel Open Source Technology Centre ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH] uxa/glamor: Enable the rest glamor rendering functions.
On Wed, 14 Dec 2011 19:44:34 +0800, Zhigang Gong zhigang.g...@linux.intel.com wrote: -Original Message- From: Chris Wilson [mailto:ch...@chris-wilson.co.uk] Sent: Wednesday, December 14, 2011 7:12 PM To: Zhigang Gong Cc: intel-gfx@lists.freedesktop.org; zhigang.g...@gmail.com Subject: RE: [PATCH] uxa/glamor: Enable the rest glamor rendering functions. On Wed, 14 Dec 2011 12:08:30 +0800, Zhigang Gong zhigang.g...@linux.intel.com wrote: -Original Message- From: Chris Wilson [mailto:ch...@chris-wilson.co.uk] Sent: Wednesday, December 14, 2011 2:45 AM To: zhigang.g...@linux.intel.com Cc: intel-gfx@lists.freedesktop.org; zhigang.g...@gmail.com; zhigang.g...@linux.intel.com Subject: Re: [PATCH] uxa/glamor: Enable the rest glamor rendering functions. On Tue, 13 Dec 2011 22:31:41 +0800, zhigang.g...@linux.intel.com wrote: From: Zhigang Gong zhigang.g...@linux.intel.com This commit enable all the rest glamor rendering functions. Tested with latest glamor master branch, can pass rendercheck. Hmm, it exposes an issue with keeping a bo cache independent of mesa and trying to feed it our own handles: Region for name 6 already exists but is not compatible The w/a for this would be: diff --git a/src/intel_glamor.c b/src/intel_glamor.c index 0cf8ed7..2757fd6 100644 --- a/src/intel_glamor.c +++ b/src/intel_glamor.c @@ -91,6 +91,7 @@ intel_glamor_create_textured_pixmap(PixmapPtr pixmap) priv = intel_get_pixmap_private(pixmap); if (glamor_egl_create_textured_pixmap(pixmap, priv-bo-handle, priv-stride)) { + drm_intel_bo_disable_reuse(priv-bo); priv-pinned = 1; return TRUE; } else but that gives up all pretense of maintaining a bo cache. Yes, I think this impacts the performance. Actually, I noticed this problem and I spent some time to track the root cause. If everything is ok, this error should not be triggered. Although the same BO maybe reused to create a new pixmap, the previous pixmap which own this BO should be already destroyed. And the previous image created with the previous pixmap should be destroyed either. Certainly it looks like glamor is taking all necessary steps to decouple the bo from the textures and renderbuffer upon pixmap finish. There is one other potential race here in that the ddx will mark the bo as purgeable as soon as it releases it back to the cache, but it may not yet have been submitted by mesa in its execbuffer. The kernel may choose to free the memory associated with the bo before that happens, and may rightfully complain the userspace is doing something silly. Right, we do have this race if the kernel free the BO's memory prior to The mesa submit its execbuffer. Hmm. But I think that may not be a real problem, as once we call intel_set_pixmap_bo(pixmap, NULL) to unlink the bo from the pixmap, the BO will not be released at DRM layer immediately, instead, it will be put on a in_flight list. And intel_batch_submit will empty the list, considering after switching to glamor, each pixmap's batch buffer should be empty, then the driver will only call intel_batch_submit at intel_flush_rendering which is called from intel_uxa_block_handler and is after the intel_glamor_flush. At intel_glamor_flush, it will do a glFlush, my understanding is glFlush should make sure the execbuffer was submitted to GPU. But I'm not very sure. Can you confirm that? Thanks. It shouldn't go on the in-flight list because we're not using intel_batchbuffer any more and so it will not be referenced by the batch. This patch along with calling dispatch-glFlush() after deleting the textured pixmap is enough to silence the warning inside mesa and prevent the purgeable race: diff --git a/src/mesa/drivers/dri/intel/intel_context.c b/src/mesa/drivers/dri/intel/intel_context.c index 068b305..347a5d6 100644 --- a/src/mesa/drivers/dri/intel/intel_context.c +++ b/src/mesa/drivers/dri/intel/intel_context.c @@ -34,6 +34,7 @@ #include main/imports.h #include main/points.h #include main/renderbuffer.h +#include main/state.h #include swrast/swrast.h #include swrast_setup/swrast_setup.h @@ -527,6 +528,8 @@ intel_glFlush(struct gl_context *ctx) intel_flush_front(ctx); if (intel-is_front_buffer_rendering) intel-need_throttle = true; + + _mesa_update_state(ctx); } diff --git a/src/mesa/main/texstate.c b/src/mesa/main/texstate.c index 7cd2858..4bcaec0 100644 --- a/src/mesa/main/texstate.c +++ b/src/mesa/main/texstate.c @@ -557,6 +557,7 @@ update_texture_state( struct gl_context *ctx ) if (enabledTargets == 0x0) { /* neither vertex nor fragment processing uses this unit */ +_mesa_reference_texobj(texUnit-_Current, NULL);
[Intel-gfx] [PATCH 01/43] drm/i915: kicking rings stuck on semaphores considered harmful
If our semaphore logic gets confused and we have a ring stuck waiting for one, there's a decent chance it'll just execute garbage when being kicked. Also, kicking the ring obscures the place where the error first occured, making error_state decoding much harder. So drop this an let gpu reset handle this mess in a clean fashion. In contrast, kicking rings stuck on MI_WAIT is rather harmless, at worst there'll be a bit of screen-flickering. There's also old broken userspace out there which needs this as a work-around. Signed-off-by: Daniel Vetter daniel.vet...@ffwll.ch Reviewed-by: Chris Wilson ch...@hchris-wilson.co.uk Reviewed-by: Ben Widawsky b...@bwidawsk.net --- drivers/gpu/drm/i915/i915_irq.c |7 --- 1 files changed, 0 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index d47a53b..070345b 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1649,13 +1649,6 @@ static bool kick_ring(struct intel_ring_buffer *ring) I915_WRITE_CTL(ring, tmp); return true; } - if (IS_GEN6(dev) - (tmp RING_WAIT_SEMAPHORE)) { - DRM_ERROR(Kicking stuck semaphore on %s\n, - ring-name); - I915_WRITE_CTL(ring, tmp); - return true; - } return false; } -- 1.7.7.3 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 02/43] drm/i915: don't bail out of intel_wait_ring_buffer too early
In the pre-gem days with non-existing hangcheck and gpu reset code, this timeout of 3 seconds was pretty important to avoid stuck processes. But now we have the hangcheck code in gem that goes to great length to ensure that the gpu is really dead before declaring it wedged. So there's no need for this timeout anymore. Actually it's even harmful because we can bail out too early (e.g. with xscreensaver slip) when running giant batchbuffers. And our code isn't robust enough to properly unroll any state-changes, we pretty much rely on the gpu reset code cleaning up the mess (like cache tracking, fencing state, active list/request tracking, ...). With this change intel_begin_ring can only fail when the gpu is wedged, and it will return -EAGAIN (like wait_request in case the gpu reset is still outstanding). v2: Chris Wilson noted that on resume timers aren't running and hence we won't ever get kicked out of this loop by the hangcheck code. Use an insanely large timeout instead for the HAS_GEM case to prevent resume bugs from totally hanging the machine. Signed-off-by: Daniel Vetter daniel.vet...@ffwll.ch Reviewed-by: Chris Wilson ch...@chris-wilson.co.uk Acked-by: Ben Widawsky b...@bwidawsk.net --- drivers/gpu/drm/i915/intel_ringbuffer.c | 11 ++- 1 files changed, 10 insertions(+), 1 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index ca70e2f..6e28301 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -1119,7 +1119,16 @@ int intel_wait_ring_buffer(struct intel_ring_buffer *ring, int n) } trace_i915_ring_wait_begin(ring); - end = jiffies + 3 * HZ; + if (drm_core_check_feature(dev, DRIVER_GEM)) + /* With GEM the hangcheck timer should kick us out of the loop, +* leaving it early runs the risk of corrupting GEM state (due +* to running on almost untested codepaths). But on resume +* timers don't work yet, so prevent a complete hang in that +* case by choosing an insanely large timeout. */ + end = jiffies + 60 * HZ; + else + end = jiffies + 3 * HZ; + do { ring-head = I915_READ_HEAD(ring); ring-space = ring_space(ring); -- 1.7.7.3 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 03/43] drm/i915: switch ring-id to be a real id
... and add a helpr function for the places where we want a flag. This way we can use ring-id to index into arrays. v2: Resurrect the missing beautification-space Chris Wilson noted. I'm moving this space around because I'll reuse ring_str in the next patch. Signed-off-by: Daniel Vetter daniel.vet...@ffwll.ch Reviewed-by: Chris Wilson ch...@chris-wilson.co.uk Reviewed-by: Ben Widawsky b...@bwidawsk.net --- drivers/gpu/drm/i915/i915_debugfs.c|9 + drivers/gpu/drm/i915/i915_gem_execbuffer.c |4 ++-- drivers/gpu/drm/i915/i915_irq.c|2 +- drivers/gpu/drm/i915/intel_ringbuffer.c| 14 +++--- drivers/gpu/drm/i915/intel_ringbuffer.h| 20 ++-- 5 files changed, 25 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index d09a6e0..224d164 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -667,9 +667,9 @@ static int i915_ringbuffer_info(struct seq_file *m, void *data) static const char *ring_str(int ring) { switch (ring) { - case RING_RENDER: return render; - case RING_BSD: return bsd; - case RING_BLT: return blt; + case RCS: return render; + case VCS: return bsd; + case BCS: return blt; default: return ; } } @@ -712,7 +712,7 @@ static void print_error_buffers(struct seq_file *m, seq_printf(m, %s [%d]:\n, name, count); while (count--) { - seq_printf(m, %08x %8u %04x %04x %08x%s%s%s%s%s%s, + seq_printf(m, %08x %8u %04x %04x %08x%s%s%s%s%s%s%s, err-gtt_offset, err-size, err-read_domains, @@ -722,6 +722,7 @@ static void print_error_buffers(struct seq_file *m, tiling_flag(err-tiling), dirty_flag(err-dirty), purgeable_flag(err-purgeable), + err-ring != -1 ? : , ring_str(err-ring), cache_level_str(err-cache_level)); diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 3693e83..926ed48 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -202,9 +202,9 @@ i915_gem_object_set_to_gpu_domain(struct drm_i915_gem_object *obj, cd-invalidate_domains |= invalidate_domains; cd-flush_domains |= flush_domains; if (flush_domains I915_GEM_GPU_DOMAINS) - cd-flush_rings |= obj-ring-id; + cd-flush_rings |= intel_ring_flag(obj-ring); if (invalidate_domains I915_GEM_GPU_DOMAINS) - cd-flush_rings |= ring-id; + cd-flush_rings |= intel_ring_flag(ring); } struct eb_objects { diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 070345b..919d244 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -804,7 +804,7 @@ static u32 capture_bo_list(struct drm_i915_error_buffer *err, err-tiling = obj-tiling_mode; err-dirty = obj-dirty; err-purgeable = obj-madv != I915_MADV_WILLNEED; - err-ring = obj-ring ? obj-ring-id : 0; + err-ring = obj-ring ? obj-ring-id : -1; err-cache_level = obj-cache_level; if (++i == count) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 6e28301..3c30dba 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -726,13 +726,13 @@ void intel_ring_setup_status_page(struct intel_ring_buffer *ring) */ if (IS_GEN7(dev)) { switch (ring-id) { - case RING_RENDER: + case RCS: mmio = RENDER_HWS_PGA_GEN7; break; - case RING_BLT: + case BCS: mmio = BLT_HWS_PGA_GEN7; break; - case RING_BSD: + case VCS: mmio = BSD_HWS_PGA_GEN7; break; } @@ -1185,7 +1185,7 @@ void intel_ring_advance(struct intel_ring_buffer *ring) static const struct intel_ring_buffer render_ring = { .name = render ring, - .id = RING_RENDER, + .id = RCS, .mmio_base = RENDER_RING_BASE, .size = 32 * PAGE_SIZE, .init = init_render_ring, @@ -1208,7 +1208,7 @@ static const struct intel_ring_buffer render_ring = { static const struct intel_ring_buffer bsd_ring = { .name = bsd ring, - .id =
[Intel-gfx] [PATCH 04/43] drm/i915: refactor ring error state capture to use arrays
The code already got unwieldy and we want to dump more per-ring registers. Only functional change is that we now also capture the video ring registers on ilk. v2: fixup a refactor fumble spotted by Chris Wilson. Signed-off-by: Daniel Vetter daniel.vet...@ffwll.ch Reviewed-by: Chris Wilson ch...@chris-wilson.co.uk Signed-off-by: Ben Widawsky b...@bwidawsk.net --- drivers/gpu/drm/i915/i915_debugfs.c | 55 ++- drivers/gpu/drm/i915/i915_drv.h | 20 ++--- drivers/gpu/drm/i915/i915_irq.c | 70 ++- drivers/gpu/drm/i915/i915_reg.h | 11 + 4 files changed, 73 insertions(+), 83 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 224d164..37a74cf 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -736,6 +736,26 @@ static void print_error_buffers(struct seq_file *m, } } +static void i915_ring_error_state(struct seq_file *m, + struct drm_device *dev, + struct drm_i915_error_state *error, + unsigned ring) +{ + seq_printf(m, %s command stream:\n, ring_str(ring)); + seq_printf(m, ACTHD: 0x%08x\n, error-acthd[ring]); + seq_printf(m, IPEIR: 0x%08x\n, error-ipeir[ring]); + seq_printf(m, IPEHR: 0x%08x\n, error-ipehr[ring]); + seq_printf(m, INSTDONE: 0x%08x\n, error-instdone[ring]); + if (ring == RCS) { + if (INTEL_INFO(dev)-gen = 4) { + seq_printf(m, INSTDONE1: 0x%08x\n, error-instdone1); + seq_printf(m, INSTPS: 0x%08x\n, error-instps); + } + seq_printf(m, INSTPM: 0x%08x\n, error-instpm); + } + seq_printf(m, seqno: 0x%08x\n, error-seqno[ring]); +} + static int i915_error_state(struct seq_file *m, void *unused) { struct drm_info_node *node = (struct drm_info_node *) m-private; @@ -758,36 +778,19 @@ static int i915_error_state(struct seq_file *m, void *unused) seq_printf(m, PCI ID: 0x%04x\n, dev-pci_device); seq_printf(m, EIR: 0x%08x\n, error-eir); seq_printf(m, PGTBL_ER: 0x%08x\n, error-pgtbl_er); - if (INTEL_INFO(dev)-gen = 6) { - seq_printf(m, ERROR: 0x%08x\n, error-error); - seq_printf(m, Blitter command stream:\n); - seq_printf(m, ACTHD:0x%08x\n, error-bcs_acthd); - seq_printf(m, IPEIR:0x%08x\n, error-bcs_ipeir); - seq_printf(m, IPEHR:0x%08x\n, error-bcs_ipehr); - seq_printf(m, INSTDONE: 0x%08x\n, error-bcs_instdone); - seq_printf(m, seqno:0x%08x\n, error-bcs_seqno); - seq_printf(m, Video (BSD) command stream:\n); - seq_printf(m, ACTHD:0x%08x\n, error-vcs_acthd); - seq_printf(m, IPEIR:0x%08x\n, error-vcs_ipeir); - seq_printf(m, IPEHR:0x%08x\n, error-vcs_ipehr); - seq_printf(m, INSTDONE: 0x%08x\n, error-vcs_instdone); - seq_printf(m, seqno:0x%08x\n, error-vcs_seqno); - } - seq_printf(m, Render command stream:\n); - seq_printf(m, ACTHD: 0x%08x\n, error-acthd); - seq_printf(m, IPEIR: 0x%08x\n, error-ipeir); - seq_printf(m, IPEHR: 0x%08x\n, error-ipehr); - seq_printf(m, INSTDONE: 0x%08x\n, error-instdone); - if (INTEL_INFO(dev)-gen = 4) { - seq_printf(m, INSTDONE1: 0x%08x\n, error-instdone1); - seq_printf(m, INSTPS: 0x%08x\n, error-instps); - } - seq_printf(m, INSTPM: 0x%08x\n, error-instpm); - seq_printf(m, seqno: 0x%08x\n, error-seqno); for (i = 0; i dev_priv-num_fence_regs; i++) seq_printf(m, fence[%d] = %08llx\n, i, error-fence[i]); + if (INTEL_INFO(dev)-gen = 6) + seq_printf(m, ERROR: 0x%08x\n, error-error); + + i915_ring_error_state(m, dev, error, RCS); + if (HAS_BLT(dev)) + i915_ring_error_state(m, dev, error, BCS); + if (HAS_BSD(dev)) + i915_ring_error_state(m, dev, error, VCS); + if (error-active_bo) print_error_buffers(m, Active, error-active_bo, diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 86615b8..187cfc0 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -152,25 +152,15 @@ struct drm_i915_error_state { u32 eir; u32 pgtbl_er; u32 pipestat[I915_MAX_PIPES]; - u32 ipeir; - u32 ipehr; - u32 instdone; - u32 acthd; + u32 ipeir[I915_NUM_RINGS]; + u32 ipehr[I915_NUM_RINGS]; + u32 instdone[I915_NUM_RINGS]; + u32 acthd[I915_NUM_RINGS]; u32 error; /* gen6+ */ - u32 bcs_acthd; /* gen6+ blt engine */ -
[Intel-gfx] [PATCH 05/43] drm/i915: collect more per ring error state
Based on a patch by Ben Widawsky, but with different colors for the bikeshed. In contrast to Ben's patch this one doesn't add the fault regs. Afaics they're for the optional page fault support which - we're not enabling - and which seems to be unsupported by the hw team. Recent bspec lacks tons of information about this that the public docs released half a year back still contain. Also dump ring HEAD/TAIL registers - I've recently seen a few error_state where just guessing these is not good enough. v2: Also dump INSTPM for every ring. v3: Fix a few really silly goof-ups spotted by Chris Wilson. Signed-off-by: Daniel Vetter daniel.vet...@ffwll.ch Reviewed-by: Chris Wilson ch...@chris-wilson.co.uk Signed-off-by: Ben Widawsky b...@bwidawsk.net --- drivers/gpu/drm/i915/i915_debugfs.c | 16 ++-- drivers/gpu/drm/i915/i915_drv.h |7 +-- drivers/gpu/drm/i915/i915_irq.c |9 +++-- drivers/gpu/drm/i915/i915_reg.h |3 +++ 4 files changed, 25 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 37a74cf..60e8092 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -742,17 +742,21 @@ static void i915_ring_error_state(struct seq_file *m, unsigned ring) { seq_printf(m, %s command stream:\n, ring_str(ring)); + seq_printf(m, HEAD: 0x%08x\n, error-head[ring]); + seq_printf(m, TAIL: 0x%08x\n, error-tail[ring]); seq_printf(m, ACTHD: 0x%08x\n, error-acthd[ring]); seq_printf(m, IPEIR: 0x%08x\n, error-ipeir[ring]); seq_printf(m, IPEHR: 0x%08x\n, error-ipehr[ring]); seq_printf(m, INSTDONE: 0x%08x\n, error-instdone[ring]); - if (ring == RCS) { - if (INTEL_INFO(dev)-gen = 4) { - seq_printf(m, INSTDONE1: 0x%08x\n, error-instdone1); - seq_printf(m, INSTPS: 0x%08x\n, error-instps); - } - seq_printf(m, INSTPM: 0x%08x\n, error-instpm); + if (ring == RCS INTEL_INFO(dev)-gen = 4) { + seq_printf(m, INSTDONE1: 0x%08x\n, error-instdone1); + seq_printf(m, BBADDR: 0x%08llx\n, error-bbaddr); } + if (INTEL_INFO(dev)-gen = 4) + seq_printf(m, INSTPS: 0x%08x\n, error-instps[ring]); + seq_printf(m, INSTPM: 0x%08x\n, error-instpm[ring]); + if (INTEL_INFO(dev)-gen = 6) + seq_printf(m, FADDR: 0x%08x\n, error-faddr[ring]); seq_printf(m, seqno: 0x%08x\n, error-seqno[ring]); } diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 187cfc0..8141e97 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -152,16 +152,19 @@ struct drm_i915_error_state { u32 eir; u32 pgtbl_er; u32 pipestat[I915_MAX_PIPES]; + u32 tail[I915_NUM_RINGS]; + u32 head[I915_NUM_RINGS]; u32 ipeir[I915_NUM_RINGS]; u32 ipehr[I915_NUM_RINGS]; u32 instdone[I915_NUM_RINGS]; u32 acthd[I915_NUM_RINGS]; u32 error; /* gen6+ */ - u32 instpm; - u32 instps; + u32 instpm[I915_NUM_RINGS]; + u32 instps[I915_NUM_RINGS]; u32 instdone1; u32 seqno[I915_NUM_RINGS]; u64 bbaddr; + u32 faddr[I915_NUM_RINGS]; u64 fence[I915_MAX_NUM_FENCES]; struct timeval time; struct drm_i915_error_object { diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 407555b..bfa4964 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -882,12 +882,15 @@ static void i915_record_ring_state(struct drm_device *dev, { struct drm_i915_private *dev_priv = dev-dev_private; + if (INTEL_INFO(dev)-gen = 6) + error-faddr[ring-id] = I915_READ(RING_DMA_FADD(ring-mmio_base)); + if (INTEL_INFO(dev)-gen = 4) { error-ipeir[ring-id] = I915_READ(RING_IPEIR(ring-mmio_base)); error-ipehr[ring-id] = I915_READ(RING_IPEHR(ring-mmio_base)); error-instdone[ring-id] = I915_READ(RING_INSTDONE(ring-mmio_base)); + error-instps[ring-id] = I915_READ(RING_INSTPS(ring-mmio_base)); if (ring-id == RCS) { - error-instps = I915_READ(INSTPS); error-instdone1 = I915_READ(INSTDONE1); error-bbaddr = I915_READ64(BB_ADDR); } @@ -898,8 +901,11 @@ static void i915_record_ring_state(struct drm_device *dev, error-bbaddr = 0; } + error-instpm[ring-id] = I915_READ(RING_INSTPM(ring-mmio_base)); error-seqno[ring-id] = ring-get_seqno(ring); error-acthd[ring-id] = intel_ring_get_active_head(ring); + error-head[ring-id] = I915_READ_HEAD(ring); + error-tail[ring-id] =
[Intel-gfx] [PATCH 06/43] drm/i915: protect force_wake_(get|put) with the gt_lock
The problem this patch solves is that the forcewake accounting necessary for register reads is protected by dev-struct_mutex. But the hangcheck and error_capture code need to access registers without grabbing this mutex because we hold it while waiting for the gpu. So a new lock is required. Because currently the error_state capture is called from the error irq handler and the hangcheck code runs from a timer, it needs to be an irqsafe spinlock (note that the registers used by the irq handler (neglecting the error handling part) only uses registers that don't need the forcewake dance). We could tune this down to a normal spinlock when we rework the error_state capture and hangcheck code to run from a workqueue. But we don't have any read in a fastpath that needs forcewake, so I've decided to not care much about overhead. This prevents tests/gem_hangcheck_forcewake from i-g-t from killing my snb on recent kernels - something must have slightly changed the timings. On previous kernels it only trigger a WARN about the broken locking. v2: Drop the previous patch for the register writes. v3: Improve the commit message per Chris Wilson's suggestions. Signed-Off-by: Daniel Vetter daniel.vet...@ffwll.ch Reviewed-by: Chris Wilson ch...@chris-wilson.co.uk Reviewed-by: Eugeni Dodonov eugeni.dodo...@intel.com --- drivers/gpu/drm/i915/i915_debugfs.c |8 ++-- drivers/gpu/drm/i915/i915_dma.c |1 + drivers/gpu/drm/i915/i915_drv.c | 18 -- drivers/gpu/drm/i915/i915_drv.h | 10 +++--- 4 files changed, 26 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 60e8092..c130c5d 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -1321,9 +1321,13 @@ static int i915_gen6_forcewake_count_info(struct seq_file *m, void *data) 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; + unsigned forcewake_count; - seq_printf(m, forcewake count = %d\n, - atomic_read(dev_priv-forcewake_count)); + spin_lock_irq(dev_priv-gt_lock); + forcewake_count = dev_priv-forcewake_count; + spin_unlock_irq(dev_priv-gt_lock); + + seq_printf(m, forcewake count = %u\n, forcewake_count); return 0; } diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index a9533c5..448d5b1 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -2032,6 +2032,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) if (!IS_I945G(dev) !IS_I945GM(dev)) pci_enable_msi(dev-pdev); + spin_lock_init(dev_priv-gt_lock); spin_lock_init(dev_priv-irq_lock); spin_lock_init(dev_priv-error_lock); spin_lock_init(dev_priv-rps_lock); diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 28836fe..34f5115 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -368,11 +368,12 @@ void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv) */ void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv) { - WARN_ON(!mutex_is_locked(dev_priv-dev-struct_mutex)); + unsigned long irqflags; - /* Forcewake is atomic in case we get in here without the lock */ - if (atomic_add_return(1, dev_priv-forcewake_count) == 1) + spin_lock_irqsave(dev_priv-gt_lock, irqflags); + if (dev_priv-forcewake_count++ == 0) dev_priv-display.force_wake_get(dev_priv); + spin_unlock_irqrestore(dev_priv-gt_lock, irqflags); } void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv) @@ -392,10 +393,12 @@ void __gen6_gt_force_wake_mt_put(struct drm_i915_private *dev_priv) */ void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv) { - WARN_ON(!mutex_is_locked(dev_priv-dev-struct_mutex)); + unsigned long irqflags; - if (atomic_dec_and_test(dev_priv-forcewake_count)) + spin_lock_irqsave(dev_priv-gt_lock, irqflags); + if (--dev_priv-forcewake_count == 0) dev_priv-display.force_wake_put(dev_priv); + spin_unlock_irqrestore(dev_priv-gt_lock, irqflags); } void __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv) @@ -626,6 +629,7 @@ int i915_reset(struct drm_device *dev, u8 flags) * need to */ bool need_display = true; + unsigned long irqflags; int ret; if (!i915_try_reset) @@ -644,8 +648,10 @@ int i915_reset(struct drm_device *dev, u8 flags) case 6: ret = gen6_do_reset(dev, flags); /* If reset with a user forcewake, try to restore */ - if (atomic_read(dev_priv-forcewake_count)) + spin_lock_irqsave(dev_priv-gt_lock,
[Intel-gfx] [PATCH 07/43] drm/i915: convert force_wake_get to func pointer in the gpu reset code
This was forgotten in the original multi-threaded forcewake conversion: commit 8d715f0024f64ad1b1be85d8c081cf577944c847 Author: Keith Packard kei...@keithp.com Date: Fri Nov 18 20:39:01 2011 -0800 drm/i915: add multi-threaded forcewake support Signed-Off-by: Daniel Vetter daniel.vet...@ffwll.ch Reviewed-by: Eugeni Dodonov eugeni.dodo...@intel.com --- drivers/gpu/drm/i915/i915_drv.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 34f5115..ac3ad22 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -650,7 +650,7 @@ int i915_reset(struct drm_device *dev, u8 flags) /* If reset with a user forcewake, try to restore */ spin_lock_irqsave(dev_priv-gt_lock, irqflags); if (dev_priv-forcewake_count) - __gen6_gt_force_wake_get(dev_priv); + dev_priv-display.force_wake_get(dev_priv); spin_unlock_irqrestore(dev_priv-gt_lock, irqflags); break; case 5: -- 1.7.7.3 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 08/43] drm/i915: drop register special-casing in forcewake
We currently have 3 register for which we must not grab forcewake for: FORCEWAKE, FROCEWAKE_MT and ECOBUS. - FORCEWAKE is excluded in the NEEDS_FORCE_WAKE macro and accessed with _NOTRACE. - FORCEWAKE_MT is just accessed with _NOTRACE. - ECOBUS is only excluded in the macro. In fear of an ever-growing list of special cases and to cut down the confusion, just access all of them with the _NOTRACE variants. Also kill the duplicate definition of the macro, which is unused. Signed-Off-by: Daniel Vetter daniel.vet...@ffwll.ch Reviewed-by: Eugeni Dodonov eugeni.dodo...@intel.com --- drivers/gpu/drm/i915/i915_drv.c |4 +--- drivers/gpu/drm/i915/i915_drv.h |7 --- drivers/gpu/drm/i915/intel_display.c |2 +- 3 files changed, 2 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index ac3ad22..653b6f2 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -931,9 +931,7 @@ MODULE_LICENSE(GPL and additional rights); /* We give fast paths for the really cool registers */ #define NEEDS_FORCE_WAKE(dev_priv, reg) \ (((dev_priv)-info-gen = 6) \ -((reg) 0x4) \ -((reg) != FORCEWAKE) \ -((reg) != ECOBUS)) +((reg) 0x4)) \ #define __i915_read(x, y) \ u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg) { \ diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 9e6ccc2..4ee4626 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1356,13 +1356,6 @@ void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv); void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv); void __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv); -/* We give fast paths for the really cool registers */ -#define NEEDS_FORCE_WAKE(dev_priv, reg) \ - (((dev_priv)-info-gen = 6) \ -((reg) 0x4) \ -((reg) != FORCEWAKE) \ -((reg) != ECOBUS)) - #define __i915_read(x, y) \ u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg); diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 633c693..70436c7 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -8500,7 +8500,7 @@ static void intel_init_display(struct drm_device *dev) mutex_lock(dev-struct_mutex); __gen6_gt_force_wake_mt_get(dev_priv); - ecobus = I915_READ(ECOBUS); + ecobus = I915_READ_NOTRACE(ECOBUS); __gen6_gt_force_wake_mt_put(dev_priv); mutex_unlock(dev-struct_mutex); -- 1.7.7.3 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 09/43] drm/i915: introduce a vtable for gpu core functions
... like for forcewake, which protects everything _but_ display. Expect more things (like gtt abstractions, rings, inter-ring sync) to come. Signed-Off-by: Daniel Vetter daniel.vet...@ffwll.ch Reviewed-by: Eugeni Dodonov eugeni.dodo...@intel.com --- drivers/gpu/drm/i915/i915_drv.c |6 +++--- drivers/gpu/drm/i915/i915_drv.h |8 ++-- drivers/gpu/drm/i915/intel_display.c |8 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 653b6f2..4a2eb68 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -372,7 +372,7 @@ void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv) spin_lock_irqsave(dev_priv-gt_lock, irqflags); if (dev_priv-forcewake_count++ == 0) - dev_priv-display.force_wake_get(dev_priv); + dev_priv-core.force_wake_get(dev_priv); spin_unlock_irqrestore(dev_priv-gt_lock, irqflags); } @@ -397,7 +397,7 @@ void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv) spin_lock_irqsave(dev_priv-gt_lock, irqflags); if (--dev_priv-forcewake_count == 0) - dev_priv-display.force_wake_put(dev_priv); + dev_priv-core.force_wake_put(dev_priv); spin_unlock_irqrestore(dev_priv-gt_lock, irqflags); } @@ -650,7 +650,7 @@ int i915_reset(struct drm_device *dev, u8 flags) /* If reset with a user forcewake, try to restore */ spin_lock_irqsave(dev_priv-gt_lock, irqflags); if (dev_priv-forcewake_count) - dev_priv-display.force_wake_get(dev_priv); + dev_priv-core.force_wake_get(dev_priv); spin_unlock_irqrestore(dev_priv-gt_lock, irqflags); break; case 5: diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 4ee4626..40e0848 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -215,8 +215,6 @@ struct drm_i915_display_funcs { struct drm_i915_gem_object *obj); int (*update_plane)(struct drm_crtc *crtc, struct drm_framebuffer *fb, int x, int y); - void (*force_wake_get)(struct drm_i915_private *dev_priv); - void (*force_wake_put)(struct drm_i915_private *dev_priv); /* clock updates for mode set */ /* cursor updates */ /* render clock increase/decrease */ @@ -224,6 +222,11 @@ struct drm_i915_display_funcs { /* pll clock increase/decrease */ }; +struct drm_i915_core_funcs { + void (*force_wake_get)(struct drm_i915_private *dev_priv); + void (*force_wake_put)(struct drm_i915_private *dev_priv); +}; + struct intel_device_info { u8 gen; u8 is_mobile:1; @@ -296,6 +299,7 @@ typedef struct drm_i915_private { struct pci_dev *bridge_dev; struct intel_ring_buffer ring[I915_NUM_RINGS]; uint32_t next_seqno; + struct drm_i915_core_funcs core; drm_dma_handle_t *status_page_dmah; uint32_t counter; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 70436c7..2f0cc52 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -8491,8 +8491,8 @@ static void intel_init_display(struct drm_device *dev) /* For FIFO watermark updates */ if (HAS_PCH_SPLIT(dev)) { - dev_priv-display.force_wake_get = __gen6_gt_force_wake_get; - dev_priv-display.force_wake_put = __gen6_gt_force_wake_put; + dev_priv-core.force_wake_get = __gen6_gt_force_wake_get; + dev_priv-core.force_wake_put = __gen6_gt_force_wake_put; /* IVB configs may use multi-threaded forcewake */ if (IS_IVYBRIDGE(dev)) { @@ -8506,9 +8506,9 @@ static void intel_init_display(struct drm_device *dev) if (ecobus FORCEWAKE_MT_ENABLE) { DRM_DEBUG_KMS(Using MT version of forcewake\n); - dev_priv-display.force_wake_get = + dev_priv-core.force_wake_get = __gen6_gt_force_wake_mt_get; - dev_priv-display.force_wake_put = + dev_priv-core.force_wake_put = __gen6_gt_force_wake_mt_put; } } -- 1.7.7.3 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 10/43] drm/i915/ringbuffer: kill snb blt workaround
This was just to facilitate product enablement with pre-production hw. Allows us to kill quite a bit of cruft. Signed-off-by: Daniel Vetter daniel.vet...@ffwll.ch Signed-off-by: Kenneth Graunke kenn...@whitecape.org Reviewed-by: Eric Anholt e...@anholt.net --- drivers/gpu/drm/i915/intel_ringbuffer.c | 81 +-- 1 files changed, 2 insertions(+), 79 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 3c30dba..2d476a9 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -1354,79 +1354,13 @@ blt_ring_put_irq(struct intel_ring_buffer *ring) GEN6_BLITTER_USER_INTERRUPT); } - -/* Workaround for some stepping of SNB, - * each time when BLT engine ring tail moved, - * the first command in the ring to be parsed - * should be MI_BATCH_BUFFER_START - */ -#define NEED_BLT_WORKAROUND(dev) \ - (IS_GEN6(dev) (dev-pdev-revision 8)) - -static inline struct drm_i915_gem_object * -to_blt_workaround(struct intel_ring_buffer *ring) -{ - return ring-private; -} - -static int blt_ring_init(struct intel_ring_buffer *ring) -{ - if (NEED_BLT_WORKAROUND(ring-dev)) { - struct drm_i915_gem_object *obj; - u32 *ptr; - int ret; - - obj = i915_gem_alloc_object(ring-dev, 4096); - if (obj == NULL) - return -ENOMEM; - - ret = i915_gem_object_pin(obj, 4096, true); - if (ret) { - drm_gem_object_unreference(obj-base); - return ret; - } - - ptr = kmap(obj-pages[0]); - *ptr++ = MI_BATCH_BUFFER_END; - *ptr++ = MI_NOOP; - kunmap(obj-pages[0]); - - ret = i915_gem_object_set_to_gtt_domain(obj, false); - if (ret) { - i915_gem_object_unpin(obj); - drm_gem_object_unreference(obj-base); - return ret; - } - - ring-private = obj; - } - - return init_ring_common(ring); -} - -static int blt_ring_begin(struct intel_ring_buffer *ring, - int num_dwords) -{ - if (ring-private) { - int ret = intel_ring_begin(ring, num_dwords+2); - if (ret) - return ret; - - intel_ring_emit(ring, MI_BATCH_BUFFER_START); - intel_ring_emit(ring, to_blt_workaround(ring)-gtt_offset); - - return 0; - } else - return intel_ring_begin(ring, 4); -} - static int blt_ring_flush(struct intel_ring_buffer *ring, u32 invalidate, u32 flush) { uint32_t cmd; int ret; - ret = blt_ring_begin(ring, 4); + ret = intel_ring_begin(ring, 4); if (ret) return ret; @@ -1441,22 +1375,12 @@ static int blt_ring_flush(struct intel_ring_buffer *ring, return 0; } -static void blt_ring_cleanup(struct intel_ring_buffer *ring) -{ - if (!ring-private) - return; - - i915_gem_object_unpin(ring-private); - drm_gem_object_unreference(ring-private); - ring-private = NULL; -} - static const struct intel_ring_buffer gen6_blt_ring = { .name = blt ring, .id = BCS, .mmio_base = BLT_RING_BASE, .size = 32 * PAGE_SIZE, - .init = blt_ring_init, + .init = init_ring_common, .write_tail = ring_write_tail, .flush = blt_ring_flush, .add_request= gen6_add_request, @@ -1464,7 +1388,6 @@ static const struct intel_ring_buffer gen6_blt_ring = { .irq_get= blt_ring_get_irq, .irq_put= blt_ring_put_irq, .dispatch_execbuffer= gen6_ring_dispatch_execbuffer, - .cleanup= blt_ring_cleanup, .sync_to= gen6_blt_ring_sync_to, .semaphore_register = {MI_SEMAPHORE_SYNC_BR, MI_SEMAPHORE_SYNC_BV, -- 1.7.7.3 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 11/43] drm/i915: Separate fence pin counting from normal bind pin counting
From: Chris Wilson ch...@chris-wilson.co.uk In order to correctly account for reserving space in the GTT and fences for a batch buffer, we need to independently track whether the fence is pinned due to a fenced GPU access in the batch or whether the buffer is pinned in the aperture. Currently we count the fenced as pinned if the buffer has already been seen in the execbuffer. This leads to a false accounting of available fence registers, causing frequent mass evictions. Worse, if coupled with the change to make i915_gem_object_get_fence() report EDADLK upon fence starvation, the batchbuffer can fail with only one fence required... Fixes intel-gpu-tools/tests/gem_fenced_exec_thrash Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=38735 Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk Reviewed-by: Daniel Vetter daniel.vet...@ffwll.ch Tested-by: Paul Neumann paul1...@yahoo.de --- drivers/gpu/drm/i915/i915_drv.h| 19 drivers/gpu/drm/i915/i915_gem.c|7 +- drivers/gpu/drm/i915/i915_gem_execbuffer.c | 139 ++-- drivers/gpu/drm/i915/intel_display.c | 16 +++- 4 files changed, 126 insertions(+), 55 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 40e0848..5abc828 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -135,6 +135,7 @@ struct drm_i915_fence_reg { struct list_head lru_list; struct drm_i915_gem_object *obj; uint32_t setup_seqno; + int pin_count; }; struct sdvo_device_mapping { @@ -1174,6 +1175,24 @@ int __must_check i915_gem_object_get_fence(struct drm_i915_gem_object *obj, struct intel_ring_buffer *pipelined); int __must_check i915_gem_object_put_fence(struct drm_i915_gem_object *obj); +static inline void +i915_gem_object_pin_fence(struct drm_i915_gem_object *obj) +{ + if (obj-fence_reg != I915_FENCE_REG_NONE) { + struct drm_i915_private *dev_priv = obj-base.dev-dev_private; + dev_priv-fence_regs[obj-fence_reg].pin_count++; + } +} + +static inline void +i915_gem_object_unpin_fence(struct drm_i915_gem_object *obj) +{ + if (obj-fence_reg != I915_FENCE_REG_NONE) { + struct drm_i915_private *dev_priv = obj-base.dev-dev_private; + dev_priv-fence_regs[obj-fence_reg].pin_count--; + } +} + void i915_gem_retire_requests(struct drm_device *dev); void i915_gem_reset(struct drm_device *dev); void i915_gem_clflush_object(struct drm_i915_gem_object *obj); diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 8359dc7..695709a 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2432,6 +2432,8 @@ i915_gem_object_put_fence(struct drm_i915_gem_object *obj) if (obj-fence_reg != I915_FENCE_REG_NONE) { struct drm_i915_private *dev_priv = obj-base.dev-dev_private; + + WARN_ON(dev_priv-fence_regs[obj-fence_reg].pin_count); i915_gem_clear_fence_reg(obj-base.dev, dev_priv-fence_regs[obj-fence_reg]); @@ -2456,7 +2458,7 @@ i915_find_fence_reg(struct drm_device *dev, if (!reg-obj) return reg; - if (!reg-obj-pin_count) + if (!reg-pin_count) avail = reg; } @@ -2466,7 +2468,7 @@ i915_find_fence_reg(struct drm_device *dev, /* None available, try to steal one or wait for a user to finish */ avail = first = NULL; list_for_each_entry(reg, dev_priv-mm.fence_list, lru_list) { - if (reg-obj-pin_count) + if (reg-pin_count) continue; if (first == NULL) @@ -2660,6 +2662,7 @@ i915_gem_clear_fence_reg(struct drm_device *dev, list_del_init(reg-lru_list); reg-obj = NULL; reg-setup_seqno = 0; + reg-pin_count = 0; } /** diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 926ed48..c918124 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -460,6 +460,54 @@ i915_gem_execbuffer_relocate(struct drm_device *dev, return ret; } +#define __EXEC_OBJECT_HAS_FENCE (131) + +static int +pin_and_fence_object(struct drm_i915_gem_object *obj, +struct intel_ring_buffer *ring) +{ + struct drm_i915_gem_exec_object2 *entry = obj-exec_entry; + bool has_fenced_gpu_access = INTEL_INFO(ring-dev)-gen 4; + bool need_fence, need_mappable; + int ret; + + need_fence = + has_fenced_gpu_access + entry-flags EXEC_OBJECT_NEEDS_FENCE + obj-tiling_mode != I915_TILING_NONE; + need_mappable = + entry-relocation_count ? true : need_fence;
[Intel-gfx] [PATCH 12/43] drm/i915: don't trash the gtt when running out of fences
With the fence accounting fixed up in the previous commit not finding enough fences is a fatal error and userspace bug. Trashing the entire gtt is not gonna turn up that missing fence, so don't to this by returning another error thatn ENOSPC. This has the added benefit that it's easier to distinguish fence accounting errors from gtt space accounting issues. TTM serves as precendence for the EDEADLK error code - it returns it when the reservation code needs resources already blocked by the current reservation. Signed-Off-by: Daniel Vetter daniel.vet...@ffwll.ch --- drivers/gpu/drm/i915/i915_gem.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 695709a..e995248 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2562,7 +2562,7 @@ i915_gem_object_get_fence(struct drm_i915_gem_object *obj, reg = i915_find_fence_reg(dev, pipelined); if (reg == NULL) - return -ENOSPC; + return -EDEADLK; ret = i915_gem_object_flush_fence(obj, pipelined); if (ret) -- 1.7.7.3 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 13/43] drm/i915: refactor debugfs open function
Only forcewake has an open with special semantics, the other r/w debugfs only assign the file private pointer. Signed-Off-by: Daniel Vetter daniel.vet...@ffwll.ch Reviewed-by: Ben Widawsky b...@bwidawsk.net Reviewed-by: Kenneth Graunke kenn...@whitecape.org --- drivers/gpu/drm/i915/i915_debugfs.c | 26 +- 1 files changed, 5 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index c130c5d..21547cd 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -1333,8 +1333,8 @@ static int i915_gen6_forcewake_count_info(struct seq_file *m, void *data) } static int -i915_wedged_open(struct inode *inode, -struct file *filp) +i915_debugfs_common_open(struct inode *inode, +struct file *filp) { filp-private_data = inode-i_private; return 0; @@ -1390,20 +1390,12 @@ i915_wedged_write(struct file *filp, static const struct file_operations i915_wedged_fops = { .owner = THIS_MODULE, - .open = i915_wedged_open, + .open = i915_debugfs_common_open, .read = i915_wedged_read, .write = i915_wedged_write, .llseek = default_llseek, }; -static int -i915_max_freq_open(struct inode *inode, - struct file *filp) -{ - filp-private_data = inode-i_private; - return 0; -} - static ssize_t i915_max_freq_read(struct file *filp, char __user *ubuf, @@ -1460,20 +1452,12 @@ i915_max_freq_write(struct file *filp, static const struct file_operations i915_max_freq_fops = { .owner = THIS_MODULE, - .open = i915_max_freq_open, + .open = i915_debugfs_common_open, .read = i915_max_freq_read, .write = i915_max_freq_write, .llseek = default_llseek, }; -static int -i915_cache_sharing_open(struct inode *inode, - struct file *filp) -{ - filp-private_data = inode-i_private; - return 0; -} - static ssize_t i915_cache_sharing_read(struct file *filp, char __user *ubuf, @@ -1539,7 +1523,7 @@ i915_cache_sharing_write(struct file *filp, static const struct file_operations i915_cache_sharing_fops = { .owner = THIS_MODULE, - .open = i915_cache_sharing_open, + .open = i915_debugfs_common_open, .read = i915_cache_sharing_read, .write = i915_cache_sharing_write, .llseek = default_llseek, -- 1.7.7.3 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 14/43] drm/i915: refactor debugfs create functions
All r/w debugfs files are created equal. v2: Add some newlines to make the code easier on the eyes as requested by Ben Widawsky. Signed-Off-by: Daniel Vetter daniel.vet...@ffwll.ch Reviewed-by: Ben Widawsky b...@bwidawsk.net Reviewed-by: Kenneth Graunke kenn...@whitecape.org --- drivers/gpu/drm/i915/i915_debugfs.c | 55 +++--- 1 files changed, 18 insertions(+), 37 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 21547cd..db83552 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -1555,21 +1555,6 @@ drm_add_fake_info_node(struct drm_minor *minor, return 0; } -static int i915_wedged_create(struct dentry *root, struct drm_minor *minor) -{ - struct drm_device *dev = minor-dev; - struct dentry *ent; - - ent = debugfs_create_file(i915_wedged, - S_IRUGO | S_IWUSR, - root, dev, - i915_wedged_fops); - if (IS_ERR(ent)) - return PTR_ERR(ent); - - return drm_add_fake_info_node(minor, ent, i915_wedged_fops); -} - static int i915_forcewake_open(struct inode *inode, struct file *file) { struct drm_device *dev = inode-i_private; @@ -1631,34 +1616,22 @@ static int i915_forcewake_create(struct dentry *root, struct drm_minor *minor) return drm_add_fake_info_node(minor, ent, i915_forcewake_fops); } -static int i915_max_freq_create(struct dentry *root, struct drm_minor *minor) -{ - struct drm_device *dev = minor-dev; - struct dentry *ent; - - ent = debugfs_create_file(i915_max_freq, - S_IRUGO | S_IWUSR, - root, dev, - i915_max_freq_fops); - if (IS_ERR(ent)) - return PTR_ERR(ent); - - return drm_add_fake_info_node(minor, ent, i915_max_freq_fops); -} - -static int i915_cache_sharing_create(struct dentry *root, struct drm_minor *minor) +static int i915_debugfs_create(struct dentry *root, + struct drm_minor *minor, + const char *name, + const struct file_operations *fops) { struct drm_device *dev = minor-dev; struct dentry *ent; - ent = debugfs_create_file(i915_cache_sharing, + ent = debugfs_create_file(name, S_IRUGO | S_IWUSR, root, dev, - i915_cache_sharing_fops); + fops); if (IS_ERR(ent)) return PTR_ERR(ent); - return drm_add_fake_info_node(minor, ent, i915_cache_sharing_fops); + return drm_add_fake_info_node(minor, ent, fops); } static struct drm_info_list i915_debugfs_list[] = { @@ -1707,17 +1680,25 @@ int i915_debugfs_init(struct drm_minor *minor) { int ret; - ret = i915_wedged_create(minor-debugfs_root, minor); + ret = i915_debugfs_create(minor-debugfs_root, minor, + i915_wedged, + i915_wedged_fops); if (ret) return ret; ret = i915_forcewake_create(minor-debugfs_root, minor); if (ret) return ret; - ret = i915_max_freq_create(minor-debugfs_root, minor); + + ret = i915_debugfs_create(minor-debugfs_root, minor, + i915_max_freq, + i915_max_freq_fops); if (ret) return ret; - ret = i915_cache_sharing_create(minor-debugfs_root, minor); + + ret = i915_debugfs_create(minor-debugfs_root, minor, + i915_cache_sharing, + i915_cache_sharing_fops); if (ret) return ret; -- 1.7.7.3 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 16/43] drm/i915: rework dev-first_error locking
- reduce the irq disabled section, even for a debugfs file this was way too long. - always disable irqs when taking the lock. v2: Thou shalt not mistake locking for reference counting, so: - reference count the error_state to protect from concurent freeeing. This will be only really used in the next patch. Signed-Off-by: Daniel Vetter daniel.vet...@ffwll.ch --- drivers/gpu/drm/i915/i915_debugfs.c | 13 - drivers/gpu/drm/i915/i915_drv.h |4 drivers/gpu/drm/i915/i915_irq.c | 17 ++--- 3 files changed, 22 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 67d7567..b8a1770 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -770,12 +770,16 @@ static int i915_error_state(struct seq_file *m, void *unused) int i, page, offset, elt; spin_lock_irqsave(dev_priv-error_lock, flags); - if (!dev_priv-first_error) { + error = dev_priv-first_error; + if (error) + kref_get(error-ref); + spin_unlock_irqrestore(dev_priv-error_lock, flags); + + if (!error) { seq_printf(m, no error state collected\n); - goto out; + return 0; } - error = dev_priv-first_error; seq_printf(m, Time: %ld s %ld us\n, error-time.tv_sec, error-time.tv_usec); @@ -846,8 +850,7 @@ static int i915_error_state(struct seq_file *m, void *unused) if (error-display) intel_display_print_error_state(m, dev, error-display); -out: - spin_unlock_irqrestore(dev_priv-error_lock, flags); + kref_put(error-ref, i915_error_state_free); return 0; } diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 621349e..b46fac5 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -37,6 +37,7 @@ #include linux/i2c.h #include drm/intel-gtt.h #include linux/backlight.h +#include linux/kref.h /* General customization: */ @@ -150,6 +151,7 @@ struct sdvo_device_mapping { struct intel_display_error_state; struct drm_i915_error_state { + struct kref ref; u32 eir; u32 pgtbl_er; u32 pipestat[I915_MAX_PIPES]; @@ -396,6 +398,7 @@ typedef struct drm_i915_private { unsigned int fsb_freq, mem_freq, is_ddr3; spinlock_t error_lock; + /* Protected by dev-error_lock. */ struct drm_i915_error_state *first_error; struct work_struct error_work; struct completion error_completion; @@ -1059,6 +1062,7 @@ extern int i915_vblank_pipe_get(struct drm_device *dev, void *data, struct drm_file *file_priv); extern int i915_vblank_swap(struct drm_device *dev, void *data, struct drm_file *file_priv); +void i915_error_state_free(struct kref *error_ref); void i915_enable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask); diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index bfa4964..56f2b2f 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -764,10 +764,11 @@ i915_error_object_free(struct drm_i915_error_object *obj) kfree(obj); } -static void -i915_error_state_free(struct drm_device *dev, - struct drm_i915_error_state *error) +void +i915_error_state_free(struct kref *error_ref) { + struct drm_i915_error_state *error = container_of(error_ref, + typeof(*error), ref); int i; for (i = 0; i ARRAY_SIZE(error-batchbuffer); i++) @@ -941,6 +942,7 @@ static void i915_capture_error_state(struct drm_device *dev) DRM_INFO(capturing error event; look for more information in /debug/dri/%d/i915_error_state\n, dev-primary-index); + kref_init(error-ref); error-eir = I915_READ(EIR); error-pgtbl_er = I915_READ(PGTBL_ER); for_each_pipe(pipe) @@ -1017,21 +1019,22 @@ static void i915_capture_error_state(struct drm_device *dev) spin_unlock_irqrestore(dev_priv-error_lock, flags); if (error) - i915_error_state_free(dev, error); + i915_error_state_free(error-ref); } void i915_destroy_error_state(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev-dev_private; struct drm_i915_error_state *error; + unsigned long flags; - spin_lock(dev_priv-error_lock); + spin_lock_irqsave(dev_priv-error_lock, flags); error = dev_priv-first_error; dev_priv-first_error = NULL; - spin_unlock(dev_priv-error_lock); + spin_unlock_irqrestore(dev_priv-error_lock, flags); if (error) - i915_error_state_free(dev, error); + kref_put(error-ref, i915_error_state_free); } #else #define
[Intel-gfx] [PATCH 17/43] drm/i915: destroy existing error_state when simulating a gpu hang
This way we can simulate a bunch of gpu hangs and run the error_state capture code every time (without the need to reload the module). Signed-Off-by: Daniel Vetter daniel.vet...@ffwll.ch --- drivers/gpu/drm/i915/i915_debugfs.c |2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index b8a1770..4a30756 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -1444,6 +1444,8 @@ i915_ring_stop_write(struct file *filp, DRM_DEBUG_DRIVER(Stopping rings 0x%08x\n, val); mutex_lock(dev-struct_mutex); + i915_destroy_error_state(dev); + dev_priv-stop_rings = val; mutex_unlock(dev-struct_mutex); -- 1.7.7.3 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 18/43] drm/i915: fix swizzle detection for gen3
It looks like the desktop variants of i915 and i945 also have the DCC register to control dram channel interleave and cpu side bit6 swizzling. Unfortunately internal Cspec/ConfigDB documentation for these ancient chips have already been dropped and there seem to be no archives. Also somebody thought the swizzling behaviour is surely a worthy secret to keep and redacted any mention of these fields from the published Intel datasheets. I suspect the hw engineers were really proud of the page coloring they've achieved in their first dual channel dram controller with bit17 - after all Bspec explains in great length the optimal layout of page frame numbers modulo 4 for the color and depth buffers, too. Later on when they've started to work on VT-d they shamefully discoverd their stupidity and tried to cover the tracks ... Tested-by: Daniel Vetter daniel.vet...@ffwll.ch (i915g) Tested-by: Pavel Ondračka pavel.ondra...@email.cz (i945g) Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=42625 Cc: sta...@kernel.org Signed-Off-by: Daniel Vetter daniel.vet...@ffwll.ch --- drivers/gpu/drm/i915/i915_gem_tiling.c |4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c index 31d334d..861223b 100644 --- a/drivers/gpu/drm/i915/i915_gem_tiling.c +++ b/drivers/gpu/drm/i915/i915_gem_tiling.c @@ -107,10 +107,10 @@ i915_gem_detect_bit_6_swizzle(struct drm_device *dev) */ swizzle_x = I915_BIT_6_SWIZZLE_NONE; swizzle_y = I915_BIT_6_SWIZZLE_NONE; - } else if (IS_MOBILE(dev)) { + } else if (IS_MOBILE(dev) || (IS_GEN3(dev) !IS_G33(dev))) { uint32_t dcc; - /* On mobile 9xx chipsets, channel interleave by the CPU is + /* On 9xx chipsets, channel interleave by the CPU is * determined by DCC. For single-channel, neither the CPU * nor the GPU do swizzling. For dual channel interleaved, * the GPU's interleave is bit 9 and 10 for X tiled, and bit -- 1.7.7.3 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 19/43] drm/i915: add debugfs file for swizzling information
This will also come handy for the gen6+ swizzling support, where the driver is supposed to control swizzling depending upon dram configuration. v2: CxDRB3 are 16 bit regs! Noticed by Chris Wilson. Signed-Off-by: Daniel Vetter daniel.vet...@ffwll.ch --- drivers/gpu/drm/i915/i915_debugfs.c | 50 +++ 1 files changed, 50 insertions(+), 0 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 4a30756..3eab427 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -1335,6 +1335,55 @@ static int i915_gen6_forcewake_count_info(struct seq_file *m, void *data) return 0; } +static const char *swizzle_string(unsigned swizzle) +{ + switch(swizzle) { + case I915_BIT_6_SWIZZLE_NONE: + return none; + case I915_BIT_6_SWIZZLE_9: + return bit9; + case I915_BIT_6_SWIZZLE_9_10: + return bit9/bit10; + case I915_BIT_6_SWIZZLE_9_11: + return bit9/bit11; + case I915_BIT_6_SWIZZLE_9_10_11: + return bit9/bit10/bit11; + case I915_BIT_6_SWIZZLE_9_17: + return bit9/bit17; + case I915_BIT_6_SWIZZLE_9_10_17: + return bit9/bit10/bit17; + case I915_BIT_6_SWIZZLE_UNKNOWN: + return unkown; + } + + return bug; +} + +static int i915_swizzle_info(struct seq_file *m, void *data) +{ + 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; + + mutex_lock(dev-struct_mutex); + seq_printf(m, bit6 swizzle for X-tiling = %s\n, + swizzle_string(dev_priv-mm.bit_6_swizzle_x)); + seq_printf(m, bit6 swizzle for Y-tiling = %s\n, + swizzle_string(dev_priv-mm.bit_6_swizzle_y)); + + if (IS_GEN3(dev) || IS_GEN4(dev)) { + seq_printf(m, DDC = 0x%08x\n, + I915_READ(DCC)); + seq_printf(m, C0DRB3 = 0x%04x\n, + I915_READ16(C0DRB3)); + seq_printf(m, C1DRB3 = 0x%04x\n, + I915_READ16(C1DRB3)); + } + mutex_unlock(dev-struct_mutex); + + return 0; +} + static int i915_debugfs_common_open(struct inode *inode, struct file *filp) @@ -1736,6 +1785,7 @@ static struct drm_info_list i915_debugfs_list[] = { {i915_gem_framebuffer, i915_gem_framebuffer_info, 0}, {i915_context_status, i915_context_status, 0}, {i915_gen6_forcewake_count, i915_gen6_forcewake_count_info, 0}, + {i915_swizzle_info, i915_swizzle_info, 0}, }; #define I915_DEBUGFS_ENTRIES ARRAY_SIZE(i915_debugfs_list) -- 1.7.7.3 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 20/43] drm/i915: swizzling support for snb/ivb
We have to do this manually. Somebody had a Great Idea. Signed-Off-by: Daniel Vetter daniel.vet...@ffwll.ch --- drivers/gpu/drm/i915/i915_dma.c|2 +- drivers/gpu/drm/i915/i915_drv.c|4 ++- drivers/gpu/drm/i915/i915_drv.h|3 +- drivers/gpu/drm/i915/i915_gem.c| 23 - drivers/gpu/drm/i915/i915_gem_tiling.c | 16 +- drivers/gpu/drm/i915/i915_reg.h| 33 6 files changed, 74 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 448d5b1..4c21c67 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1202,7 +1202,7 @@ static int i915_load_gem_init(struct drm_device *dev) i915_gem_do_init(dev, 0, mappable_size, gtt_size - PAGE_SIZE); mutex_lock(dev-struct_mutex); - ret = i915_gem_init_ringbuffer(dev); + ret = i915_gem_init_hw(dev); mutex_unlock(dev-struct_mutex); if (ret) return ret; diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 6dd219b..f12b43e 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -494,7 +494,7 @@ static int i915_drm_thaw(struct drm_device *dev) mutex_lock(dev-struct_mutex); dev_priv-mm.suspended = 0; - error = i915_gem_init_ringbuffer(dev); + error = i915_gem_init_hw(dev); mutex_unlock(dev-struct_mutex); if (HAS_PCH_SPLIT(dev)) @@ -690,6 +690,8 @@ int i915_reset(struct drm_device *dev, u8 flags) !dev_priv-mm.suspended) { dev_priv-mm.suspended = 0; + i915_gem_init_swizzling(dev); + dev_priv-ring[RCS].init(dev_priv-ring[RCS]); if (HAS_BSD(dev)) dev_priv-ring[VCS].init(dev_priv-ring[VCS]); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index b46fac5..311a4e1 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1206,7 +1206,8 @@ int __must_check i915_gem_object_set_domain(struct drm_i915_gem_object *obj, uint32_t read_domains, uint32_t write_domain); int __must_check i915_gem_object_finish_gpu(struct drm_i915_gem_object *obj); -int __must_check i915_gem_init_ringbuffer(struct drm_device *dev); +int __must_check i915_gem_init_hw(struct drm_device *dev); +void i915_gem_init_swizzling(struct drm_device *dev); void i915_gem_cleanup_ringbuffer(struct drm_device *dev); void i915_gem_do_init(struct drm_device *dev, unsigned long start, diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index e995248..39459d2 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -3744,12 +3744,31 @@ i915_gem_idle(struct drm_device *dev) return 0; } +void i915_gem_init_swizzling(struct drm_device *dev) +{ + drm_i915_private_t *dev_priv = dev-dev_private; + + if (INTEL_INFO(dev)-gen 6 || + dev_priv-mm.bit_6_swizzle_x == I915_BIT_6_SWIZZLE_NONE) + return; + + I915_WRITE(TILECTL, I915_READ(TILECTL) | TILECTL_SWZCTL); + if (IS_GEN6(dev)) + I915_WRITE(ARB_MODE, ARB_MODE_ENABLE(ARB_MODE_SWIZZLE_SNB)); + else + I915_WRITE(ARB_MODE, ARB_MODE_ENABLE(ARB_MODE_SWIZZLE_IVB)); + I915_WRITE(DISP_ARB_CTL, I915_READ(DISP_ARB_CTL) | +DISP_TILE_SURFACE_SWIZZLING); + +} int -i915_gem_init_ringbuffer(struct drm_device *dev) +i915_gem_init_hw(struct drm_device *dev) { drm_i915_private_t *dev_priv = dev-dev_private; int ret; + i915_gem_init_swizzling(dev); + ret = intel_init_render_ring_buffer(dev); if (ret) return ret; @@ -3805,7 +3824,7 @@ i915_gem_entervt_ioctl(struct drm_device *dev, void *data, mutex_lock(dev-struct_mutex); dev_priv-mm.suspended = 0; - ret = i915_gem_init_ringbuffer(dev); + ret = i915_gem_init_hw(dev); if (ret != 0) { mutex_unlock(dev-struct_mutex); return ret; diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c index 861223b..af0a2fc 100644 --- a/drivers/gpu/drm/i915/i915_gem_tiling.c +++ b/drivers/gpu/drm/i915/i915_gem_tiling.c @@ -93,8 +93,20 @@ i915_gem_detect_bit_6_swizzle(struct drm_device *dev) uint32_t swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN; if (INTEL_INFO(dev)-gen = 6) { - swizzle_x = I915_BIT_6_SWIZZLE_NONE; - swizzle_y = I915_BIT_6_SWIZZLE_NONE; + uint32_t dimm_c0, dimm_c1; + dimm_c0 = I915_READ(MAD_DIMM_C0); + dimm_c1 = I915_READ(MAD_DIMM_C1); +
[Intel-gfx] [PATCH 21/43] drm/i915: add gen6+ registers to i915_swizzle_info
Signed-Off-by: Daniel Vetter daniel.vet...@ffwll.ch --- drivers/gpu/drm/i915/i915_debugfs.c | 13 + 1 files changed, 13 insertions(+), 0 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 3eab427..5ab7784 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -1378,6 +1378,19 @@ static int i915_swizzle_info(struct seq_file *m, void *data) I915_READ16(C0DRB3)); seq_printf(m, C1DRB3 = 0x%04x\n, I915_READ16(C1DRB3)); + } else if (IS_GEN6(dev) || IS_GEN7(dev)) { + seq_printf(m, MAD_DIMM_C0 = 0x%08x\n, + I915_READ(MAD_DIMM_C0)); + seq_printf(m, MAD_DIMM_C1 = 0x%08x\n, + I915_READ(MAD_DIMM_C1)); + seq_printf(m, MAD_DIMM_C2 = 0x%08x\n, + I915_READ(MAD_DIMM_C2)); + seq_printf(m, TILECTL = 0x%08x\n, + I915_READ(TILECTL)); + seq_printf(m, ARB_MODE = 0x%08x\n, + I915_READ(ARB_MODE)); + seq_printf(m, DISP_ARB_CTL = 0x%08x\n, + I915_READ(DISP_ARB_CTL)); } mutex_unlock(dev-struct_mutex); -- 1.7.7.3 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 23/43] drm/i915: multithreaded forcewake is an ivb+ feature
Name the function accordingly. Suggested by Chris Wilson. Signed-Off-by: Daniel Vetter daniel.vet...@ffwll.ch Reviewed-by: Eugeni Dodonov eugeni.dodo...@intel.com --- drivers/gpu/drm/i915/i915_drv.c |4 ++-- drivers/gpu/drm/i915/i915_drv.h |4 ++-- drivers/gpu/drm/i915/intel_display.c |8 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index f12b43e..6e0f868 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -344,7 +344,7 @@ void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv) udelay(10); } -void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv) +void __gen7_gt_force_wake_mt_get(struct drm_i915_private *dev_priv) { int count; @@ -382,7 +382,7 @@ void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv) POSTING_READ(FORCEWAKE); } -void __gen6_gt_force_wake_mt_put(struct drm_i915_private *dev_priv) +void __gen7_gt_force_wake_mt_put(struct drm_i915_private *dev_priv) { I915_WRITE_NOTRACE(FORCEWAKE_MT, (116) | 0); POSTING_READ(FORCEWAKE_MT); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 6f1830f..bdbd6d8 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1342,9 +1342,9 @@ extern void intel_detect_pch(struct drm_device *dev); extern int intel_trans_dp_port_sel(struct drm_crtc *crtc); extern void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv); -extern void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv); +extern void __gen7_gt_force_wake_mt_get(struct drm_i915_private *dev_priv); extern void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv); -extern void __gen6_gt_force_wake_mt_put(struct drm_i915_private *dev_priv); +extern void __gen7_gt_force_wake_mt_put(struct drm_i915_private *dev_priv); /* overlay */ #ifdef CONFIG_DEBUG_FS diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 571bf4e..6ac2e73 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -8507,17 +8507,17 @@ static void intel_init_display(struct drm_device *dev) u32 ecobus; mutex_lock(dev-struct_mutex); - __gen6_gt_force_wake_mt_get(dev_priv); + __gen7_gt_force_wake_mt_get(dev_priv); ecobus = I915_READ_NOTRACE(ECOBUS); - __gen6_gt_force_wake_mt_put(dev_priv); + __gen7_gt_force_wake_mt_put(dev_priv); mutex_unlock(dev-struct_mutex); if (ecobus FORCEWAKE_MT_ENABLE) { DRM_DEBUG_KMS(Using MT version of forcewake\n); dev_priv-core.force_wake_get = - __gen6_gt_force_wake_mt_get; + __gen7_gt_force_wake_mt_get; dev_priv-core.force_wake_put = - __gen6_gt_force_wake_mt_put; + __gen7_gt_force_wake_mt_put; } } -- 1.7.7.3 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 24/43] drm/i915: capture error_state also for stuck rings
Since quite a while we also the basic output configuration in the error_state, so it should contain enough information to diagnose these MI_WAIT hangs. Signed-Off-by: Daniel Vetter daniel.vet...@ffwll.ch Reviewed-and-tested-by: Chris Wilson ch...@chris-wilson.co.uk Reviewed-by: Eugeni Dodonov eugeni.dodo...@intel.com --- drivers/gpu/drm/i915/i915_irq.c |3 +-- 1 files changed, 1 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 56f2b2f..0dac9af 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1708,6 +1708,7 @@ void i915_hangcheck_elapsed(unsigned long data) dev_priv-last_instdone1 == instdone1) { if (dev_priv-hangcheck_count++ 1) { DRM_ERROR(Hangcheck timer elapsed... GPU hung\n); + i915_handle_error(dev, true); if (!IS_GEN2(dev)) { /* Is the chip hanging on a WAIT_FOR_EVENT? @@ -1715,7 +1716,6 @@ void i915_hangcheck_elapsed(unsigned long data) * and break the hang. This should work on * all but the second generation chipsets. */ - if (kick_ring(dev_priv-ring[RCS])) goto repeat; @@ -1728,7 +1728,6 @@ void i915_hangcheck_elapsed(unsigned long data) goto repeat; } - i915_handle_error(dev, true); return; } } else { -- 1.7.7.3 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 27/43] drm/i915: flush overlay regfile writes
Better be paranoid. The wmb should flush the wc writes, and the chipset_flush hopefully flushes any mch buffers. There've been a few overlay hangs I've never really diagnosed, unfortunately all the reporters disappeared. Maybe-related: https://bugs.freedesktop.org/show_bug.cgi?id=33309 Signed-Off-by: Daniel Vetter daniel.vet...@ffwll.ch --- drivers/gpu/drm/i915/intel_overlay.c |3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index cdf17d4..f75e892 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c @@ -209,6 +209,9 @@ static void intel_overlay_unmap_regs(struct intel_overlay *overlay, { if (!OVERLAY_NEEDS_PHYSICAL(overlay-dev)) io_mapping_unmap(regs); + + wmb(); + intel_gtt_chipset_flush(); } static int intel_overlay_do_wait_request(struct intel_overlay *overlay, -- 1.7.7.3 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 26/43] drm/i915: Only clear the GPU domains upon a successful finish
From: Chris Wilson ch...@chris-wilson.co.uk By clearing the GPU read domains before waiting upon the buffer, we run the risk of the wait being interrupted and the domains prematurely cleared. The next time we attempt to wait upon the buffer (after userspace handles the signal), we believe that the buffer is idle and so skip the wait. There are a number of bugs across all generations which show signs of an overly haste reuse of active buffers. Such as: https://bugs.freedesktop.org/show_bug.cgi?id=29046 https://bugs.freedesktop.org/show_bug.cgi?id=35863 https://bugs.freedesktop.org/show_bug.cgi?id=38952 https://bugs.freedesktop.org/show_bug.cgi?id=40282 https://bugs.freedesktop.org/show_bug.cgi?id=41098 https://bugs.freedesktop.org/show_bug.cgi?id=41102 https://bugs.freedesktop.org/show_bug.cgi?id=41284 https://bugs.freedesktop.org/show_bug.cgi?id=42141 A couple of those pre-date i915_gem_object_finish_gpu(), so may be unrelated (such as a wild write from a userspace command buffer), but this does look like a convincing cause for most of those bugs. Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk Cc: sta...@kernel.org Reviewed-by: Daniel Vetter daniel.vet...@ffwll.ch Reviewed-by: Eugeni Dodonov eugeni.dodo...@intel.com --- drivers/gpu/drm/i915/i915_gem.c |7 +-- 1 files changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index d560175..036bc58 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -3087,10 +3087,13 @@ i915_gem_object_finish_gpu(struct drm_i915_gem_object *obj) return ret; } + ret = i915_gem_object_wait_rendering(obj); + if (ret) + return ret; + /* Ensure that we invalidate the GPU's caches and TLBs. */ obj-base.read_domains = ~I915_GEM_GPU_DOMAINS; - - return i915_gem_object_wait_rendering(obj); + return 0; } /** -- 1.7.7.3 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 28/43] drm/i915: Handle unmappable buffers during error state capture
From: Chris Wilson ch...@chris-wilson.co.uk As the buffer is not necessarily accessible through the GTT at the time of a GPU hang, and capturing some of its contents is far more valuable than skipping it, provide a clflushed fallback read path. We still prefer to read through the GTT as that is more consistent with the GPU access of the same buffer. So example it will demonstrate any errorneous tiling or swizzling of the command buffer as seen by the GPU. This becomes necessary with use of CPU relocations and lazy GTT binding, but could potentially happen anyway as a result of a pathological error. Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk Reviewed-by: Daniel Vetter daniel.vet...@ffwll.ch --- drivers/gpu/drm/i915/i915_irq.c | 28 +++- 1 files changed, 23 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 0dac9af..7d06bc5 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -720,7 +720,6 @@ i915_error_object_create(struct drm_i915_private *dev_priv, reloc_offset = src-gtt_offset; for (page = 0; page page_count; page++) { unsigned long flags; - void __iomem *s; void *d; d = kmalloc(PAGE_SIZE, GFP_ATOMIC); @@ -728,10 +727,29 @@ i915_error_object_create(struct drm_i915_private *dev_priv, goto unwind; local_irq_save(flags); - s = io_mapping_map_atomic_wc(dev_priv-mm.gtt_mapping, -reloc_offset); - memcpy_fromio(d, s, PAGE_SIZE); - io_mapping_unmap_atomic(s); + if (reloc_offset dev_priv-mm.gtt_mappable_end) { + void __iomem *s; + + /* Simply ignore tiling or any overlapping fence. +* It's part of the error state, and this hopefully +* captures what the GPU read. +*/ + + s = io_mapping_map_atomic_wc(dev_priv-mm.gtt_mapping, +reloc_offset); + memcpy_fromio(d, s, PAGE_SIZE); + io_mapping_unmap_atomic(s); + } else { + void *s; + + drm_clflush_pages(src-pages[page], 1); + + s = kmap_atomic(src-pages[page]); + memcpy(d, s, PAGE_SIZE); + kunmap_atomic(s); + + drm_clflush_pages(src-pages[page], 1); + } local_irq_restore(flags); dst-pages[page] = d; -- 1.7.7.3 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 29/43] drm/i915: remove the i915_batchbuffer_info debugfs file
With the error_state facility in place, this has outlived it's usefulness. It also oopses with the lates llc-reloc patches because it directly access objects through the gtt without any checks. Signed-Off-by: Daniel Vetter daniel.vet...@ffwll.ch Reviewed-by: Chris Wilson ch...@chris-wilson.co.uk Reviewed-by: Eugeni Dodonov eugeni.dodo...@intel.com --- drivers/gpu/drm/i915/i915_debugfs.c | 40 --- 1 files changed, 0 insertions(+), 40 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 5ab7784..aa305a6 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -562,45 +562,6 @@ static int i915_hws_info(struct seq_file *m, void *data) return 0; } -static void i915_dump_object(struct seq_file *m, -struct io_mapping *mapping, -struct drm_i915_gem_object *obj) -{ - int page, page_count, i; - - page_count = obj-base.size / PAGE_SIZE; - for (page = 0; page page_count; page++) { - u32 *mem = io_mapping_map_wc(mapping, -obj-gtt_offset + page * PAGE_SIZE); - for (i = 0; i PAGE_SIZE; i += 4) - seq_printf(m, %08x : %08x\n, i, mem[i / 4]); - io_mapping_unmap(mem); - } -} - -static int i915_batchbuffer_info(struct seq_file *m, void *data) -{ - struct drm_info_node *node = (struct drm_info_node *) m-private; - struct drm_device *dev = node-minor-dev; - drm_i915_private_t *dev_priv = dev-dev_private; - struct drm_i915_gem_object *obj; - int ret; - - ret = mutex_lock_interruptible(dev-struct_mutex); - if (ret) - return ret; - - list_for_each_entry(obj, dev_priv-mm.active_list, mm_list) { - if (obj-base.read_domains I915_GEM_DOMAIN_COMMAND) { - seq_printf(m, --- gtt_offset = 0x%08x\n, obj-gtt_offset); - i915_dump_object(m, dev_priv-mm.gtt_mapping, obj); - } - } - - mutex_unlock(dev-struct_mutex); - return 0; -} - static int i915_ringbuffer_data(struct seq_file *m, void *data) { struct drm_info_node *node = (struct drm_info_node *) m-private; @@ -1782,7 +1743,6 @@ static struct drm_info_list i915_debugfs_list[] = { {i915_bsd_ringbuffer_info, i915_ringbuffer_info, 0, (void *)VCS}, {i915_blt_ringbuffer_data, i915_ringbuffer_data, 0, (void *)BCS}, {i915_blt_ringbuffer_info, i915_ringbuffer_info, 0, (void *)BCS}, - {i915_batchbuffers, i915_batchbuffer_info, 0}, {i915_error_state, i915_error_state, 0}, {i915_rstdby_delays, i915_rstdby_delays, 0}, {i915_cur_delayinfo, i915_cur_delayinfo, 0}, -- 1.7.7.3 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 30/43] drm/i915: reject GTT domain in relocations
This confuses our domain tracking and can (for gtt write domains) lead to a subsequent oops. Tested by tests/gem_exec_bad_domains from i-g-t. Signed-Off-by: Daniel Vetter daniel.vet...@ffwll.ch Reviewed-by: Eric Anholt e...@anholt.net Reviewed-by: Chris Wilson ch...@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_gem_execbuffer.c |5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index c918124..30b7862 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -302,8 +302,9 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, reloc-write_domain); return ret; } - if (unlikely((reloc-write_domain | reloc-read_domains) I915_GEM_DOMAIN_CPU)) { - DRM_ERROR(reloc with read/write CPU domains: + if (unlikely((reloc-write_domain | reloc-read_domains) + ~I915_GEM_GPU_DOMAINS)) { + DRM_ERROR(reloc with read/write non-GPU domains: obj %p target %d offset %d read %08x write %08x, obj, reloc-target_handle, -- 1.7.7.3 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 31/43] drm/i915: Use kcalloc instead of kzalloc to allocate array
From: Thomas Meyer tho...@m3y3r.de The advantage of kcalloc is, that will prevent integer overflows which could result from the multiplication of number of elements and size and it is also a bit nicer to read. The semantic patch that makes this change is available in https://lkml.org/lkml/2011/11/25/107 Signed-off-by: Thomas Meyer tho...@m3y3r.de Signed-Off-by: Daniel Vetter daniel.vet...@ffwll.ch --- drivers/gpu/drm/i915/intel_bios.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index 63880e2..5065633 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c @@ -572,7 +572,7 @@ parse_device_mapping(struct drm_i915_private *dev_priv, DRM_DEBUG_KMS(no child dev is parsed from VBT\n); return; } - dev_priv-child_dev = kzalloc(sizeof(*p_child) * count, GFP_KERNEL); + dev_priv-child_dev = kcalloc(count, sizeof(*p_child), GFP_KERNEL); if (!dev_priv-child_dev) { DRM_DEBUG_KMS(No memory space for child device\n); return; -- 1.7.7.3 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 32/43] drm/i915: Avoid using mappable space for relocation processing through the CPU
From: Chris Wilson ch...@chris-wilson.co.uk We try to avoid writing the relocations through the uncached GTT, if the buffer is currently in the CPU write domain and so will be flushed out to main memory afterwards anyway. Also on SandyBridge we can safely write to the pages in cacheable memory, so long as the buffer is LLC mapped. In either of these caches, we therefore do not need to force the reallocation of the buffer into the mappable region of the GTT, reducing the aperture pressure. Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk Reviewed-by: Daniel Vetter daniel.vet...@ffwll.ch --- drivers/gpu/drm/i915/i915_drv.h|2 + drivers/gpu/drm/i915/i915_gem.c|4 +-- drivers/gpu/drm/i915/i915_gem_execbuffer.c | 36 +++ 3 files changed, 28 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index bdbd6d8..1cafe32 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1226,6 +1226,8 @@ int __must_check i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, bool write); int __must_check +i915_gem_object_set_to_cpu_domain(struct drm_i915_gem_object *obj, bool write); +int __must_check i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj, u32 alignment, struct intel_ring_buffer *pipelined); diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 036bc58..7ada9d2 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -39,8 +39,6 @@ static __must_check int i915_gem_object_flush_gpu_write_domain(struct drm_i915_gem_object *obj); static void i915_gem_object_flush_gtt_write_domain(struct drm_i915_gem_object *obj); static void i915_gem_object_flush_cpu_write_domain(struct drm_i915_gem_object *obj); -static __must_check int i915_gem_object_set_to_cpu_domain(struct drm_i915_gem_object *obj, - bool write); static __must_check int i915_gem_object_set_cpu_read_domain_range(struct drm_i915_gem_object *obj, uint64_t offset, uint64_t size); @@ -3102,7 +3100,7 @@ i915_gem_object_finish_gpu(struct drm_i915_gem_object *obj) * This function returns when the move is complete, including waiting on * flushes to occur. */ -static int +int i915_gem_object_set_to_cpu_domain(struct drm_i915_gem_object *obj, bool write) { uint32_t old_write_domain, old_read_domains; diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 30b7862..7e65505 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -265,6 +265,12 @@ eb_destroy(struct eb_objects *eb) kfree(eb); } +static inline int use_cpu_reloc(struct drm_i915_gem_object *obj) +{ + return (obj-base.write_domain == I915_GEM_DOMAIN_CPU || + obj-cache_level != I915_CACHE_NONE); +} + static int i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, struct eb_objects *eb, @@ -351,11 +357,19 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, return ret; } + /* We can't wait for rendering with pagefaults disabled */ + if (obj-active in_atomic()) + return -EFAULT; + reloc-delta += target_offset; - if (obj-base.write_domain == I915_GEM_DOMAIN_CPU) { + if (use_cpu_reloc(obj)) { uint32_t page_offset = reloc-offset ~PAGE_MASK; char *vaddr; + ret = i915_gem_object_set_to_cpu_domain(obj, 1); + if (ret) + return ret; + vaddr = kmap_atomic(obj-pages[reloc-offset PAGE_SHIFT]); *(uint32_t *)(vaddr + page_offset) = reloc-delta; kunmap_atomic(vaddr); @@ -364,10 +378,6 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, uint32_t __iomem *reloc_entry; void __iomem *reloc_page; - /* We can't wait for rendering with pagefaults disabled */ - if (obj-active in_atomic()) - return -EFAULT; - ret = i915_gem_object_set_to_gtt_domain(obj, 1); if (ret) return ret; @@ -464,6 +474,13 @@ i915_gem_execbuffer_relocate(struct drm_device *dev, #define __EXEC_OBJECT_HAS_FENCE (131) static int +need_reloc_mappable(struct drm_i915_gem_object *obj) +{ + struct drm_i915_gem_exec_object2 *entry = obj-exec_entry; + return entry-relocation_count !use_cpu_reloc(obj); +} + +static int
[Intel-gfx] [PATCH 33/43] drm/i915: fall through pwrite_gtt_slow to the shmem slow path
The gtt_pwrite slowpath grabs the userspace memory with get_user_pages. This will not work for non-page backed memory, like a gtt mmapped gem object. Hence fall throuh to the shmem paths if we hit -EFAULT in the gtt paths. Now the shmem paths have exactly the same problem, but this way we only need to rearrange the code in one write path. v2: v1 accidentaly falls back to shmem pwrite for phys objects. Fixed. v3: Make the codeflow around phys_pwrite cleara as suggested by Chris Wilson. Signed-Off-by: Daniel Vetter daniel.vet...@ffwll.ch Reviewed-by: Chris Wilson ch...@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_gem.c | 33 + 1 files changed, 21 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 7ada9d2..f74ecb8 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -994,10 +994,13 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, * pread/pwrite currently are reading and writing from the CPU * perspective, requiring manual detiling by the client. */ - if (obj-phys_obj) + if (obj-phys_obj) { ret = i915_gem_phys_pwrite(dev, obj, args, file); - else if (obj-gtt_space -obj-base.write_domain != I915_GEM_DOMAIN_CPU) { + goto out; + } + + if (obj-gtt_space + obj-base.write_domain != I915_GEM_DOMAIN_CPU) { ret = i915_gem_object_pin(obj, 0, true); if (ret) goto out; @@ -1016,18 +1019,24 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, out_unpin: i915_gem_object_unpin(obj); - } else { - ret = i915_gem_object_set_to_cpu_domain(obj, 1); - if (ret) - goto out; - ret = -EFAULT; - if (!i915_gem_object_needs_bit17_swizzle(obj)) - ret = i915_gem_shmem_pwrite_fast(dev, obj, args, file); - if (ret == -EFAULT) - ret = i915_gem_shmem_pwrite_slow(dev, obj, args, file); + if (ret != -EFAULT) + goto out; + /* Fall through to the shmfs paths because the gtt paths might +* fail with non-page-backed user pointers (e.g. gtt mappings +* when moving data between textures). */ } + ret = i915_gem_object_set_to_cpu_domain(obj, 1); + if (ret) + goto out; + + ret = -EFAULT; + if (!i915_gem_object_needs_bit17_swizzle(obj)) + ret = i915_gem_shmem_pwrite_fast(dev, obj, args, file); + if (ret == -EFAULT) + ret = i915_gem_shmem_pwrite_slow(dev, obj, args, file); + out: drm_gem_object_unreference(obj-base); unlock: -- 1.7.7.3 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 34/43] drm/i915: rewrite shmem_pwrite_slow to use copy_from_user
... instead of get_user_pages, because that fails on non page-backed user addresses like e.g. a gtt mapping of a bo. To get there essentially copy the vfs read path into pagecache. We can't call that right away because we have to take care of bit17 swizzling. To not deadlock with our own pagefault handler we need to completely drop struct_mutex, reducing the atomicty-guarantees of our userspace abi. Implications for racing with other gem ioctl: - execbuf, pwrite, pread: Due to -EFAULT fallback to slow paths there's already the risk of the pwrite call not being atomic, no degration. - read/write access to mmaps: already fully racy, no degration. - set_tiling: Calling set_tiling while reading/writing is already pretty much undefined, now it just got a bit worse. set_tiling is only called by libdrm on unused/new bos, so no problem. - set_domain: When changing to the gtt domain while copying (without any read/write access, e.g. for synchronization), we might leave unflushed data in the cpu caches. The clflush_object at the end of pwrite_slow takes care of this problem. - truncating of purgeable objects: the shmem_read_mapping_page call could reinstate backing storage for truncated objects. The check at the end of pwrite_slow takes care of this. v2: - add missing intel_gtt_chipset_flush - add __ to copy_from_user_swizzled as suggest by Chris Wilson. v3: Fixup bit17 swizzling, it swizzled the wrong pages. Signed-off-by: Daniel Vetter daniel.vet...@ffwll.ch Reviewed-by: Chris Wilson ch...@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_gem.c | 127 --- 1 files changed, 65 insertions(+), 62 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index f74ecb8..78776a4 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -56,6 +56,7 @@ static void i915_gem_free_object_tail(struct drm_i915_gem_object *obj); static int i915_gem_inactive_shrink(struct shrinker *shrinker, struct shrink_control *sc); +static void i915_gem_object_truncate(struct drm_i915_gem_object *obj); /* some bookkeeping */ static void i915_gem_info_add_obj(struct drm_i915_private *dev_priv, @@ -383,6 +384,32 @@ i915_gem_shmem_pread_fast(struct drm_device *dev, return 0; } +static inline int +__copy_from_user_swizzled(char __user *gpu_vaddr, int gpu_offset, + const char *cpu_vaddr, + int length) +{ + int ret, cpu_offset = 0; + + while (length 0) { + int cacheline_end = ALIGN(gpu_offset + 1, 64); + int this_length = min(cacheline_end - gpu_offset, length); + int swizzled_gpu_offset = gpu_offset ^ 64; + + ret = __copy_from_user(gpu_vaddr + swizzled_gpu_offset, + cpu_vaddr + cpu_offset, + this_length); + if (ret) + return ret + length; + + cpu_offset += this_length; + gpu_offset += this_length; + length -= this_length; + } + + return 0; +} + /** * This is the fallback shmem pread path, which allocates temporary storage * in kernel space to copy_to_user into outside of the struct_mutex, so we @@ -839,71 +866,36 @@ i915_gem_shmem_pwrite_slow(struct drm_device *dev, struct drm_file *file) { struct address_space *mapping = obj-base.filp-f_path.dentry-d_inode-i_mapping; - struct mm_struct *mm = current-mm; - struct page **user_pages; ssize_t remain; - loff_t offset, pinned_pages, i; - loff_t first_data_page, last_data_page, num_pages; - int shmem_page_offset; - int data_page_index, data_page_offset; - int page_length; - int ret; - uint64_t data_ptr = args-data_ptr; - int do_bit17_swizzling; + loff_t offset; + char __user *user_data; + int shmem_page_offset, page_length, ret; + int obj_do_bit17_swizzling, page_do_bit17_swizzling; + user_data = (char __user *) (uintptr_t) args-data_ptr; remain = args-size; - /* Pin the user pages containing the data. We can't fault while -* holding the struct mutex, and all of the pwrite implementations -* want to hold it while dereferencing the user data. -*/ - first_data_page = data_ptr / PAGE_SIZE; - last_data_page = (data_ptr + args-size - 1) / PAGE_SIZE; - num_pages = last_data_page - first_data_page + 1; - - user_pages = drm_malloc_ab(num_pages, sizeof(struct page *)); - if (user_pages == NULL) - return -ENOMEM; - - mutex_unlock(dev-struct_mutex); - down_read(mm-mmap_sem); - pinned_pages = get_user_pages(current, mm, (uintptr_t)args-data_ptr, - num_pages, 0, 0, user_pages, NULL); -
[Intel-gfx] [PATCH 35/43] drm/i915: rewrite shmem_pread_slow to use copy_to_user
Like for shmem_pwrite_slow. The only difference is that because we read data, we can leave the fetched cachelines in the cpu: In the case that the object isn't in the cpu read domain anymore, the clflush for the next cpu read domain invalidation will simply drop these cachelines. slow_shmem_bit17_copy is now ununsed, so kill it. With this patch tests/gem_mmap_gtt now actually works. v2: add __ to copy_to_user_swizzled as suggested by Chris Wilson. v3: Fixup the swizzling logic, it swizzled the wrong pages. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=38115 Signed-off-by: Daniel Vetter daniel.vet...@ffwll.ch Reviewed-by: Chris Wilson ch...@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_gem.c | 191 --- 1 files changed, 57 insertions(+), 134 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 78776a4..d38e2e6 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -257,73 +257,6 @@ static int i915_gem_object_needs_bit17_swizzle(struct drm_i915_gem_object *obj) obj-tiling_mode != I915_TILING_NONE; } -static inline void -slow_shmem_copy(struct page *dst_page, - int dst_offset, - struct page *src_page, - int src_offset, - int length) -{ - char *dst_vaddr, *src_vaddr; - - dst_vaddr = kmap(dst_page); - src_vaddr = kmap(src_page); - - memcpy(dst_vaddr + dst_offset, src_vaddr + src_offset, length); - - kunmap(src_page); - kunmap(dst_page); -} - -static inline void -slow_shmem_bit17_copy(struct page *gpu_page, - int gpu_offset, - struct page *cpu_page, - int cpu_offset, - int length, - int is_read) -{ - char *gpu_vaddr, *cpu_vaddr; - - /* Use the unswizzled path if this page isn't affected. */ - if ((page_to_phys(gpu_page) (1 17)) == 0) { - if (is_read) - return slow_shmem_copy(cpu_page, cpu_offset, - gpu_page, gpu_offset, length); - else - return slow_shmem_copy(gpu_page, gpu_offset, - cpu_page, cpu_offset, length); - } - - gpu_vaddr = kmap(gpu_page); - cpu_vaddr = kmap(cpu_page); - - /* Copy the data, XORing A6 with A17 (1). The user already knows he's -* XORing with the other bits (A9 for Y, A9 and A10 for X) -*/ - while (length 0) { - int cacheline_end = ALIGN(gpu_offset + 1, 64); - int this_length = min(cacheline_end - gpu_offset, length); - int swizzled_gpu_offset = gpu_offset ^ 64; - - if (is_read) { - memcpy(cpu_vaddr + cpu_offset, - gpu_vaddr + swizzled_gpu_offset, - this_length); - } else { - memcpy(gpu_vaddr + swizzled_gpu_offset, - cpu_vaddr + cpu_offset, - this_length); - } - cpu_offset += this_length; - gpu_offset += this_length; - length -= this_length; - } - - kunmap(cpu_page); - kunmap(gpu_page); -} - /** * This is the fast shmem pread path, which attempts to copy_from_user directly * from the backing pages of the object to the user's address space. On a @@ -385,6 +318,32 @@ i915_gem_shmem_pread_fast(struct drm_device *dev, } static inline int +__copy_to_user_swizzled(char __user *cpu_vaddr, + const char *gpu_vaddr, int gpu_offset, + int length) +{ + int ret, cpu_offset = 0; + + while (length 0) { + int cacheline_end = ALIGN(gpu_offset + 1, 64); + int this_length = min(cacheline_end - gpu_offset, length); + int swizzled_gpu_offset = gpu_offset ^ 64; + + ret = __copy_to_user(cpu_vaddr + cpu_offset, +gpu_vaddr + swizzled_gpu_offset, +this_length); + if (ret) + return ret + length; + + cpu_offset += this_length; + gpu_offset += this_length; + length -= this_length; + } + + return 0; +} + +static inline int __copy_from_user_swizzled(char __user *gpu_vaddr, int gpu_offset, const char *cpu_vaddr, int length) @@ -423,72 +382,34 @@ i915_gem_shmem_pread_slow(struct drm_device *dev, struct drm_file *file) { struct address_space *mapping = obj-base.filp-f_path.dentry-d_inode-i_mapping; - struct mm_struct *mm = current-mm; - struct page **user_pages; + char __user
[Intel-gfx] [PATCH 37/43] agp/intel-gtt: export the gtt pagetable iomapping
We need this because ppgtt page directory entries need to be in the global gtt pagetable. Signed-Off-by: Daniel Vetter daniel.vet...@ffwll.ch Reviewed-by: Ben Widawsky b...@bwidawsk.net --- drivers/char/agp/intel-gtt.c |1 + include/drm/intel-gtt.h |2 ++ 2 files changed, 3 insertions(+), 0 deletions(-) diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c index 0a305ac..5cf47ac 100644 --- a/drivers/char/agp/intel-gtt.c +++ b/drivers/char/agp/intel-gtt.c @@ -680,6 +680,7 @@ static int intel_gtt_init(void) iounmap(intel_private.registers); return -ENOMEM; } + intel_private.base.gtt = intel_private.gtt; global_cache_flush(); /* FIXME: ? */ diff --git a/include/drm/intel-gtt.h b/include/drm/intel-gtt.h index 6d4c77a..0a0001b 100644 --- a/include/drm/intel-gtt.h +++ b/include/drm/intel-gtt.h @@ -17,6 +17,8 @@ const struct intel_gtt { unsigned int do_idle_maps : 1; /* Share the scratch page dma with ppgtts. */ dma_addr_t scratch_page_dma; + /* for ppgtt PDE access */ + u32 __iomem *gtt; } *intel_gtt_get(void); void intel_gtt_chipset_flush(void); -- 1.7.7.3 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 38/43] drm/i915: initialization/teardown for the aliasing ppgtt
This just adds the setup and teardown code for the ppgtt PDE and the last-level pagetables, which are fixed for the entire lifetime, at least for the moment. v2: Kill the stray debug printk noted by and improve the pte definitions as suggested by Chris Wilson. v3: Clean up the aperture stealing code as noted by Ben Widawsky. v4: Paint the init code in a more pleasing colour as suggest by Chris Wilson. v5: Explain the magic numbers noticed by Ben Widawsky. Signed-Off-by: Daniel Vetter daniel.vet...@ffwll.ch Reviewed-by: Ben Widawsky b...@bwidawsk.net --- drivers/gpu/drm/i915/i915_dma.c | 41 --- drivers/gpu/drm/i915/i915_drv.h | 18 + drivers/gpu/drm/i915/i915_gem_gtt.c | 139 +++ drivers/gpu/drm/i915/i915_reg.h | 16 4 files changed, 203 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index fd617fb..2cc0ba4 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1190,22 +1190,39 @@ static int i915_load_gem_init(struct drm_device *dev) /* Basic memrange allocator for stolen space */ drm_mm_init(dev_priv-mm.stolen, 0, prealloc_size); - /* Let GEM Manage all of the aperture. -* -* However, leave one page at the end still bound to the scratch page. -* There are a number of places where the hardware apparently -* prefetches past the end of the object, and we've seen multiple -* hangs with the GPU head pointer stuck in a batchbuffer bound -* at the last page of the aperture. One page should be enough to -* keep any prefetching inside of the aperture. -*/ - i915_gem_do_init(dev, 0, mappable_size, gtt_size - PAGE_SIZE); + if (HAS_ALIASING_PPGTT(dev)) { + /* PPGTT pdes are stolen from global gtt ptes, so shrink the +* aperture accordingly when using aliasing ppgtt. */ + gtt_size -= I915_PPGTT_PD_ENTRIES*PAGE_SIZE; + /* For paranoia keep the guard page in between. */ + gtt_size -= PAGE_SIZE; + + i915_gem_do_init(dev, 0, mappable_size, gtt_size); + + ret = i915_gem_init_aliasing_ppgtt(dev); + if (ret) + return ret; + } else { + /* Let GEM Manage all of the aperture. +* +* However, leave one page at the end still bound to the scratch +* page. There are a number of places where the hardware +* apparently prefetches past the end of the object, and we've +* seen multiple hangs with the GPU head pointer stuck in a +* batchbuffer bound at the last page of the aperture. One page +* should be enough to keep any prefetching inside of the +* aperture. +*/ + i915_gem_do_init(dev, 0, mappable_size, gtt_size - PAGE_SIZE); + } mutex_lock(dev-struct_mutex); ret = i915_gem_init_hw(dev); mutex_unlock(dev-struct_mutex); - if (ret) + if (ret) { + i915_gem_cleanup_aliasing_ppgtt(dev); return ret; + } /* Try to set up FBC with a reasonable compressed buffer size */ if (I915_HAS_FBC(dev) i915_powersave) { @@ -1292,6 +1309,7 @@ cleanup_gem: mutex_lock(dev-struct_mutex); i915_gem_cleanup_ringbuffer(dev); mutex_unlock(dev-struct_mutex); + i915_gem_cleanup_aliasing_ppgtt(dev); cleanup_vga_switcheroo: vga_switcheroo_unregister_client(dev-pdev); cleanup_vga_client: @@ -2179,6 +2197,7 @@ int i915_driver_unload(struct drm_device *dev) i915_gem_free_all_phys_object(dev); i915_gem_cleanup_ringbuffer(dev); mutex_unlock(dev-struct_mutex); + i915_gem_cleanup_aliasing_ppgtt(dev); if (I915_HAS_FBC(dev) i915_powersave) i915_cleanup_compression(dev); drm_mm_takedown(dev_priv-mm.stolen); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 1cafe32..2dc5b27 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -254,6 +254,16 @@ struct intel_device_info { u8 has_blt_ring:1; }; +#define I915_PPGTT_PD_ENTRIES 512 +#define I915_PPGTT_PT_ENTRIES 1024 +struct i915_hw_ppgtt { + unsigned num_pd_entries; + struct page **pt_pages; + uint32_t pd_offset; + dma_addr_t *pt_dma_addr; + dma_addr_t scratch_page_dma_addr; +}; + enum no_fbc_reason { FBC_NO_OUTPUT, /* no outputs enabled to compress */ FBC_STOLEN_TOO_SMALL, /* not enough space to hold compressed buffers */ @@ -584,6 +594,9 @@ typedef struct drm_i915_private { struct io_mapping *gtt_mapping; int gtt_mtrr; + /** PPGTT
[Intel-gfx] [PATCH 39/43] drm/i915: ppgtt binding/unbinding support
This adds support to bind/unbind objects and wires it up. Objects are only put into the ppgtt when necessary, i.e. at execbuf time. Objects are still unconditionally put into the global gtt. v2: Kill the quick hack and explicitly pass cache_level to ppgtt_bind like for the global gtt function. Noticed by Chris Wilson. Signed-off-by: Daniel Vetter daniel.vet...@ffwll.ch Reviewed-by: Ben Widawsky b...@bwidawsk.net --- drivers/gpu/drm/i915/i915_drv.h|7 ++ drivers/gpu/drm/i915/i915_gem.c| 11 ++ drivers/gpu/drm/i915/i915_gem_execbuffer.c |9 ++ drivers/gpu/drm/i915/i915_gem_gtt.c| 146 ++- 4 files changed, 167 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 2dc5b27..66b4c87 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -854,6 +854,8 @@ struct drm_i915_gem_object { unsigned int cache_level:2; + unsigned int has_aliasing_ppgtt_mapping:1; + struct page **pages; /** @@ -1266,6 +1268,11 @@ int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj, /* i915_gem_gtt.c */ int __must_check i915_gem_init_aliasing_ppgtt(struct drm_device *dev); void i915_gem_cleanup_aliasing_ppgtt(struct drm_device *dev); +void i915_ppgtt_bind_object(struct i915_hw_ppgtt *ppgtt, + struct drm_i915_gem_object *obj, + enum i915_cache_level cache_level); +void i915_ppgtt_unbind_object(struct i915_hw_ppgtt *ppgtt, + struct drm_i915_gem_object *obj); void i915_gem_restore_gtt_mappings(struct drm_device *dev); int __must_check i915_gem_gtt_bind_object(struct drm_i915_gem_object *obj); diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index d38e2e6..f231b80 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2022,6 +2022,7 @@ static void i915_gem_object_finish_gtt(struct drm_i915_gem_object *obj) int i915_gem_object_unbind(struct drm_i915_gem_object *obj) { + drm_i915_private_t *dev_priv = obj-base.dev-dev_private; int ret = 0; if (obj-gtt_space == NULL) @@ -2066,6 +2067,11 @@ i915_gem_object_unbind(struct drm_i915_gem_object *obj) trace_i915_gem_object_unbind(obj); i915_gem_gtt_unbind_object(obj); + if (obj-has_aliasing_ppgtt_mapping) { + i915_ppgtt_unbind_object(dev_priv-mm.aliasing_ppgtt, obj); + obj-has_aliasing_ppgtt_mapping = 0; + } + i915_gem_object_put_pages_gtt(obj); list_del_init(obj-gtt_list); @@ -2882,6 +2888,8 @@ i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, bool write) int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj, enum i915_cache_level cache_level) { + struct drm_device *dev = obj-base.dev; + drm_i915_private_t *dev_priv = dev-dev_private; int ret; if (obj-cache_level == cache_level) @@ -2910,6 +2918,9 @@ int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj, } i915_gem_gtt_rebind_object(obj, cache_level); + if (obj-has_aliasing_ppgtt_mapping) + i915_ppgtt_bind_object(dev_priv-mm.aliasing_ppgtt, + obj, cache_level); } if (cache_level == I915_CACHE_NONE) { diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 7e65505..77b2473 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -530,6 +530,7 @@ i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring, struct drm_file *file, struct list_head *objects) { + drm_i915_private_t *dev_priv = ring-dev-dev_private; struct drm_i915_gem_object *obj; int ret, retry; bool has_fenced_gpu_access = INTEL_INFO(ring-dev)-gen 4; @@ -636,6 +637,14 @@ i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring, } i915_gem_object_unpin(obj); + + /* ... and ensure ppgtt mapping exist if needed. */ + if (dev_priv-mm.aliasing_ppgtt !obj-has_aliasing_ppgtt_mapping) { + i915_ppgtt_bind_object(dev_priv-mm.aliasing_ppgtt, + obj, obj-cache_level); + + obj-has_aliasing_ppgtt_mapping = 1; + } } if (ret != -ENOSPC || retry 1) diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 548b885..f895e20 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@
[Intel-gfx] [PATCH 40/43] drm/i915: ppgtt register definitions
Signed-off-by: Daniel Vetter daniel.vet...@ffwll.ch Reviewed-by: Ben Widawsky b...@bwidawsk.net --- drivers/gpu/drm/i915/i915_reg.h | 18 ++ 1 files changed, 18 insertions(+), 0 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 51ec59d..2fa7dfa 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -86,6 +86,13 @@ #define GEN6_MBC_SNPCR_LOW (221) #define GEN6_MBC_SNPCR_MIN (321) /* only 1/16th of the cache is shared */ +#define GEN6_MBCTL 0x0907c +#define GEN6_MBCTL_ENABLE_BOOT_FETCH (1 4) +#define GEN6_MBCTL_CTX_FETCH_NEEDED (1 3) +#define GEN6_MBCTL_BME_UPDATE_ENABLE (1 2) +#define GEN6_MBCTL_MAE_UPDATE_ENABLE (1 1) +#define GEN6_MBCTL_BOOT_FETCH_MECH (1 0) + #define GEN6_GDRST 0x941c #define GEN6_GRDOM_FULL (1 0) #define GEN6_GRDOM_RENDER (1 1) @@ -108,6 +115,16 @@ #define GEN6_PTE_GFDT (1 3) #define GEN6_PTE_ADDR_ENCODE(addr) GEN6_GTT_ADDR_ENCODE(addr) +#define RING_PP_DIR_BASE(ring) ((ring)-mmio_base+0x228) +#define RING_PP_DIR_BASE_READ(ring)((ring)-mmio_base+0x518) +#define RING_PP_DIR_DCLV(ring) ((ring)-mmio_base+0x220) +#define PP_DIR_DCLV_2G 0x + +#define GAM_ECOCHK 0x4090 +#define ECOCHK_SNB_BIT (110) +#define ECOCHK_PPGTT_CACHE64B(0x33) +#define ECOCHK_PPGTT_CACHE4B (0x03) + /* VGA stuff */ #define VGA_ST01_MDA 0x3ba @@ -420,6 +437,7 @@ #define GFX_MODE 0x02520 #define GFX_MODE_GEN7 0x0229c +#define RING_MODE_GEN7(ring) ((ring)-mmio_base+0x29c) #define GFX_RUN_LIST_ENABLE (115) #define GFX_TLB_INVALIDATE_ALWAYS(113) #define GFX_SURFACE_FAULT_ENABLE (112) -- 1.7.7.3 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 41/43] drm/i915: ppgtt debugfs info
Signed-off-by: Daniel Vetter daniel.vet...@ffwll.ch Reviewed-by: Ben Widawsky b...@bwidawsk.net --- drivers/gpu/drm/i915/i915_debugfs.c | 38 +++ 1 files changed, 38 insertions(+), 0 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index aa305a6..c4f8c7e 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -1358,6 +1358,43 @@ static int i915_swizzle_info(struct seq_file *m, void *data) return 0; } +static int i915_ppgtt_info(struct seq_file *m, void *data) +{ + 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, ret; + + + ret = mutex_lock_interruptible(dev-struct_mutex); + if (ret) + return ret; + if (INTEL_INFO(dev)-gen == 6) + seq_printf(m, GFX_MODE: 0x%08x\n, I915_READ(GFX_MODE)); + + for (i = 0; i I915_NUM_RINGS; i++) { + ring = dev_priv-ring[i]; + + seq_printf(m, %s\n, ring-name); + if (INTEL_INFO(dev)-gen == 7) + seq_printf(m, GFX_MODE: 0x%08x\n, I915_READ(RING_MODE_GEN7(ring))); + seq_printf(m, PP_DIR_BASE: 0x%08x\n, I915_READ(RING_PP_DIR_BASE(ring))); + seq_printf(m, PP_DIR_BASE_READ: 0x%08x\n, I915_READ(RING_PP_DIR_BASE_READ(ring))); + seq_printf(m, PP_DIR_DCLV: 0x%08x\n, I915_READ(RING_PP_DIR_DCLV(ring))); + } + if (dev_priv-mm.aliasing_ppgtt) { + struct i915_hw_ppgtt *ppgtt = dev_priv-mm.aliasing_ppgtt; + + seq_printf(m, aliasing PPGTT:\n); + seq_printf(m, pd gtt offset: 0x%08x\n, ppgtt-pd_offset); + } + seq_printf(m, ECOCHK: 0x%08x\n, I915_READ(GAM_ECOCHK)); + mutex_unlock(dev-struct_mutex); + + return 0; +} + static int i915_debugfs_common_open(struct inode *inode, struct file *filp) @@ -1759,6 +1796,7 @@ static struct drm_info_list i915_debugfs_list[] = { {i915_context_status, i915_context_status, 0}, {i915_gen6_forcewake_count, i915_gen6_forcewake_count_info, 0}, {i915_swizzle_info, i915_swizzle_info, 0}, + {i915_ppgtt_info, i915_ppgtt_info, 0}, }; #define I915_DEBUGFS_ENTRIES ARRAY_SIZE(i915_debugfs_list) -- 1.7.7.3 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 42/43] drm/i915: per-ring fault reg
v2: Chris Wilson suggested to allocate the error_state with kzalloc for better paranioa. Also kill existing spurious clears of the error_state while at it. Signed-Off-by: Daniel Vetter daniel.vet...@ffwll.ch Reviewed-by: Ben Widawsky b...@bwidawsk.net --- drivers/gpu/drm/i915/i915_debugfs.c |8 ++-- drivers/gpu/drm/i915/i915_drv.h |2 ++ drivers/gpu/drm/i915/i915_irq.c | 13 +++-- drivers/gpu/drm/i915/i915_reg.h |2 ++ 4 files changed, 17 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index c4f8c7e..8213257 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -716,8 +716,10 @@ static void i915_ring_error_state(struct seq_file *m, if (INTEL_INFO(dev)-gen = 4) seq_printf(m, INSTPS: 0x%08x\n, error-instps[ring]); seq_printf(m, INSTPM: 0x%08x\n, error-instpm[ring]); - if (INTEL_INFO(dev)-gen = 6) + if (INTEL_INFO(dev)-gen = 6) { seq_printf(m, FADDR: 0x%08x\n, error-faddr[ring]); + seq_printf(m, FAULT_REG: 0x%08x\n, error-fault_reg[ring]); + } seq_printf(m, seqno: 0x%08x\n, error-seqno[ring]); } @@ -751,8 +753,10 @@ static int i915_error_state(struct seq_file *m, void *unused) for (i = 0; i dev_priv-num_fence_regs; i++) seq_printf(m, fence[%d] = %08llx\n, i, error-fence[i]); - if (INTEL_INFO(dev)-gen = 6) + if (INTEL_INFO(dev)-gen = 6) { seq_printf(m, ERROR: 0x%08x\n, error-error); + seq_printf(m, DONE_REG: 0x%08x\n, error-done_reg); + } i915_ring_error_state(m, dev, error, RCS); if (HAS_BLT(dev)) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 66b4c87..9b1a7ad 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -167,6 +167,8 @@ struct drm_i915_error_state { u32 instdone1; u32 seqno[I915_NUM_RINGS]; u64 bbaddr; + u32 fault_reg[I915_NUM_RINGS]; + u32 done_reg; u32 faddr[I915_NUM_RINGS]; u64 fence[I915_MAX_NUM_FENCES]; struct timeval time; diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 7d06bc5..b9ba180 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -901,8 +901,10 @@ static void i915_record_ring_state(struct drm_device *dev, { struct drm_i915_private *dev_priv = dev-dev_private; - if (INTEL_INFO(dev)-gen = 6) + if (INTEL_INFO(dev)-gen = 6) { error-faddr[ring-id] = I915_READ(RING_DMA_FADD(ring-mmio_base)); + error-fault_reg[ring-id] = I915_READ(RING_FAULT_REG(ring)); + } if (INTEL_INFO(dev)-gen = 4) { error-ipeir[ring-id] = I915_READ(RING_IPEIR(ring-mmio_base)); @@ -917,7 +919,6 @@ static void i915_record_ring_state(struct drm_device *dev, error-ipeir[ring-id] = I915_READ(IPEIR); error-ipehr[ring-id] = I915_READ(IPEHR); error-instdone[ring-id] = I915_READ(INSTDONE); - error-bbaddr = 0; } error-instpm[ring-id] = I915_READ(RING_INSTPM(ring-mmio_base)); @@ -951,7 +952,7 @@ static void i915_capture_error_state(struct drm_device *dev) return; /* Account for pipe specific data like PIPE*STAT */ - error = kmalloc(sizeof(*error), GFP_ATOMIC); + error = kzalloc(sizeof(*error), GFP_ATOMIC); if (!error) { DRM_DEBUG_DRIVER(out of memory, not capturing error state\n); return; @@ -966,10 +967,10 @@ static void i915_capture_error_state(struct drm_device *dev) for_each_pipe(pipe) error-pipestat[pipe] = I915_READ(PIPESTAT(pipe)); - if (INTEL_INFO(dev)-gen = 6) + if (INTEL_INFO(dev)-gen = 6) { error-error = I915_READ(ERROR_GEN6); - else - error-error = 0; + error-done_reg = I915_READ(DONE_REG); + } i915_record_ring_state(dev, error, dev_priv-ring[RCS]); if (HAS_BLT(dev)) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 2fa7dfa..8e10a89 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -363,6 +363,8 @@ #define ARB_MODE_ENABLE(x) GFX_MODE_ENABLE(x) #define ARB_MODE_DISABLE(x) GFX_MODE_DISABLE(x) #define RENDER_HWS_PGA_GEN7(0x04080) +#define RING_FAULT_REG(ring) (0x4094 + 0x100*(ring)-id) +#define DONE_REG 0x40b0 #define BSD_HWS_PGA_GEN7 (0x04180) #define BLT_HWS_PGA_GEN7 (0x04280) #define RING_ACTHD(base) ((base)+0x74) -- 1.7.7.3 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 43/43] drm/i915: enable ppgtt
v2: Don't try to enable ppgtt on pre-snb. Signed-off-by: Daniel Vetter daniel.vet...@ffwll.ch Reviewed-by: Ben Widawsky b...@bwidawsk.net --- drivers/gpu/drm/i915/i915_drv.c |2 ++ drivers/gpu/drm/i915/i915_drv.h |1 + drivers/gpu/drm/i915/i915_gem.c | 39 +++ 3 files changed, 42 insertions(+), 0 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 6e0f868..461356e 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -698,6 +698,8 @@ int i915_reset(struct drm_device *dev, u8 flags) if (HAS_BLT(dev)) dev_priv-ring[BCS].init(dev_priv-ring[BCS]); + i915_gem_init_ppgtt(dev); + mutex_unlock(dev-struct_mutex); drm_irq_uninstall(dev); drm_mode_config_reset(dev); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 9b1a7ad..1f83c61 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1228,6 +1228,7 @@ int __must_check i915_gem_object_set_domain(struct drm_i915_gem_object *obj, int __must_check i915_gem_object_finish_gpu(struct drm_i915_gem_object *obj); int __must_check i915_gem_init_hw(struct drm_device *dev); void i915_gem_init_swizzling(struct drm_device *dev); +void i915_gem_init_ppgtt(struct drm_device *dev); void i915_gem_cleanup_ringbuffer(struct drm_device *dev); void i915_gem_do_init(struct drm_device *dev, unsigned long start, diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index f231b80..10fed1e 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -3708,6 +3708,43 @@ void i915_gem_init_swizzling(struct drm_device *dev) DISP_TILE_SURFACE_SWIZZLING); } + +void i915_gem_init_ppgtt(struct drm_device *dev) +{ + drm_i915_private_t *dev_priv = dev-dev_private; + uint32_t pd_offset; + struct intel_ring_buffer *ring; + int i; + + if (!HAS_ALIASING_PPGTT(dev)) + return; + + pd_offset = dev_priv-mm.aliasing_ppgtt-pd_offset; + pd_offset /= 64; /* in cachelines, */ + pd_offset = 16; + + if (INTEL_INFO(dev)-gen == 6) { + uint32_t ecochk = I915_READ(GAM_ECOCHK); + I915_WRITE(GAM_ECOCHK, ecochk | ECOCHK_SNB_BIT | + ECOCHK_PPGTT_CACHE64B); + I915_WRITE(GFX_MODE, GFX_MODE_ENABLE(GFX_PPGTT_ENABLE)); + } else if (INTEL_INFO(dev)-gen = 7) { + I915_WRITE(GAM_ECOCHK, ECOCHK_PPGTT_CACHE64B); + /* GFX_MODE is per-ring on gen7+ */ + } + + for (i = 0; i I915_NUM_RINGS; i++) { + ring = dev_priv-ring[i]; + + if (INTEL_INFO(dev)-gen = 7) + I915_WRITE(RING_MODE_GEN7(ring), + GFX_MODE_ENABLE(GFX_PPGTT_ENABLE)); + + I915_WRITE(RING_PP_DIR_DCLV(ring), PP_DIR_DCLV_2G); + I915_WRITE(RING_PP_DIR_BASE(ring), pd_offset); + } +} + int i915_gem_init_hw(struct drm_device *dev) { @@ -3734,6 +3771,8 @@ i915_gem_init_hw(struct drm_device *dev) dev_priv-next_seqno = 1; + i915_gem_init_ppgtt(dev); + return 0; cleanup_bsd_ring: -- 1.7.7.3 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 15/43] drm/i915: add interface to simulate gpu hangs
gpu reset is a very important piece of our infrastructure. Unfortunately we only really it test by actually hanging the gpu, which often has bad side-effects for the entire system. And the gpu hang handling code is one of the rather complicated pieces of code we have, consisting of - hang detection - error capture - actual gpu reset - reset of all the gem bookkeeping - reinitialition of the entire gpu This patch adds a debugfs to selectively stopping rings by ceasing to update the hw tail pointer, which will result in the gpu no longer updating it's head pointer and eventually to the hangcheck firing. This way we can exercise the gpu hang code under controlled conditions without a dying gpu taking down the entire systems. Patch motivated by me forgetting to properly reinitialize ppgtt after a gpu reset. Usage: echo $((1 $ringnum)) i915_ring_stop # stops one ring echo 0x i915_ring_stop # stops all, future-proof version then run whatever testload is desired. i915_ring_stop automatically resets after a gpu hang is detected to avoid hanging the gpu to fast and declaring it wedged. v2: Incorporate feedback from Chris Wilson. v3: Add the missing cleanup. Signed-Off-by: Daniel Vetter daniel.vet...@ffwll.ch Reviewed-by: Chris Wilson ch...@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_debugfs.c | 65 +++ drivers/gpu/drm/i915/i915_drv.c |2 + drivers/gpu/drm/i915/i915_drv.h |2 + drivers/gpu/drm/i915/intel_ringbuffer.c |4 ++ 4 files changed, 73 insertions(+), 0 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index db83552..67d7567 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -1397,6 +1397,64 @@ static const struct file_operations i915_wedged_fops = { }; static ssize_t +i915_ring_stop_read(struct file *filp, + char __user *ubuf, + size_t max, + loff_t *ppos) +{ + struct drm_device *dev = filp-private_data; + drm_i915_private_t *dev_priv = dev-dev_private; + char buf[80]; + int len; + + len = snprintf(buf, sizeof(buf), + 0x%08x\n, dev_priv-stop_rings); + + if (len sizeof(buf)) + len = sizeof(buf); + + return simple_read_from_buffer(ubuf, max, ppos, buf, len); +} + +static ssize_t +i915_ring_stop_write(struct file *filp, +const char __user *ubuf, +size_t cnt, +loff_t *ppos) +{ + struct drm_device *dev = filp-private_data; + struct drm_i915_private *dev_priv = dev-dev_private; + char buf[20]; + int val = 0; + + if (cnt 0) { + if (cnt sizeof(buf) - 1) + return -EINVAL; + + if (copy_from_user(buf, ubuf, cnt)) + return -EFAULT; + buf[cnt] = 0; + + val = simple_strtoul(buf, NULL, 0); + } + + DRM_DEBUG_DRIVER(Stopping rings 0x%08x\n, val); + + mutex_lock(dev-struct_mutex); + dev_priv-stop_rings = val; + mutex_unlock(dev-struct_mutex); + + return cnt; +} + +static const struct file_operations i915_ring_stop_fops = { + .owner = THIS_MODULE, + .open = i915_debugfs_common_open, + .read = i915_ring_stop_read, + .write = i915_ring_stop_write, + .llseek = default_llseek, +}; +static ssize_t i915_max_freq_read(struct file *filp, char __user *ubuf, size_t max, @@ -1701,6 +1759,11 @@ int i915_debugfs_init(struct drm_minor *minor) i915_cache_sharing_fops); if (ret) return ret; + ret = i915_debugfs_create(minor-debugfs_root, minor, + i915_ring_stop, + i915_ring_stop_fops); + if (ret) + return ret; return drm_debugfs_create_files(i915_debugfs_list, I915_DEBUGFS_ENTRIES, @@ -1719,6 +1782,8 @@ void i915_debugfs_cleanup(struct drm_minor *minor) 1, minor); drm_debugfs_remove_files((struct drm_info_list *) i915_cache_sharing_fops, 1, minor); + drm_debugfs_remove_files((struct drm_info_list *) i915_ring_stop_fops, +1, minor); } #endif /* CONFIG_DEBUG_FS */ diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 4a2eb68..6dd219b 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -638,6 +638,8 @@ int i915_reset(struct drm_device *dev, u8 flags) if (!mutex_trylock(dev-struct_mutex)) return -EBUSY; + dev_priv-stop_rings = 0; + i915_gem_reset(dev); ret = -ENODEV; diff --git a/drivers/gpu/drm/i915/i915_drv.h
Re: [Intel-gfx] [PATCH 08/43] drm/i915: drop register special-casing in forcewake
On Wed, 14 Dec 2011 13:57:05 +0100, Daniel Vetter daniel.vet...@ffwll.ch wrote: We currently have 3 register for which we must not grab forcewake for: FORCEWAKE, FROCEWAKE_MT and ECOBUS. - FORCEWAKE is excluded in the NEEDS_FORCE_WAKE macro and accessed with _NOTRACE. - FORCEWAKE_MT is just accessed with _NOTRACE. - ECOBUS is only excluded in the macro. In fear of an ever-growing list of special cases and to cut down the confusion, just access all of them with the _NOTRACE variants. Instead you build in future confusion by making us guess wtf is this using *_NOTRACE. The NOTRACE macro needs a bit of explanation as it now is more than simply skipping the tracepoints, and why certain registers must be accessed through the macro. Also add that warning to the register define. -Chris -- Chris Wilson, Intel Open Source Technology Centre ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 09/43] drm/i915: introduce a vtable for gpu core functions
On Wed, 14 Dec 2011 13:57:06 +0100, Daniel Vetter daniel.vet...@ffwll.ch wrote: ... like for forcewake, which protects everything _but_ display. Expect more things (like gtt abstractions, rings, inter-ring sync) to come. The only thing that looks odd is the layout in drm_i915_private is a little haphazard. Otherwise, Reviewed-by: Chris Wilson ch...@chris-wilson.co.uk -Chris -- Chris Wilson, Intel Open Source Technology Centre ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 13/43] drm/i915: refactor debugfs open function
On Wed, 14 Dec 2011 13:57:10 +0100, Daniel Vetter daniel.vet...@ffwll.ch wrote: Only forcewake has an open with special semantics, the other r/w debugfs only assign the file private pointer. Signed-Off-by: Daniel Vetter daniel.vet...@ffwll.ch Reviewed-by: Ben Widawsky b...@bwidawsk.net Reviewed-by: Kenneth Graunke kenn...@whitecape.org Reviewed-by: Chris Wilson ch...@chris-wilson.co.uk -Chris -- Chris Wilson, Intel Open Source Technology Centre ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 27/43] drm/i915: flush overlay regfile writes
On Wed, 14 Dec 2011 13:57:24 +0100, Daniel Vetter daniel.vet...@ffwll.ch wrote: Better be paranoid. The wmb should flush the wc writes, and the chipset_flush hopefully flushes any mch buffers. There've been a few overlay hangs I've never really diagnosed, unfortunately all the reporters disappeared. At which point we should just put the darn wmb into i830_chipset_flush() and make snark remarks about wbinvd. -Chris -- Chris Wilson, Intel Open Source Technology Centre ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 43/43] drm/i915: enable ppgtt
On Wed, 14 Dec 2011 13:57:40 +0100, Daniel Vetter daniel.vet...@ffwll.ch wrote: v2: Don't try to enable ppgtt on pre-snb. Signed-off-by: Daniel Vetter daniel.vet...@ffwll.ch Reviewed-by: Ben Widawsky b...@bwidawsk.net --- +void i915_gem_init_ppgtt(struct drm_device *dev) +{ + drm_i915_private_t *dev_priv = dev-dev_private; + uint32_t pd_offset; + struct intel_ring_buffer *ring; + int i; + + if (!HAS_ALIASING_PPGTT(dev)) + return; I still think it is safer to use if (dev_priv-mm.aliasing_ppgtt == NULL) return; here And pretty please can I module parameter to enable/disable ppgtt on boot. -Chris -- Chris Wilson, Intel Open Source Technology Centre ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 13/43] drm/i915: refactor debugfs open function
On Wed, Dec 14, 2011 at 10:57, Daniel Vetter daniel.vet...@ffwll.ch wrote: Only forcewake has an open with special semantics, the other r/w debugfs only assign the file private pointer. Signed-Off-by: Daniel Vetter daniel.vet...@ffwll.ch Reviewed-by: Ben Widawsky b...@bwidawsk.net Reviewed-by: Kenneth Graunke kenn...@whitecape.org Reviewed-by: Eugeni Dodonov eugeni.dodo...@intel.com -- Eugeni Dodonov http://eugeni.dodonov.net/ ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 16/43] drm/i915: rework dev-first_error locking
On Wed, Dec 14, 2011 at 10:57, Daniel Vetter daniel.vet...@ffwll.ch wrote: - reduce the irq disabled section, even for a debugfs file this was way too long. - always disable irqs when taking the lock. v2: Thou shalt not mistake locking for reference counting, so: - reference count the error_state to protect from concurent freeeing. This will be only really used in the next patch. Signed-Off-by: Daniel Vetter daniel.vet...@ffwll.ch Reviewed-by: Eugeni Dodonov eugeni.dodo...@intel.com -- Eugeni Dodonov http://eugeni.dodonov.net/ ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 02/43] drm/i915: don't bail out of intel_wait_ring_buffer too early
On Wed, Dec 14, 2011 at 10:56, Daniel Vetter daniel.vet...@ffwll.ch wrote: In the pre-gem days with non-existing hangcheck and gpu reset code, this timeout of 3 seconds was pretty important to avoid stuck processes. But now we have the hangcheck code in gem that goes to great length to ensure that the gpu is really dead before declaring it wedged. So there's no need for this timeout anymore. Actually it's even harmful because we can bail out too early (e.g. with xscreensaver slip) when running giant batchbuffers. And our code isn't robust enough to properly unroll any state-changes, we pretty much rely on the gpu reset code cleaning up the mess (like cache tracking, fencing state, active list/request tracking, ...). With this change intel_begin_ring can only fail when the gpu is wedged, and it will return -EAGAIN (like wait_request in case the gpu reset is still outstanding). v2: Chris Wilson noted that on resume timers aren't running and hence we won't ever get kicked out of this loop by the hangcheck code. Use an insanely large timeout instead for the HAS_GEM case to prevent resume bugs from totally hanging the machine. Signed-off-by: Daniel Vetter daniel.vet...@ffwll.ch Reviewed-by: Chris Wilson ch...@chris-wilson.co.uk Acked-by: Ben Widawsky b...@bwidawsk.net Reviewed-by: Eugeni Dodonov eugeni.dodo...@intel.com -- Eugeni Dodonov http://eugeni.dodonov.net/ ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 03/43] drm/i915: switch ring-id to be a real id
On Wed, Dec 14, 2011 at 10:57, Daniel Vetter daniel.vet...@ffwll.ch wrote: ... and add a helpr function for the places where we want a flag. This way we can use ring-id to index into arrays. v2: Resurrect the missing beautification-space Chris Wilson noted. I'm moving this space around because I'll reuse ring_str in the next patch. Signed-off-by: Daniel Vetter daniel.vet...@ffwll.ch Reviewed-by: Chris Wilson ch...@chris-wilson.co.uk Reviewed-by: Ben Widawsky b...@bwidawsk.net Reviewed-by: Eugeni Dodonov eugeni.dodo...@intel.com -- Eugeni Dodonov http://eugeni.dodonov.net/ ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 05/43] drm/i915: collect more per ring error state
On Wed, Dec 14, 2011 at 10:57, Daniel Vetter daniel.vet...@ffwll.ch wrote: Based on a patch by Ben Widawsky, but with different colors for the bikeshed. In contrast to Ben's patch this one doesn't add the fault regs. Afaics they're for the optional page fault support which - we're not enabling - and which seems to be unsupported by the hw team. Recent bspec lacks tons of information about this that the public docs released half a year back still contain. Also dump ring HEAD/TAIL registers - I've recently seen a few error_state where just guessing these is not good enough. v2: Also dump INSTPM for every ring. v3: Fix a few really silly goof-ups spotted by Chris Wilson. Signed-off-by: Daniel Vetter daniel.vet...@ffwll.ch Reviewed-by: Chris Wilson ch...@chris-wilson.co.uk Signed-off-by: Ben Widawsky b...@bwidawsk.net Reviewed-by: Eugeni Dodonov eugeni.dodo...@intel.com -- Eugeni Dodonov http://eugeni.dodonov.net/ ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 14/43] drm/i915: refactor debugfs create functions
On Wed, Dec 14, 2011 at 10:57, Daniel Vetter daniel.vet...@ffwll.ch wrote: All r/w debugfs files are created equal. v2: Add some newlines to make the code easier on the eyes as requested by Ben Widawsky. Signed-Off-by: Daniel Vetter daniel.vet...@ffwll.ch Reviewed-by: Ben Widawsky b...@bwidawsk.net Reviewed-by: Kenneth Graunke kenn...@whitecape.org Reviewed-by: Eugeni Dodonov eugeni.dodo...@intel.com -- Eugeni Dodonov http://eugeni.dodonov.net/ ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 17/43] drm/i915: destroy existing error_state when simulating a gpu hang
On Wed, Dec 14, 2011 at 10:57, Daniel Vetter daniel.vet...@ffwll.ch wrote: This way we can simulate a bunch of gpu hangs and run the error_state capture code every time (without the need to reload the module). Signed-Off-by: Daniel Vetter daniel.vet...@ffwll.ch Reviewed-by: Eugeni Dodonov eugeni.dodo...@intel.com -- Eugeni Dodonov http://eugeni.dodonov.net/ ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 28/43] drm/i915: Handle unmappable buffers during error state capture
On Wed, Dec 14, 2011 at 10:57, Daniel Vetter daniel.vet...@ffwll.ch wrote: From: Chris Wilson ch...@chris-wilson.co.uk As the buffer is not necessarily accessible through the GTT at the time of a GPU hang, and capturing some of its contents is far more valuable than skipping it, provide a clflushed fallback read path. We still prefer to read through the GTT as that is more consistent with the GPU access of the same buffer. So example it will demonstrate any errorneous tiling or swizzling of the command buffer as seen by the GPU. This becomes necessary with use of CPU relocations and lazy GTT binding, but could potentially happen anyway as a result of a pathological error. Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk Reviewed-by: Daniel Vetter daniel.vet...@ffwll.ch Reviewed-by: Eugeni Dodonov eugeni.dodo...@intel.com -- Eugeni Dodonov http://eugeni.dodonov.net/ ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 09/43] drm/i915: introduce a vtable for gpu core functions
On 12/14/2011 04:57 AM, Daniel Vetter wrote: ... like for forcewake, which protects everything _but_ display. Expect more things (like gtt abstractions, rings, inter-ring sync) to come. Signed-Off-by: Daniel Vetter daniel.vet...@ffwll.ch Reviewed-by: Eugeni Dodonov eugeni.dodo...@intel.com --- drivers/gpu/drm/i915/i915_drv.c |6 +++--- drivers/gpu/drm/i915/i915_drv.h |8 ++-- drivers/gpu/drm/i915/intel_display.c |8 3 files changed, 13 insertions(+), 9 deletions(-) Reviewed-by: Kenneth Graunke kenn...@whitecape.org ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 40/43] drm/i915: ppgtt register definitions
On Wed, Dec 14, 2011 at 10:57, Daniel Vetter daniel.vet...@ffwll.ch wrote: Signed-off-by: Daniel Vetter daniel.vet...@ffwll.ch Reviewed-by: Ben Widawsky b...@bwidawsk.net Reviewed-by: Eugeni Dodonov eugeni.dodo...@intel.com -- Eugeni Dodonov http://eugeni.dodonov.net/ ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 42/43] drm/i915: per-ring fault reg
On Wed, Dec 14, 2011 at 10:57, Daniel Vetter daniel.vet...@ffwll.ch wrote: v2: Chris Wilson suggested to allocate the error_state with kzalloc for better paranioa. Also kill existing spurious clears of the error_state while at it. Signed-Off-by: Daniel Vetter daniel.vet...@ffwll.ch Reviewed-by: Ben Widawsky b...@bwidawsk.net Reviewed-by: Eugeni Dodonov eugeni.dodo...@intel.com -- Eugeni Dodonov http://eugeni.dodonov.net/ ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 15/43] drm/i915: add interface to simulate gpu hangs
On Wed, Dec 14, 2011 at 10:57, Daniel Vetter daniel.vet...@ffwll.ch wrote: gpu reset is a very important piece of our infrastructure. Unfortunately we only really it test by actually hanging the gpu, which often has bad side-effects for the entire system. And the gpu hang handling code is one of the rather complicated pieces of code we have, consisting of - hang detection - error capture - actual gpu reset - reset of all the gem bookkeeping - reinitialition of the entire gpu This patch adds a debugfs to selectively stopping rings by ceasing to update the hw tail pointer, which will result in the gpu no longer updating it's head pointer and eventually to the hangcheck firing. This way we can exercise the gpu hang code under controlled conditions without a dying gpu taking down the entire systems. Patch motivated by me forgetting to properly reinitialize ppgtt after a gpu reset. Usage: echo $((1 $ringnum)) i915_ring_stop # stops one ring echo 0x i915_ring_stop # stops all, future-proof version then run whatever testload is desired. i915_ring_stop automatically resets after a gpu hang is detected to avoid hanging the gpu to fast and declaring it wedged. v2: Incorporate feedback from Chris Wilson. v3: Add the missing cleanup. Signed-Off-by: Daniel Vetter daniel.vet...@ffwll.ch Reviewed-by: Chris Wilson ch...@chris-wilson.co.uk Reviewed-by: Eugeni Dodonov eugeni.dodo...@intel.com -- Eugeni Dodonov http://eugeni.dodonov.net/ ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 40/43] drm/i915: ppgtt register definitions
On Wed, Dec 14, 2011 at 16:58, Eugeni Dodonov eug...@dodonov.net wrote: On Wed, Dec 14, 2011 at 10:57, Daniel Vetter daniel.vet...@ffwll.chwrote: Signed-off-by: Daniel Vetter daniel.vet...@ffwll.ch Reviewed-by: Ben Widawsky b...@bwidawsk.net Reviewed-by: Eugeni Dodonov eugeni.dodo...@intel.com Just clarifying - the R-b is for the ppgtt series. I think I also sent a Tested-by already, but in any case, also for the series: Tested-by: Eugeni Dodonov eugeni.dodo...@intel.com -- Eugeni Dodonov http://eugeni.dodonov.net/ ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 22/43] drm/i915: prevent division by zero when asking for chipset power
On 12/14/2011 04:57 AM, Daniel Vetter wrote: From: Eugeni Dodonov eugeni.dodo...@intel.com This prevents an in-kernel division by zero which happens when we are asking for i915_chipset_val too quickly, or within a race condition between the power monitoring thread and userspace accesses via debugfs. The issue can be reproduced easily via the following command: while ``; do cat /sys/kernel/debug/dri/0/i915_emon_status; done This is particularly dangerous because it can be triggered by a non-privileged user by just reading the debugfs entry. This issue was also found independently by Konstantin Belousov kostik...@gmail.com, who proposed a similar patch. Reported-by: Konstantin Belousov kostik...@gmail.com Acked-by: Jesse Barnes jbar...@virtuousgeek.org Acked-by: Keith Packard kei...@keithp.com Cc: sta...@vger.kernel.org Signed-off-by: Eugeni Dodonov eugeni.dodo...@intel.com Signed-off-by: Daniel Vetter daniel.vet...@ffwll.ch --- drivers/gpu/drm/i915/i915_dma.c | 10 ++ drivers/gpu/drm/i915/i915_drv.h |1 + 2 files changed, 11 insertions(+), 0 deletions(-) This has been in drm-intel-fixes since December 8th. ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 3/4] drm/i915: Update GEN6_RP_CONTROL definitions
On Tue, Dec 13, 2011 at 01:21, Ben Widawsky b...@bwidawsk.net wrote: This matches the modern specs more accurately. This will be used by the following patch to fix the way we display RC status. Signed-off-by: Ben Widawsky b...@bwidawsk.net Reviewed-by: Eugeni Dodonov eugeni.dodo...@intel.com -- Eugeni Dodonov http://eugeni.dodonov.net/ ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 4/4] drm/i915: drpc debugfs update for gen6
On Tue, Dec 13, 2011 at 17:37, Jesse Barnes jbar...@virtuousgeek.orgwrote: On Mon, 12 Dec 2011 19:22:00 -0800 Ben Widawsky b...@bwidawsk.net wrote: Many of the old fields from Ironlake have gone away. Strip all those fields, and try to update to fields people care about. RC information isn't exactly ideal anymore. All we can guarantee when we read the register is that we're not using forcewake, ie. the software isn't forcing the hardware to stay awake. The downside is that in doing this we may wait a while and that causes an unnaturally idle state on the GPU. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=42578 Signed-off-by: Ben Widawsky b...@bwidawsk.net --- Aside from the merge error: Reviewed-by: Jesse Barnes jbar...@virtuousgeek.org Reviewed-by: Eugeni Dodonov eugeni.dodo...@intel.com -- Eugeni Dodonov http://eugeni.dodonov.net/ ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] kernel BUG at drivers/gpu/drm/i915/i915_gem
On Wed, Dec 14, 2011 at 02:47:33 +0100, Daniel Vetter wrote: On Mon, Dec 12, 2011 at 10:16, Rocko Requin rockoreq...@hotmail.com wrote: If you can wire up netconsole you should be able to gather the full backtrace and that would be really useful. Otherwise can you please confirm by reverting that commit from your current tree that it is indeed the culprit? Otherwise please bisect the issue. I built 3.2-rc5 with the patch from commit eb1711bb94991e93669c5a1b5f84f11be2d51ea1 reversed, and have been using it now for a day and a half without any i915_gem issues. So at this stage it does seem likely it is the culprit, based on the fact that I had at least 2 and probably 3 i915_gem crashes in around 12 hours with the commit applied. When I get some free time I'll reapply the patch and see if I can reproduce the crash and get a netconsole dump. Backtraces from another reporter seriously look like we're hitting some ugly use-after free. Can you please test whether the patch drm/i915: Only clear the GPU domains upon a successful finish by Chris Wilson fixes anything for you? You can grab it from http://cgit.freedesktop.org/~danvet/drm/patch/?id=389a55581e30607af0fcde6cdb4e54f189cf46cf Hi, it looks I stumbled over the same: [88399.844150] kernel BUG at drivers/gpu/drm/i915/i915_gem.c:1952! 2011-12-14_19:28:56.93083 0[88399.844182] invalid opcode: [#1] SMP While doing this I was running a 32 bit photo software (Bibble 5 pro) in fullscreen on an otherwise 64 bit system. The full log including the trace is attached. I'll try with the patch applied. Regards, Tino [88399.844150] kernel BUG at drivers/gpu/drm/i915/i915_gem.c:1952! 2011-12-14_19:28:56.93083 0[88399.844182] invalid opcode: [#1] SMP [88399.844210] CPU 3 [88399.844222] Modules linked in: bluetooth cpufreq_stats fuse ipv6 loop snd_hda_codec_hdmi snd_hda_codec_realtek snd_hda_intel snd_hda_codec snd_pcm dvb_usb_vp7045 dvb_usb dvb_core rc_core snd_timer xhci_hcd snd_page_alloc evdev [88399.844368] [88399.844380] Pid: 8959, comm: Xorg Not tainted 3.2.0-rc5-1-g3aae701 #24 /DH67BL [88399.844439] RIP: 0010:[813804d6] [813804d6] i915_wait_request+0x516/0x530 [88399.844491] RSP: 0018:88020b3cbbe8 EFLAGS: 00010246 [88399.844519] RAX: 88021661e800 RBX: 880216692038 RCX: 5250 [88399.844555] RDX: 8802166923f8 RSI: RDI: 880216692038 [88399.844591] RBP: 880216692000 R08: 0010 R09: 0002 [88399.844627] R10: 88021661e800 R11: 005a R12: [88399.844664] R13: R14: R15: 88021661e800 [88399.844700] FS: 7fbef0355880() GS:88021fb8() knlGS: [88399.844741] CS: 0010 DS: ES: CR0: 8005003b [88399.844770] CR2: 7f2c5ed0200c CR3: 000216748000 CR4: 000406e0 [88399.844806] DR0: DR1: DR2: [88399.844842] DR3: DR6: 0ff0 DR7: 0400 [88399.844879] Process Xorg (pid: 8959, threadinfo 88020b3ca000, task 8801f0eee110) 2011-12-14_19:28:56.93093 0[88399.844919] Stack: [88399.844932] 88021661e800 813ac08c 0042 0042 [88399.844977] 8802166922f8 8138056e 8802166923f8 0042 [88399.845023] 88020b3cbd10 81385c01 880216692038 2011-12-14_19:28:56.93094 0[88399.845068] Call Trace: [88399.845087] [813ac08c] ? blt_ring_flush+0xdc/0x110 [88399.845120] [8138056e] ? i915_gem_flush_ring+0x4e/0x210 [88399.845154] [81385c01] ? i915_gem_execbuffer_relocate_entry+0x171/0x300 [88399.845193] [81386d0c] ? i915_gem_do_execbuffer.isra.8+0xb3c/0x13d0 [88399.845233] [81381ed8] ? i915_gem_object_set_to_gtt_domain+0xd8/0x1d0 [88399.845272] [81387a4e] ? i915_gem_execbuffer2+0x9e/0x260 [88399.845307] [8135883c] ? drm_ioctl+0x3ec/0x4a0 [88399.845336] [813879b0] ? i915_gem_execbuffer+0x410/0x410 [88399.845371] [8110c9a6] ? do_vfs_ioctl+0x96/0x550 [88399.845402] [810fc50d] ? vfs_read+0x14d/0x170 [88399.845430] [8110cea9] ? sys_ioctl+0x49/0x80 [88399.845460] [8156327b] ? system_call_fastpath+0x16/0x1b 2011-12-14_19:28:56.93100 0[88399.845491] Code: ff ff 0f 1f 00 45 31 e4 e9 de fc ff ff 0f 1f 84 00 00 00 00 00 41 bc f0 ff ff ff e9 cb fc ff ff 41 bc f4 ff ff ff e9 8a fb ff ff 0f 0b 41 bc 00 fe ff ff eb 91 45 85 e4 0f 84 5e fb ff ff e9 a8 2011-12-14_19:28:56.93101 kern.alert: [88399.845744] RIP [813804d6] i915_wait_request+0x516/0x530 [88399.845781] RSP 88020b3cbbe8 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH] [RFC] LLC and per-BO cache handling
On Wed, 14 Dec 2011 00:33:00 -0200, Eugeni Dodonov eug...@dodonov.net wrote: With base on comments and feedback on LLC handling from Daniel Vetter, Chris Wilson and Ben Widawsky, I reworked my patch into a more useful approach for detecting presence of different cache levels from userspace. So, in this context, PATCH 1 adds the very same .has_llc flag and debugfs entry for it. PATCH 2 does the initial job of preparing to export cache levels to userspace, which can be queried via the DRM interface by means of PATCH 3. And finally, PATCH 4 allows to get and set a specific cache level for each bo. So, I haven't come up with a usecase, and I don't think I've heard of one: why do we want the cache level setting ioctl? pgpofcyzUqoUB.pgp Description: PGP signature ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 2/3] drm/i915: Force sync command ordering (Gen6+)
On Thu, 08 Dec 2011 18:35:24 -0800 Eric Anholt e...@anholt.net wrote: Since MI_FLUSH_DW exists on gen6, and keithp says we still have outstanding issues with missed blit IRQs there, I started trying it today. Two kernel branches posted at git://people.freedesktop.org/~anholt/linux/ flush-dw-notify: This is the initial attempt I did with MI_FLUSH_DW with internal notify. Quickly produced missed blit IRQs. I thought this was because the notify was in parallel with the post-sync op, not synced to be after. So I reverted part of the patch and produced... Bummer, that one looks like it ought to work. On current drm-intel-next, this patch seems to be preventing missed IRQs on IVB at least. Anyone else wanna give it a try and confirm? I've only tested with Eric's blit-and-wait.c test so far. -- Jesse Barnes, Intel Open Source Technology Center diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index b40004b..cb821a0 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -482,78 +482,83 @@ static irqreturn_t ivybridge_irq_handler(DRM_IRQ_ARGS) I915_WRITE(DEIER, de_ier ~DE_MASTER_IRQ_CONTROL); POSTING_READ(DEIER); - de_iir = I915_READ(DEIIR); - gt_iir = I915_READ(GTIIR); - pch_iir = I915_READ(SDEIIR); - pm_iir = I915_READ(GEN6_PMIIR); + /* +* Try to mitigate dropped IRQs by handling as many as possible +* each time we get a physical interrupt. +*/ + while (1) { + de_iir = I915_READ(DEIIR); + gt_iir = I915_READ(GTIIR); + pch_iir = I915_READ(SDEIIR); + pm_iir = I915_READ(GEN6_PMIIR); + + if (de_iir == 0 gt_iir == 0 pch_iir == 0 pm_iir == 0) { + I915_WRITE(DEIER, de_ier); + POSTING_READ(DEIER); + return ret; + } - if (de_iir == 0 gt_iir == 0 pch_iir == 0 pm_iir == 0) - goto done; + ret = IRQ_HANDLED; - ret = IRQ_HANDLED; + if (dev-primary-master) { + master_priv = dev-primary-master-driver_priv; + if (master_priv-sarea_priv) + master_priv-sarea_priv-last_dispatch = + READ_BREADCRUMB(dev_priv); + } - if (dev-primary-master) { - master_priv = dev-primary-master-driver_priv; - if (master_priv-sarea_priv) - master_priv-sarea_priv-last_dispatch = - READ_BREADCRUMB(dev_priv); - } + if (gt_iir (GT_USER_INTERRUPT | GT_PIPE_NOTIFY)) + notify_ring(dev, dev_priv-ring[RCS]); + if (gt_iir GT_GEN6_BSD_USER_INTERRUPT) + notify_ring(dev, dev_priv-ring[VCS]); + if (gt_iir GT_BLT_USER_INTERRUPT) + notify_ring(dev, dev_priv-ring[BCS]); - if (gt_iir (GT_USER_INTERRUPT | GT_PIPE_NOTIFY)) - notify_ring(dev, dev_priv-ring[RCS]); - if (gt_iir GT_GEN6_BSD_USER_INTERRUPT) - notify_ring(dev, dev_priv-ring[VCS]); - if (gt_iir GT_BLT_USER_INTERRUPT) - notify_ring(dev, dev_priv-ring[BCS]); + if (de_iir DE_GSE_IVB) + intel_opregion_gse_intr(dev); - if (de_iir DE_GSE_IVB) - intel_opregion_gse_intr(dev); + if (de_iir DE_PLANEA_FLIP_DONE_IVB) { + intel_prepare_page_flip(dev, 0); + intel_finish_page_flip_plane(dev, 0); + } - if (de_iir DE_PLANEA_FLIP_DONE_IVB) { - intel_prepare_page_flip(dev, 0); - intel_finish_page_flip_plane(dev, 0); - } + if (de_iir DE_PLANEB_FLIP_DONE_IVB) { + intel_prepare_page_flip(dev, 1); + intel_finish_page_flip_plane(dev, 1); + } - if (de_iir DE_PLANEB_FLIP_DONE_IVB) { - intel_prepare_page_flip(dev, 1); - intel_finish_page_flip_plane(dev, 1); - } + if (de_iir DE_PIPEA_VBLANK_IVB) + drm_handle_vblank(dev, 0); - if (de_iir DE_PIPEA_VBLANK_IVB) - drm_handle_vblank(dev, 0); + if (de_iir DE_PIPEB_VBLANK_IVB) + drm_handle_vblank(dev, 1); - if (de_iir DE_PIPEB_VBLANK_IVB) - drm_handle_vblank(dev, 1); + /* check event from PCH */ + if (de_iir DE_PCH_EVENT_IVB) { + if (pch_iir SDE_HOTPLUG_MASK_CPT) + queue_work(dev_priv-wq, + dev_priv-hotplug_work); + pch_irq_handler(dev); + } - /* check event from PCH */ -
Re: [Intel-gfx] [PATCH 1/4] drm/i915: add a LLC feature flag in device description
On Wed, 14 Dec 2011 00:33:01 -0200 Eugeni Dodonov eug...@dodonov.net wrote: From: Eugeni Dodonov eugeni.dodo...@intel.com LLC is not SNB-specific, so we should check for it in a more generic way. v2: export LLC support status via debugfs. Signed-off-by: Eugeni Dodonov eugeni.dodo...@intel.com I like it. Reviewed-by: Jesse Barnes jbar...@virtuousgeek.org -- Jesse Barnes, Intel Open Source Technology Center signature.asc Description: PGP signature ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 0/3] TV Out patches to make our mode list be according to TV timing standards
Hi all, The following patches makes the TV Out mode list be according to timing table specification from TV standards. The first one of the list fixes the https://bugs.freedesktop.org/show_bug.cgi?id=23899 When I start looking at this bug I was so focused on the pixel clock that I didn't noticed refresh rates were half of the specification for most of the modes. After the fix some modes got obsoletes and others were removed simply because they weren't on the TV Out standard timing table. From this same table I got the 1080p specification and added to our list there. Cheers, Rodrigo. Rodrigo Vivi (3): drm/i915: Fix TV Out refresh rate. drm/i915: Removing TV Out modes. drm/i915: Adding 1080p modes to our TV Out mode list. drivers/gpu/drm/i915/intel_tv.c | 176 ++- 1 files changed, 63 insertions(+), 113 deletions(-) -- 1.7.7.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 1/3] drm/i915: Fix TV Out refresh rate.
TV Out refresh rate was half of the specification for almost all modes. Due to this reason pixel clock was so low for some modes causing flickering screen. Signed-off-by: Rodrigo Vivi rodrigo.v...@gmail.com --- drivers/gpu/drm/i915/intel_tv.c | 16 1 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c index f3c6a9a..2b1fcad 100644 --- a/drivers/gpu/drm/i915/intel_tv.c +++ b/drivers/gpu/drm/i915/intel_tv.c @@ -417,7 +417,7 @@ static const struct tv_mode tv_modes[] = { { .name = NTSC-M, .clock = 108000, - .refresh= 29970, + .refresh= 59940, .oversample = TV_OVERSAMPLE_8X, .component_only = 0, /* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 3.580MHz */ @@ -460,7 +460,7 @@ static const struct tv_mode tv_modes[] = { { .name = NTSC-443, .clock = 108000, - .refresh= 29970, + .refresh= 59940, .oversample = TV_OVERSAMPLE_8X, .component_only = 0, /* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 4.43MHz */ @@ -502,7 +502,7 @@ static const struct tv_mode tv_modes[] = { { .name = NTSC-J, .clock = 108000, - .refresh= 29970, + .refresh= 59940, .oversample = TV_OVERSAMPLE_8X, .component_only = 0, @@ -545,7 +545,7 @@ static const struct tv_mode tv_modes[] = { { .name = PAL-M, .clock = 108000, - .refresh= 29970, + .refresh= 59940, .oversample = TV_OVERSAMPLE_8X, .component_only = 0, @@ -589,7 +589,7 @@ static const struct tv_mode tv_modes[] = { /* 625 Lines, 50 Fields, 15.625KHz line, Sub-Carrier 4.434MHz */ .name = PAL-N, .clock = 108000, - .refresh= 25000, + .refresh= 5, .oversample = TV_OVERSAMPLE_8X, .component_only = 0, @@ -634,7 +634,7 @@ static const struct tv_mode tv_modes[] = { /* 625 Lines, 50 Fields, 15.625KHz line, Sub-Carrier 4.434MHz */ .name = PAL, .clock = 108000, - .refresh= 25000, + .refresh= 5, .oversample = TV_OVERSAMPLE_8X, .component_only = 0, @@ -821,7 +821,7 @@ static const struct tv_mode tv_modes[] = { { .name = 1080i@50Hz, .clock = 148800, - .refresh= 25000, + .refresh= 5, .oversample = TV_OVERSAMPLE_2X, .component_only = 1, @@ -847,7 +847,7 @@ static const struct tv_mode tv_modes[] = { { .name = 1080i@60Hz, .clock = 148800, - .refresh= 3, + .refresh= 6, .oversample = TV_OVERSAMPLE_2X, .component_only = 1, -- 1.7.7.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 2/3] drm/i915: Removing TV Out modes.
These modes are no longer needed or are not according to TV timing standards. Signed-off-by: Rodrigo Vivi rodrigo.v...@gmail.com --- drivers/gpu/drm/i915/intel_tv.c | 122 --- 1 files changed, 0 insertions(+), 122 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c index 2b1fcad..1571be3 100644 --- a/drivers/gpu/drm/i915/intel_tv.c +++ b/drivers/gpu/drm/i915/intel_tv.c @@ -674,78 +674,6 @@ static const struct tv_mode tv_modes[] = { .filter_table = filter_table, }, { - .name = 480p@59.94Hz, - .clock = 107520, - .refresh= 59940, - .oversample = TV_OVERSAMPLE_4X, - .component_only = 1, - - .hsync_end = 64, .hblank_end = 122, - .hblank_start = 842, .htotal = 857, - - .progressive= true, .trilevel_sync = false, - - .vsync_start_f1 = 12, .vsync_start_f2 = 12, - .vsync_len = 12, - - .veq_ena= false, - - .vi_end_f1 = 44, .vi_end_f2 = 44, - .nbr_end= 479, - - .burst_ena = false, - - .filter_table = filter_table, - }, - { - .name = 480p@60Hz, - .clock = 107520, - .refresh= 6, - .oversample = TV_OVERSAMPLE_4X, - .component_only = 1, - - .hsync_end = 64, .hblank_end = 122, - .hblank_start = 842, .htotal = 856, - - .progressive= true, .trilevel_sync = false, - - .vsync_start_f1 = 12, .vsync_start_f2 = 12, - .vsync_len = 12, - - .veq_ena= false, - - .vi_end_f1 = 44, .vi_end_f2 = 44, - .nbr_end= 479, - - .burst_ena = false, - - .filter_table = filter_table, - }, - { - .name = 576p, - .clock = 107520, - .refresh= 5, - .oversample = TV_OVERSAMPLE_4X, - .component_only = 1, - - .hsync_end = 64, .hblank_end = 139, - .hblank_start = 859, .htotal = 863, - - .progressive= true, .trilevel_sync = false, - - .vsync_start_f1 = 10, .vsync_start_f2 = 10, - .vsync_len = 10, - - .veq_ena= false, - - .vi_end_f1 = 48, .vi_end_f2 = 48, - .nbr_end= 575, - - .burst_ena = false, - - .filter_table = filter_table, - }, - { .name = 720p@60Hz, .clock = 148800, .refresh= 6, @@ -770,30 +698,6 @@ static const struct tv_mode tv_modes[] = { .filter_table = filter_table, }, { - .name = 720p@59.94Hz, - .clock = 148800, - .refresh= 59940, - .oversample = TV_OVERSAMPLE_2X, - .component_only = 1, - - .hsync_end = 80, .hblank_end = 300, - .hblank_start = 1580, .htotal = 1651, - - .progressive= true, .trilevel_sync = true, - - .vsync_start_f1 = 10, .vsync_start_f2 = 10, - .vsync_len = 10, - - .veq_ena= false, - - .vi_end_f1 = 29, .vi_end_f2 = 29, - .nbr_end= 719, - - .burst_ena = false, - - .filter_table = filter_table, - }, - { .name = 720p@50Hz, .clock = 148800, .refresh= 5, @@ -870,32 +774,6 @@ static const struct tv_mode tv_modes[] = { .filter_table = filter_table, }, - { - .name = 1080i@59.94Hz, - .clock = 148800, - .refresh= 29970, - .oversample = TV_OVERSAMPLE_2X, - .component_only = 1, - - .hsync_end = 88, .hblank_end = 235, - .hblank_start = 2155, .htotal = 2201, - - .progressive= false,.trilevel_sync = true, - - .vsync_start_f1 = 4,.vsync_start_f2= 5, -
[Intel-gfx] [PATCH 3/3] drm/i915: Adding 1080p modes to our TV Out mode list.
According to TV Out timing standards, supported 1080p modes were missing. Signed-off-by: Rodrigo Vivi rodrigo.v...@gmail.com --- drivers/gpu/drm/i915/intel_tv.c | 72 +++ 1 files changed, 72 insertions(+), 0 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c index 1571be3..cfb44f4 100644 --- a/drivers/gpu/drm/i915/intel_tv.c +++ b/drivers/gpu/drm/i915/intel_tv.c @@ -774,6 +774,78 @@ static const struct tv_mode tv_modes[] = { .filter_table = filter_table, }, + { + .name = 1080p@30Hz, + .clock = 148800, + .refresh= 3, + .oversample = TV_OVERSAMPLE_2X, + .component_only = 1, + + .hsync_end = 88, .hblank_end = 235, + .hblank_start = 2155, .htotal = 2199, + + .progressive= true, .trilevel_sync = true, + + .vsync_start_f1 = 8,.vsync_start_f2 = 8, + .vsync_len = 10, + + .veq_ena= false, + + .vi_end_f1 = 44, .vi_end_f2 = 44, + .nbr_end= 1079, + + .burst_ena = false, + + .filter_table = filter_table, + }, + { + .name = 1080p@50Hz, + .clock = 148800, + .refresh= 5, + .oversample = TV_OVERSAMPLE_2X, + .component_only = 1, + + .hsync_end = 88, .hblank_end = 235, + .hblank_start = 2155, .htotal = 2639, + + .progressive= true, .trilevel_sync = true, + + .vsync_start_f1 = 8,.vsync_start_f2 = 8, + .vsync_len = 10, + + .veq_ena= false, + + .vi_end_f1 = 44, .vi_end_f2 = 44, + .nbr_end= 1079, + + .burst_ena = false, + + .filter_table = filter_table, + }, + { + .name = 1080p@60Hz, + .clock = 148800, + .refresh= 6, + .oversample = TV_OVERSAMPLE_2X, + .component_only = 1, + + .hsync_end = 88, .hblank_end = 235, + .hblank_start = 2155, .htotal = 2199, + + .progressive= true, .trilevel_sync = true, + + .vsync_start_f1 = 8,.vsync_start_f2 = 8, + .vsync_len = 10, + + .veq_ena= false, + + .vi_end_f1 = 44, .vi_end_f2 = 44, + .nbr_end= 1079, + + .burst_ena = false, + + .filter_table = filter_table, + }, }; static struct intel_tv *enc_to_intel_tv(struct drm_encoder *encoder) -- 1.7.7.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 3/3] drm/i915: Adding 1080p modes to our TV Out mode list.
On Wed, 14 Dec 2011 21:10:08 -0200, Rodrigo Vivi rodrigo.v...@gmail.com wrote: According to TV Out timing standards, supported 1080p modes were missing. Can you both here in the changelog and in comments a document reference so that we can easily find the right table again in future? -Chris -- Chris Wilson, Intel Open Source Technology Centre ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] i915_init takes a full second of kernel init time
On Tue, Dec 13, 2011 at 2:21 PM, Chris Wilson ch...@chris-wilson.co.uk wrote: On Tue, 13 Dec 2011 14:01:29 -0800, Jesse Barnes jbar...@virtuousgeek.org wrote: We had some async code to take all of this out of the boot time critical path at least... I thought Chris merged them long ago but I guess they were dropped. Chris? It never made it upstream because it had a tendency to hang machines during boot, as the async code was broken at the time wrt handling multiple async domains and it interacted badly with PIO hard disk controllers. After a little bit of digging I found: http://cgit.freedesktop.org/~ickle/linux-2.6/commit/?h=asyncid=470d6985b508466308fc4c6aec945cdbf6de39b8 -Chris I've tried this patch, but it doesn't really reduce the startup time by much, the mainline of i915_init is still taking 0.7s with the patch applied. Scott -- Scott James Remnant | Chrome OS Systems | key...@google.com | Google ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx