Message ID | 1405543770-3212-1-git-send-email-przanoni@gmail.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Wed, Jul 16, 2014 at 05:49:29PM -0300, Paulo Zanoni wrote: > static void > -hsw_unclaimed_reg_check(struct drm_i915_private *dev_priv, u32 reg) > +hsw_unclaimed_reg_detect(struct drm_i915_private *dev_priv) > { > + if (i915.mmio_debug) > + return; > + > if (__raw_i915_read32(dev_priv, FPGA_DBG) & FPGA_DBG_RM_NOCLAIM) { > - DRM_ERROR("Unclaimed write to %x\n", reg); > + DRM_ERROR("Unclaimed register detected. Please use the i915.mmio_debug=1 to debug this problem."); > __raw_i915_write32(dev_priv, FPGA_DBG, FPGA_DBG_RM_NOCLAIM); > } What was the point here? You still add an extra read to every register write and then repeat the request to enable mmio_debug ad infinitum. And you still check for illegal writes in the irq handler. Just kill this code. -Chris
2014-08-26 7:22 GMT-03:00 Chris Wilson <chris@chris-wilson.co.uk>: > On Wed, Jul 16, 2014 at 05:49:29PM -0300, Paulo Zanoni wrote: >> static void >> -hsw_unclaimed_reg_check(struct drm_i915_private *dev_priv, u32 reg) >> +hsw_unclaimed_reg_detect(struct drm_i915_private *dev_priv) >> { >> + if (i915.mmio_debug) >> + return; >> + >> if (__raw_i915_read32(dev_priv, FPGA_DBG) & FPGA_DBG_RM_NOCLAIM) { >> - DRM_ERROR("Unclaimed write to %x\n", reg); >> + DRM_ERROR("Unclaimed register detected. Please use the i915.mmio_debug=1 to debug this problem."); >> __raw_i915_write32(dev_priv, FPGA_DBG, FPGA_DBG_RM_NOCLAIM); >> } > > What was the point here? You still add an extra read to every register > write Well, we previously had 2 extra reads instead of 1, so with this patch we're in a better position :) > and then repeat the request to enable mmio_debug ad infinitum. Yeah, this could be avoided. OTOH, on most cases it's not gonna happen frequently enough to annoy the user. > And > you still check for illegal writes in the irq handler. That just happens on HSW, not BDW+. > > Just kill this code. If we do it, we won't be checking for unclaimed registers on BDW+ without i915.mmio_debug=1. > -Chris > > -- > Chris Wilson, Intel Open Source Technology Centre
On Tue, Aug 26, 2014 at 09:17:11AM -0300, Paulo Zanoni wrote: > 2014-08-26 7:22 GMT-03:00 Chris Wilson <chris@chris-wilson.co.uk>: > > On Wed, Jul 16, 2014 at 05:49:29PM -0300, Paulo Zanoni wrote: > >> static void > >> -hsw_unclaimed_reg_check(struct drm_i915_private *dev_priv, u32 reg) > >> +hsw_unclaimed_reg_detect(struct drm_i915_private *dev_priv) > >> { > >> + if (i915.mmio_debug) > >> + return; > >> + > >> if (__raw_i915_read32(dev_priv, FPGA_DBG) & FPGA_DBG_RM_NOCLAIM) { > >> - DRM_ERROR("Unclaimed write to %x\n", reg); > >> + DRM_ERROR("Unclaimed register detected. Please use the i915.mmio_debug=1 to debug this problem."); > >> __raw_i915_write32(dev_priv, FPGA_DBG, FPGA_DBG_RM_NOCLAIM); > >> } > > > > What was the point here? You still add an extra read to every register > > write > > Well, we previously had 2 extra reads instead of 1, so with this patch > we're in a better position :) > > > > and then repeat the request to enable mmio_debug ad infinitum. > > Yeah, this could be avoided. OTOH, on most cases it's not gonna happen > frequently enough to annoy the user. How do you think I came across this? > > And > > you still check for illegal writes in the irq handler. > > That just happens on HSW, not BDW+. Even on hsw, it should be killed. Checking inside the irq handler is just insane. Just move it to one of the periodic checks since we can't get any more information than an error occurred, and ask to be re-run with mmio_debug (and then shut up) - heck you could even automatically enable it for a one-shot operation. > > > > Just kill this code. > > If we do it, we won't be checking for unclaimed registers on BDW+ > without i915.mmio_debug=1. Then do as above. -Chris
2014-08-26 9:42 GMT-03:00 Chris Wilson <chris@chris-wilson.co.uk>: > On Tue, Aug 26, 2014 at 09:17:11AM -0300, Paulo Zanoni wrote: >> 2014-08-26 7:22 GMT-03:00 Chris Wilson <chris@chris-wilson.co.uk>: >> > On Wed, Jul 16, 2014 at 05:49:29PM -0300, Paulo Zanoni wrote: >> >> static void >> >> -hsw_unclaimed_reg_check(struct drm_i915_private *dev_priv, u32 reg) >> >> +hsw_unclaimed_reg_detect(struct drm_i915_private *dev_priv) >> >> { >> >> + if (i915.mmio_debug) >> >> + return; >> >> + >> >> if (__raw_i915_read32(dev_priv, FPGA_DBG) & FPGA_DBG_RM_NOCLAIM) { >> >> - DRM_ERROR("Unclaimed write to %x\n", reg); >> >> + DRM_ERROR("Unclaimed register detected. Please use the i915.mmio_debug=1 to debug this problem."); >> >> __raw_i915_write32(dev_priv, FPGA_DBG, FPGA_DBG_RM_NOCLAIM); >> >> } >> > >> > What was the point here? You still add an extra read to every register >> > write >> >> Well, we previously had 2 extra reads instead of 1, so with this patch >> we're in a better position :) >> >> >> > and then repeat the request to enable mmio_debug ad infinitum. >> >> Yeah, this could be avoided. OTOH, on most cases it's not gonna happen >> frequently enough to annoy the user. > > How do you think I came across this? > >> > And >> > you still check for illegal writes in the irq handler. >> >> That just happens on HSW, not BDW+. > > Even on hsw, it should be killed. Checking inside the irq handler is > just insane. Just move it to one of the periodic checks since we can't > get any more information than an error occurred, and ask to be re-run > with mmio_debug (and then shut up) - heck you could even automatically > enable it for a one-shot operation. Yeah, looking at how the IRQ handler situation is _today_, I agree it doesn't really make too much sense. I know it was different in the past, so I wonder how we ended up reaching this point :) Anyway, if we just remove the call to intel_uncore_check_errors() that happens on the irq handler, we'll still end up checking for errors as soon as we I915_WRITE(DEIER), so that won't be too much helpful. One thing we could do would be to remove the check from the I915_WRITE macros and put it on a real periodic check that could be executed at other specific points of our code (less frequent than every i915_write), or put it at its own workqueue that gets run every X jiffies. Or perhaps change the implementation of hsw_unclaimed_reg_detect() to not do anything when we're in an interrupt/spinlock context. Which one do you think is better to do? Of course, we can also implement the one-shot thing on top of the above, but it won't really help us reducing the amount of reads on the "happy case" where we never got the error before. All I have to say in my defense is that I did ask you to look at this patch before it was merged :) > >> > >> > Just kill this code. >> >> If we do it, we won't be checking for unclaimed registers on BDW+ >> without i915.mmio_debug=1. > > Then do as above. > -Chris > > -- > Chris Wilson, Intel Open Source Technology Centre
On Tue, Aug 26, 2014 at 10:04:22AM -0300, Paulo Zanoni wrote: > 2014-08-26 9:42 GMT-03:00 Chris Wilson <chris@chris-wilson.co.uk>: > > On Tue, Aug 26, 2014 at 09:17:11AM -0300, Paulo Zanoni wrote: > >> 2014-08-26 7:22 GMT-03:00 Chris Wilson <chris@chris-wilson.co.uk>: > >> > On Wed, Jul 16, 2014 at 05:49:29PM -0300, Paulo Zanoni wrote: > >> >> static void > >> >> -hsw_unclaimed_reg_check(struct drm_i915_private *dev_priv, u32 reg) > >> >> +hsw_unclaimed_reg_detect(struct drm_i915_private *dev_priv) > >> >> { > >> >> + if (i915.mmio_debug) > >> >> + return; > >> >> + > >> >> if (__raw_i915_read32(dev_priv, FPGA_DBG) & FPGA_DBG_RM_NOCLAIM) { > >> >> - DRM_ERROR("Unclaimed write to %x\n", reg); > >> >> + DRM_ERROR("Unclaimed register detected. Please use the i915.mmio_debug=1 to debug this problem."); > >> >> __raw_i915_write32(dev_priv, FPGA_DBG, FPGA_DBG_RM_NOCLAIM); > >> >> } > >> > > >> > What was the point here? You still add an extra read to every register > >> > write > >> > >> Well, we previously had 2 extra reads instead of 1, so with this patch > >> we're in a better position :) > >> > >> > >> > and then repeat the request to enable mmio_debug ad infinitum. > >> > >> Yeah, this could be avoided. OTOH, on most cases it's not gonna happen > >> frequently enough to annoy the user. > > > > How do you think I came across this? > > > >> > And > >> > you still check for illegal writes in the irq handler. > >> > >> That just happens on HSW, not BDW+. > > > > Even on hsw, it should be killed. Checking inside the irq handler is > > just insane. Just move it to one of the periodic checks since we can't > > get any more information than an error occurred, and ask to be re-run > > with mmio_debug (and then shut up) - heck you could even automatically > > enable it for a one-shot operation. > > Yeah, looking at how the IRQ handler situation is _today_, I agree it > doesn't really make too much sense. I know it was different in the > past, so I wonder how we ended up reaching this point :) > > Anyway, if we just remove the call to intel_uncore_check_errors() that > happens on the irq handler, we'll still end up checking for errors as > soon as we I915_WRITE(DEIER), so that won't be too much helpful. One > thing we could do would be to remove the check from the I915_WRITE > macros and put it on a real periodic check that could be executed at > other specific points of our code (less frequent than every > i915_write), or put it at its own workqueue that gets run every X > jiffies. Or perhaps change the implementation of > hsw_unclaimed_reg_detect() to not do anything when we're in an > interrupt/spinlock context. Which one do you think is better to do? From the irq handler, we can use just use raw mmio interfaces and skip all the debug and forcewake. I think the solution I prefer is to instrument modesetting (say check_state) and warn if an error had occurred outside of mmio_debug. > Of course, we can also implement the one-shot thing on top of the > above, but it won't really help us reducing the amount of reads on the > "happy case" where we never got the error before. Actually I am tempted to dynamically patch the mmio vfuncs to avoid even the forcewake spinlock when we already hold it. So there won't be any such logic except when enabled by the user. -Chris
2014-08-26 10:18 GMT-03:00 Chris Wilson <chris@chris-wilson.co.uk>: > On Tue, Aug 26, 2014 at 10:04:22AM -0300, Paulo Zanoni wrote: >> 2014-08-26 9:42 GMT-03:00 Chris Wilson <chris@chris-wilson.co.uk>: >> > On Tue, Aug 26, 2014 at 09:17:11AM -0300, Paulo Zanoni wrote: >> >> 2014-08-26 7:22 GMT-03:00 Chris Wilson <chris@chris-wilson.co.uk>: >> >> > On Wed, Jul 16, 2014 at 05:49:29PM -0300, Paulo Zanoni wrote: >> >> >> static void >> >> >> -hsw_unclaimed_reg_check(struct drm_i915_private *dev_priv, u32 reg) >> >> >> +hsw_unclaimed_reg_detect(struct drm_i915_private *dev_priv) >> >> >> { >> >> >> + if (i915.mmio_debug) >> >> >> + return; >> >> >> + >> >> >> if (__raw_i915_read32(dev_priv, FPGA_DBG) & FPGA_DBG_RM_NOCLAIM) { >> >> >> - DRM_ERROR("Unclaimed write to %x\n", reg); >> >> >> + DRM_ERROR("Unclaimed register detected. Please use the i915.mmio_debug=1 to debug this problem."); >> >> >> __raw_i915_write32(dev_priv, FPGA_DBG, FPGA_DBG_RM_NOCLAIM); >> >> >> } >> >> > >> >> > What was the point here? You still add an extra read to every register >> >> > write >> >> >> >> Well, we previously had 2 extra reads instead of 1, so with this patch >> >> we're in a better position :) >> >> >> >> >> >> > and then repeat the request to enable mmio_debug ad infinitum. >> >> >> >> Yeah, this could be avoided. OTOH, on most cases it's not gonna happen >> >> frequently enough to annoy the user. >> > >> > How do you think I came across this? >> > >> >> > And >> >> > you still check for illegal writes in the irq handler. >> >> >> >> That just happens on HSW, not BDW+. >> > >> > Even on hsw, it should be killed. Checking inside the irq handler is >> > just insane. Just move it to one of the periodic checks since we can't >> > get any more information than an error occurred, and ask to be re-run >> > with mmio_debug (and then shut up) - heck you could even automatically >> > enable it for a one-shot operation. >> >> Yeah, looking at how the IRQ handler situation is _today_, I agree it >> doesn't really make too much sense. I know it was different in the >> past, so I wonder how we ended up reaching this point :) >> >> Anyway, if we just remove the call to intel_uncore_check_errors() that >> happens on the irq handler, we'll still end up checking for errors as >> soon as we I915_WRITE(DEIER), so that won't be too much helpful. One >> thing we could do would be to remove the check from the I915_WRITE >> macros and put it on a real periodic check that could be executed at >> other specific points of our code (less frequent than every >> i915_write), or put it at its own workqueue that gets run every X >> jiffies. Or perhaps change the implementation of >> hsw_unclaimed_reg_detect() to not do anything when we're in an >> interrupt/spinlock context. Which one do you think is better to do? > > From the irq handler, we can use just use raw mmio interfaces and skip > all the debug and forcewake. I think the solution I prefer is to > instrument modesetting (say check_state) and warn if an error had occurred > outside of mmio_debug. My only problem with checking at modesetting is that we often spend hours and hours without doing a modeset, so it could lead to problems not ever being detected. So maybe there's a better place, but if that's what we want I won't block any patches. > >> Of course, we can also implement the one-shot thing on top of the >> above, but it won't really help us reducing the amount of reads on the >> "happy case" where we never got the error before. > > Actually I am tempted to dynamically patch the mmio vfuncs to avoid even > the forcewake spinlock when we already hold it. So there won't be any > such logic except when enabled by the user. Should I expect a patch from you, or should I go and write the patch based on what we already discussed? > -Chris > > -- > Chris Wilson, Intel Open Source Technology Centre
On Tue, Aug 26, 2014 at 10:29:23AM -0300, Paulo Zanoni wrote: > 2014-08-26 10:18 GMT-03:00 Chris Wilson <chris@chris-wilson.co.uk>: > > On Tue, Aug 26, 2014 at 10:04:22AM -0300, Paulo Zanoni wrote: > >> Of course, we can also implement the one-shot thing on top of the > >> above, but it won't really help us reducing the amount of reads on the > >> "happy case" where we never got the error before. > > > > Actually I am tempted to dynamically patch the mmio vfuncs to avoid even > > the forcewake spinlock when we already hold it. So there won't be any > > such logic except when enabled by the user. > > Should I expect a patch from you, or should I go and write the patch > based on what we already discussed? Imo this is crazy - we have no control over what the compiler does and when exactly it loads vtable entries, so patching them at runtime would be an interesting excercise at best. Adding a special version of I915_READ/WRITE for the irq hotpath makes sense, but only if we can actually show a benefit in benchmarks. -Daniel
On Tue, Aug 26, 2014 at 03:34:07PM +0200, Daniel Vetter wrote: > On Tue, Aug 26, 2014 at 10:29:23AM -0300, Paulo Zanoni wrote: > > 2014-08-26 10:18 GMT-03:00 Chris Wilson <chris@chris-wilson.co.uk>: > > > On Tue, Aug 26, 2014 at 10:04:22AM -0300, Paulo Zanoni wrote: > > >> Of course, we can also implement the one-shot thing on top of the > > >> above, but it won't really help us reducing the amount of reads on the > > >> "happy case" where we never got the error before. > > > > > > Actually I am tempted to dynamically patch the mmio vfuncs to avoid even > > > the forcewake spinlock when we already hold it. So there won't be any > > > such logic except when enabled by the user. > > > > Should I expect a patch from you, or should I go and write the patch > > based on what we already discussed? > > Imo this is crazy - we have no control over what the compiler does and > when exactly it loads vtable entries, so patching them at runtime would be > an interesting excercise at best. Wtf? -Chris
On Tue, Aug 26, 2014 at 02:46:25PM +0100, Chris Wilson wrote: > On Tue, Aug 26, 2014 at 03:34:07PM +0200, Daniel Vetter wrote: > > On Tue, Aug 26, 2014 at 10:29:23AM -0300, Paulo Zanoni wrote: > > > 2014-08-26 10:18 GMT-03:00 Chris Wilson <chris@chris-wilson.co.uk>: > > > > On Tue, Aug 26, 2014 at 10:04:22AM -0300, Paulo Zanoni wrote: > > > >> Of course, we can also implement the one-shot thing on top of the > > > >> above, but it won't really help us reducing the amount of reads on the > > > >> "happy case" where we never got the error before. > > > > > > > > Actually I am tempted to dynamically patch the mmio vfuncs to avoid even > > > > the forcewake spinlock when we already hold it. So there won't be any > > > > such logic except when enabled by the user. > > > > > > Should I expect a patch from you, or should I go and write the patch > > > based on what we already discussed? > > > > Imo this is crazy - we have no control over what the compiler does and > > when exactly it loads vtable entries, so patching them at runtime would be > > an interesting excercise at best. > > Wtf? I've assumed you'd runtime patch the vtables or something like that. And I didn't see any other less crazy way to ... -Daniel
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 991b663..ca0a9dd 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2135,6 +2135,7 @@ struct i915_params { bool disable_display; bool disable_vtd_wa; int use_mmio_flip; + bool mmio_debug; }; extern struct i915_params i915 __read_mostly; diff --git a/drivers/gpu/drm/i915/i915_params.c b/drivers/gpu/drm/i915/i915_params.c index bbdee21..62ee830 100644 --- a/drivers/gpu/drm/i915/i915_params.c +++ b/drivers/gpu/drm/i915/i915_params.c @@ -49,6 +49,7 @@ struct i915_params i915 __read_mostly = { .enable_cmd_parser = 1, .disable_vtd_wa = 0, .use_mmio_flip = 0, + .mmio_debug = 0, }; module_param_named(modeset, i915.modeset, int, 0400); @@ -161,3 +162,8 @@ MODULE_PARM_DESC(enable_cmd_parser, module_param_named(use_mmio_flip, i915.use_mmio_flip, int, 0600); MODULE_PARM_DESC(use_mmio_flip, "use MMIO flips (-1=never, 0=driver discretion [default], 1=always)"); + +module_param_named(mmio_debug, i915.mmio_debug, bool, 0600); +MODULE_PARM_DESC(mmio_debug, + "Enable the MMIO debug code (default: false). This may negatively " + "affect performance."); diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index e0f0843..6fee122 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -514,20 +514,30 @@ ilk_dummy_write(struct drm_i915_private *dev_priv) } static void -hsw_unclaimed_reg_clear(struct drm_i915_private *dev_priv, u32 reg) +hsw_unclaimed_reg_debug(struct drm_i915_private *dev_priv, u32 reg, bool read, + bool before) { + const char *op = read ? "reading" : "writing to"; + const char *when = before ? "before" : "after"; + + if (!i915.mmio_debug) + return; + if (__raw_i915_read32(dev_priv, FPGA_DBG) & FPGA_DBG_RM_NOCLAIM) { - DRM_ERROR("Unknown unclaimed register before writing to %x\n", - reg); + WARN(1, "Unclaimed register detected %s %s register 0x%x\n", + when, op, reg); __raw_i915_write32(dev_priv, FPGA_DBG, FPGA_DBG_RM_NOCLAIM); } } static void -hsw_unclaimed_reg_check(struct drm_i915_private *dev_priv, u32 reg) +hsw_unclaimed_reg_detect(struct drm_i915_private *dev_priv) { + if (i915.mmio_debug) + return; + if (__raw_i915_read32(dev_priv, FPGA_DBG) & FPGA_DBG_RM_NOCLAIM) { - DRM_ERROR("Unclaimed write to %x\n", reg); + DRM_ERROR("Unclaimed register detected. Please use the i915.mmio_debug=1 to debug this problem."); __raw_i915_write32(dev_priv, FPGA_DBG, FPGA_DBG_RM_NOCLAIM); } } @@ -564,6 +574,7 @@ gen5_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \ static u##x \ gen6_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \ REG_READ_HEADER(x); \ + hsw_unclaimed_reg_debug(dev_priv, reg, true, true); \ if (dev_priv->uncore.forcewake_count == 0 && \ NEEDS_FORCE_WAKE((dev_priv), (reg))) { \ dev_priv->uncore.funcs.force_wake_get(dev_priv, \ @@ -574,6 +585,7 @@ gen6_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \ } else { \ val = __raw_i915_read##x(dev_priv, reg); \ } \ + hsw_unclaimed_reg_debug(dev_priv, reg, true, false); \ REG_READ_FOOTER; \ } @@ -700,12 +712,13 @@ hsw_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace) if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \ __fifo_ret = __gen6_gt_wait_for_fifo(dev_priv); \ } \ - hsw_unclaimed_reg_clear(dev_priv, reg); \ + hsw_unclaimed_reg_debug(dev_priv, reg, false, true); \ __raw_i915_write##x(dev_priv, reg, val); \ if (unlikely(__fifo_ret)) { \ gen6_gt_check_fifodbg(dev_priv); \ } \ - hsw_unclaimed_reg_check(dev_priv, reg); \ + hsw_unclaimed_reg_debug(dev_priv, reg, false, false); \ + hsw_unclaimed_reg_detect(dev_priv); \ REG_WRITE_FOOTER; \ }