From: "Ville Syrjälä" <ville.syrjala@linux.intel.com>
To: Ben Widawsky <benjamin.widawsky@intel.com>
Cc: intel-gfx@lists.freedesktop.org, vishnu.venkatesh@intel.com,
bryan.j.bell@intel.com, Ben Widawsky <ben@bwidawsk.net>
Subject: Re: [PATCH 5/8] drm/i915: Add second slice l3 remapping
Date: Fri, 13 Sep 2013 12:38:01 +0300 [thread overview]
Message-ID: <20130913093801.GN20128@intel.com> (raw)
In-Reply-To: <1379050122-12774-6-git-send-email-benjamin.widawsky@intel.com>
On Thu, Sep 12, 2013 at 10:28:31PM -0700, Ben Widawsky wrote:
> Certain HSW SKUs have a second bank of L3. This L3 remapping has a
> separate register set, and interrupt from the first "slice". A slice is
> simply a term to define some subset of the GPU's l3 cache. This patch
> implements both the interrupt handler, and ability to communicate with
> userspace about this second slice.
>
> Signed-off-by: Ben Widawsky <ben@bwidawsk.net>
> ---
> drivers/gpu/drm/i915/i915_drv.h | 9 ++--
> drivers/gpu/drm/i915/i915_gem.c | 26 ++++++----
> drivers/gpu/drm/i915/i915_irq.c | 84 +++++++++++++++++++++------------
> drivers/gpu/drm/i915/i915_reg.h | 6 +++
> drivers/gpu/drm/i915/i915_sysfs.c | 34 ++++++++++---
> drivers/gpu/drm/i915/intel_ringbuffer.c | 6 +--
> include/uapi/drm/i915_drm.h | 8 ++--
> 7 files changed, 115 insertions(+), 58 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 81ba5bb..eb90461 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -918,9 +918,11 @@ struct i915_ums_state {
> int mm_suspended;
> };
>
> +#define MAX_L3_SLICES 2
> struct intel_l3_parity {
> - u32 *remap_info;
> + u32 *remap_info[MAX_L3_SLICES];
> struct work_struct error_work;
> + int which_slice;
> };
>
> struct i915_gem_mm {
> @@ -1686,7 +1688,8 @@ struct drm_i915_file_private {
>
> #define HAS_FORCE_WAKE(dev) (INTEL_INFO(dev)->has_force_wake)
>
> -#define HAS_L3_GPU_CACHE(dev) (IS_IVYBRIDGE(dev) || IS_HASWELL(dev))
> +#define HAS_L3_GPU_CACHE(dev) (INTEL_INFO(dev)->gen >= 7)
> +#define NUM_L3_SLICES(dev) (IS_HSW_GT3(dev) ? 2 : HAS_L3_GPU_CACHE(dev))
>
> #define GT_FREQUENCY_MULTIPLIER 50
>
> @@ -1947,7 +1950,7 @@ bool i915_gem_clflush_object(struct drm_i915_gem_object *obj, bool force);
> int __must_check i915_gem_object_finish_gpu(struct drm_i915_gem_object *obj);
> int __must_check i915_gem_init(struct drm_device *dev);
> int __must_check i915_gem_init_hw(struct drm_device *dev);
> -void i915_gem_l3_remap(struct drm_device *dev);
> +void i915_gem_l3_remap(struct drm_device *dev, int slice);
> void i915_gem_init_swizzling(struct drm_device *dev);
> void i915_gem_cleanup_ringbuffer(struct drm_device *dev);
> int __must_check i915_gpu_idle(struct drm_device *dev);
> diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
> index 5b510a3..b11f7d6c 100644
> --- a/drivers/gpu/drm/i915/i915_gem.c
> +++ b/drivers/gpu/drm/i915/i915_gem.c
> @@ -4256,16 +4256,21 @@ i915_gem_idle(struct drm_device *dev)
> return 0;
> }
>
> -void i915_gem_l3_remap(struct drm_device *dev)
> +void i915_gem_l3_remap(struct drm_device *dev, int slice)
> {
> drm_i915_private_t *dev_priv = dev->dev_private;
> + u32 reg_base = GEN7_L3LOG_BASE + (slice * 0x200);
> + u32 *remap_info = dev_priv->l3_parity.remap_info[slice];
> u32 misccpctl;
> int i;
>
> if (!HAS_L3_GPU_CACHE(dev))
> return;
>
> - if (!dev_priv->l3_parity.remap_info)
> + if (NUM_L3_SLICES(dev) < 2 && slice)
> + return;
This check is redundant as we should never populate
l3_parity.remap_info[1] when there's no second slice.
> +
> + if (!remap_info)
> return;
>
> misccpctl = I915_READ(GEN7_MISCCPCTL);
> @@ -4273,17 +4278,17 @@ void i915_gem_l3_remap(struct drm_device *dev)
> POSTING_READ(GEN7_MISCCPCTL);
>
> for (i = 0; i < GEN7_L3LOG_SIZE; i += 4) {
> - u32 remap = I915_READ(GEN7_L3LOG_BASE + i);
> - if (remap && remap != dev_priv->l3_parity.remap_info[i/4])
> + u32 remap = I915_READ(reg_base + i);
> + if (remap && remap != remap_info[i/4])
> DRM_DEBUG("0x%x was already programmed to %x\n",
> - GEN7_L3LOG_BASE + i, remap);
> - if (remap && !dev_priv->l3_parity.remap_info[i/4])
> + reg_base + i, remap);
> + if (remap && !remap_info[i/4])
> DRM_DEBUG_DRIVER("Clearing remapped register\n");
> - I915_WRITE(GEN7_L3LOG_BASE + i, dev_priv->l3_parity.remap_info[i/4]);
> + I915_WRITE(reg_base + i, remap_info[i/4]);
> }
>
> /* Make sure all the writes land before disabling dop clock gating */
> - POSTING_READ(GEN7_L3LOG_BASE);
> + POSTING_READ(reg_base);
>
> I915_WRITE(GEN7_MISCCPCTL, misccpctl);
> }
> @@ -4377,7 +4382,7 @@ int
> i915_gem_init_hw(struct drm_device *dev)
> {
> drm_i915_private_t *dev_priv = dev->dev_private;
> - int ret;
> + int ret, i;
>
> if (INTEL_INFO(dev)->gen < 6 && !intel_enable_gtt())
> return -EIO;
> @@ -4396,7 +4401,8 @@ i915_gem_init_hw(struct drm_device *dev)
> I915_WRITE(GEN7_MSG_CTL, temp);
> }
>
> - i915_gem_l3_remap(dev);
> + for (i = 0; i < NUM_L3_SLICES(dev); i++)
> + i915_gem_l3_remap(dev, i);
>
> i915_gem_init_swizzling(dev);
>
> diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
> index 13d26cf..62cdf05 100644
> --- a/drivers/gpu/drm/i915/i915_irq.c
> +++ b/drivers/gpu/drm/i915/i915_irq.c
> @@ -882,9 +882,10 @@ static void ivybridge_parity_work(struct work_struct *work)
> drm_i915_private_t *dev_priv = container_of(work, drm_i915_private_t,
> l3_parity.error_work);
> u32 error_status, row, bank, subbank;
> - char *parity_event[5];
> + char *parity_event[6];
> uint32_t misccpctl;
> unsigned long flags;
> + uint8_t slice = 0;
>
> /* We must turn off DOP level clock gating to access the L3 registers.
> * In order to prevent a get/put style interface, acquire struct mutex
> @@ -892,45 +893,63 @@ static void ivybridge_parity_work(struct work_struct *work)
> */
> mutex_lock(&dev_priv->dev->struct_mutex);
>
> + /* If we've screwed up tracking, just let the interrupt fire again */
> + if (WARN_ON(!dev_priv->l3_parity.which_slice))
> + goto out;
> +
> misccpctl = I915_READ(GEN7_MISCCPCTL);
> I915_WRITE(GEN7_MISCCPCTL, misccpctl & ~GEN7_DOP_CLOCK_GATE_ENABLE);
> POSTING_READ(GEN7_MISCCPCTL);
>
> - error_status = I915_READ(GEN7_L3CDERRST1);
> - row = GEN7_PARITY_ERROR_ROW(error_status);
> - bank = GEN7_PARITY_ERROR_BANK(error_status);
> - subbank = GEN7_PARITY_ERROR_SUBBANK(error_status);
> + while ((slice = ffs(dev_priv->l3_parity.which_slice)) != 0) {
> + u32 reg;
>
> - I915_WRITE(GEN7_L3CDERRST1, GEN7_PARITY_ERROR_VALID |
> - GEN7_L3CDERRST1_ENABLE);
> - POSTING_READ(GEN7_L3CDERRST1);
> + if (WARN_ON(slice >= MAX_L3_SLICES))
> + break;
Could be >= NUM_L3_SLICES(dev) for a bit of extra paranoia. Also we
would fail to clear invalid bits from which_slice in this case, and
thus we'd get the WARN every time the work runs. But I guess this
should never happen in any case so probably not worth worrying about
this too much.
>
> - I915_WRITE(GEN7_MISCCPCTL, misccpctl);
> + dev_priv->l3_parity.which_slice &= ~(1<<slice);
>
> - spin_lock_irqsave(&dev_priv->irq_lock, flags);
> - ilk_enable_gt_irq(dev_priv, GT_RENDER_L3_PARITY_ERROR_INTERRUPT);
> - spin_unlock_irqrestore(&dev_priv->irq_lock, flags);
> + reg = GEN7_L3CDERRST1 + (slice * 0x200);
>
> - mutex_unlock(&dev_priv->dev->struct_mutex);
> + error_status = I915_READ(reg);
> + row = GEN7_PARITY_ERROR_ROW(error_status);
> + bank = GEN7_PARITY_ERROR_BANK(error_status);
> + subbank = GEN7_PARITY_ERROR_SUBBANK(error_status);
> +
> + I915_WRITE(reg, GEN7_PARITY_ERROR_VALID | GEN7_L3CDERRST1_ENABLE);
> + POSTING_READ(reg);
> +
> + parity_event[0] = I915_L3_PARITY_UEVENT "=1";
> + parity_event[1] = kasprintf(GFP_KERNEL, "ROW=%d", row);
> + parity_event[2] = kasprintf(GFP_KERNEL, "BANK=%d", bank);
> + parity_event[3] = kasprintf(GFP_KERNEL, "SUBBANK=%d", subbank);
> + parity_event[4] = kasprintf(GFP_KERNEL, "SLICE=%d", slice);
> + parity_event[5] = NULL;
>
> - parity_event[0] = I915_L3_PARITY_UEVENT "=1";
> - parity_event[1] = kasprintf(GFP_KERNEL, "ROW=%d", row);
> - parity_event[2] = kasprintf(GFP_KERNEL, "BANK=%d", bank);
> - parity_event[3] = kasprintf(GFP_KERNEL, "SUBBANK=%d", subbank);
> - parity_event[4] = NULL;
> + kobject_uevent_env(&dev_priv->dev->primary->kdev.kobj,
> + KOBJ_CHANGE, parity_event);
>
> - kobject_uevent_env(&dev_priv->dev->primary->kdev.kobj,
> - KOBJ_CHANGE, parity_event);
> + DRM_DEBUG("Parity error: Slice = %d, Row = %d, Bank = %d, Sub bank = %d.\n",
> + slice, row, bank, subbank);
>
> - DRM_DEBUG("Parity error: Row = %d, Bank = %d, Sub bank = %d.\n",
> - row, bank, subbank);
> + kfree(parity_event[4]);
> + kfree(parity_event[3]);
> + kfree(parity_event[2]);
> + kfree(parity_event[1]);
> + }
> +
> + I915_WRITE(GEN7_MISCCPCTL, misccpctl);
> +
> +out:
> + WARN_ON(dev_priv->l3_parity.which_slice);
First I figured the irq could rearm this behind our back, but we disable
the irq until the work is done. So yeah, this is fine.
> + spin_lock_irqsave(&dev_priv->irq_lock, flags);
> + ilk_enable_gt_irq(dev_priv, GT_PARITY_ERROR);
Is it actually safe to enable the second slice irq when there's no second
slice? This docs say it's just "reserved", but no mention whether it RO or
could there be side effects.
> + spin_unlock_irqrestore(&dev_priv->irq_lock, flags);
>
> - kfree(parity_event[3]);
> - kfree(parity_event[2]);
> - kfree(parity_event[1]);
> + mutex_unlock(&dev_priv->dev->struct_mutex);
> }
>
> -static void ivybridge_parity_error_irq_handler(struct drm_device *dev)
> +static void ivybridge_parity_error_irq_handler(struct drm_device *dev, u32 iir)
> {
> drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
>
> @@ -938,9 +957,12 @@ static void ivybridge_parity_error_irq_handler(struct drm_device *dev)
> return;
>
> spin_lock(&dev_priv->irq_lock);
> - ilk_disable_gt_irq(dev_priv, GT_RENDER_L3_PARITY_ERROR_INTERRUPT);
> + ilk_disable_gt_irq(dev_priv, GT_PARITY_ERROR);
> spin_unlock(&dev_priv->irq_lock);
>
> + iir &= GT_PARITY_ERROR;
> + dev_priv->l3_parity.which_slice =
> + 1 << (iir & GT_RENDER_L3_PARITY_ERROR_INTERRUPT_S1 ? 1 : 0);
What if both slices report an error at the same time?
> queue_work(dev_priv->wq, &dev_priv->l3_parity.error_work);
> }
>
> @@ -975,8 +997,8 @@ static void snb_gt_irq_handler(struct drm_device *dev,
> i915_handle_error(dev, false);
> }
>
> - if (gt_iir & GT_RENDER_L3_PARITY_ERROR_INTERRUPT)
> - ivybridge_parity_error_irq_handler(dev);
> + if (gt_iir & GT_PARITY_ERROR)
> + ivybridge_parity_error_irq_handler(dev, gt_iir);
> }
>
> #define HPD_STORM_DETECT_PERIOD 1000
> @@ -2261,8 +2283,8 @@ static void gen5_gt_irq_postinstall(struct drm_device *dev)
> dev_priv->gt_irq_mask = ~0;
> if (HAS_L3_GPU_CACHE(dev)) {
> /* L3 parity interrupt is always unmasked. */
> - dev_priv->gt_irq_mask = ~GT_RENDER_L3_PARITY_ERROR_INTERRUPT;
> - gt_irqs |= GT_RENDER_L3_PARITY_ERROR_INTERRUPT;
> + dev_priv->gt_irq_mask = ~GT_PARITY_ERROR;
> + gt_irqs |= GT_PARITY_ERROR;
> }
>
> gt_irqs |= GT_RENDER_USER_INTERRUPT;
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index bcee89b..4155a1d 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -927,6 +927,7 @@
> #define GT_BLT_USER_INTERRUPT (1 << 22)
> #define GT_BSD_CS_ERROR_INTERRUPT (1 << 15)
> #define GT_BSD_USER_INTERRUPT (1 << 12)
> +#define GT_RENDER_L3_PARITY_ERROR_INTERRUPT_S1 (1 << 11) /* hsw+; rsvd on snb, ivb, vlv */
> #define GT_RENDER_L3_PARITY_ERROR_INTERRUPT (1 << 5) /* !snb */
> #define GT_RENDER_PIPECTL_NOTIFY_INTERRUPT (1 << 4)
> #define GT_RENDER_CS_MASTER_ERROR_INTERRUPT (1 << 3)
> @@ -937,6 +938,9 @@
> #define PM_VEBOX_CS_ERROR_INTERRUPT (1 << 12) /* hsw+ */
> #define PM_VEBOX_USER_INTERRUPT (1 << 10) /* hsw+ */
>
> +#define GT_PARITY_ERROR (GT_RENDER_L3_PARITY_ERROR_INTERRUPT_S1 | \
> + GT_RENDER_L3_PARITY_ERROR_INTERRUPT)
> +
> /* These are all the "old" interrupts */
> #define ILK_BSD_USER_INTERRUPT (1<<5)
> #define I915_PIPE_CONTROL_NOTIFY_INTERRUPT (1<<18)
> @@ -4742,6 +4746,7 @@
>
> /* IVYBRIDGE DPF */
> #define GEN7_L3CDERRST1 0xB008 /* L3CD Error Status 1 */
> +#define HSW_L3CDERRST11 0xB208 /* L3CD Error Status register 1 slice 1 */
> #define GEN7_L3CDERRST1_ROW_MASK (0x7ff<<14)
> #define GEN7_PARITY_ERROR_VALID (1<<13)
> #define GEN7_L3CDERRST1_BANK_MASK (3<<11)
> @@ -4755,6 +4760,7 @@
> #define GEN7_L3CDERRST1_ENABLE (1<<7)
>
> #define GEN7_L3LOG_BASE 0xB070
> +#define HSW_L3LOG_BASE_SLICE1 0xB270
> #define GEN7_L3LOG_SIZE 0x80
>
> #define GEN7_HALF_SLICE_CHICKEN1 0xe100 /* IVB GT1 + VLV */
> diff --git a/drivers/gpu/drm/i915/i915_sysfs.c b/drivers/gpu/drm/i915/i915_sysfs.c
> index 43c2e81..d208f2d 100644
> --- a/drivers/gpu/drm/i915/i915_sysfs.c
> +++ b/drivers/gpu/drm/i915/i915_sysfs.c
> @@ -119,6 +119,7 @@ i915_l3_read(struct file *filp, struct kobject *kobj,
> struct drm_device *drm_dev = dminor->dev;
> struct drm_i915_private *dev_priv = drm_dev->dev_private;
> uint32_t misccpctl;
> + int slice = (int)(uintptr_t)attr->private;
> int i, ret;
>
> count = round_down(count, 4);
> @@ -135,11 +136,11 @@ i915_l3_read(struct file *filp, struct kobject *kobj,
>
> if (IS_HASWELL(drm_dev)) {
> int last = min_t(int, GEN7_L3LOG_SIZE, count + offset);
> - if ((!dev_priv->l3_parity.remap_info))
> + if ((!dev_priv->l3_parity.remap_info[slice]))
> memset(buf + offset, 0, last - offset);
> else
> memcpy(buf + offset,
> - dev_priv->l3_parity.remap_info + (offset/4),
> + dev_priv->l3_parity.remap_info[slice] + (offset/4),
> last - offset);
>
> i = last;
> @@ -170,6 +171,7 @@ i915_l3_write(struct file *filp, struct kobject *kobj,
> struct drm_device *drm_dev = dminor->dev;
> struct drm_i915_private *dev_priv = drm_dev->dev_private;
> u32 *temp = NULL; /* Just here to make handling failures easy */
> + int slice = (int)(uintptr_t)attr->private;
> int ret;
>
> ret = l3_access_valid(drm_dev, offset);
> @@ -180,7 +182,7 @@ i915_l3_write(struct file *filp, struct kobject *kobj,
> if (ret)
> return ret;
>
> - if (!dev_priv->l3_parity.remap_info) {
> + if (!dev_priv->l3_parity.remap_info[slice]) {
> temp = kzalloc(GEN7_L3LOG_SIZE, GFP_KERNEL);
> if (!temp) {
> mutex_unlock(&drm_dev->struct_mutex);
> @@ -200,11 +202,11 @@ i915_l3_write(struct file *filp, struct kobject *kobj,
> * at this point it is left as a TODO.
> */
> if (temp)
> - dev_priv->l3_parity.remap_info = temp;
> + dev_priv->l3_parity.remap_info[slice] = temp;
>
> - memcpy(dev_priv->l3_parity.remap_info + (offset/4), buf, count);
> + memcpy(dev_priv->l3_parity.remap_info[slice] + (offset/4), buf, count);
>
> - i915_gem_l3_remap(drm_dev);
> + i915_gem_l3_remap(drm_dev, slice);
>
> mutex_unlock(&drm_dev->struct_mutex);
>
> @@ -216,7 +218,17 @@ static struct bin_attribute dpf_attrs = {
> .size = GEN7_L3LOG_SIZE,
> .read = i915_l3_read,
> .write = i915_l3_write,
> - .mmap = NULL
> + .mmap = NULL,
> + .private = (void *)0
> +};
> +
> +static struct bin_attribute dpf_attrs_1 = {
> + .attr = {.name = "l3_parity_slice_1", .mode = (S_IRUSR | S_IWUSR)},
> + .size = GEN7_L3LOG_SIZE,
> + .read = i915_l3_read,
> + .write = i915_l3_write,
> + .mmap = NULL,
> + .private = (void *)1
> };
>
> static ssize_t gt_cur_freq_mhz_show(struct device *kdev,
> @@ -527,6 +539,13 @@ void i915_setup_sysfs(struct drm_device *dev)
> ret = device_create_bin_file(&dev->primary->kdev, &dpf_attrs);
> if (ret)
> DRM_ERROR("l3 parity sysfs setup failed\n");
> +
> + if (NUM_L3_SLICES(dev) > 1) {
> + ret = device_create_bin_file(&dev->primary->kdev,
> + &dpf_attrs_1);
> + if (ret)
> + DRM_ERROR("l3 parity slice 1 setup failed\n");
> + }
> }
>
> ret = 0;
> @@ -550,6 +569,7 @@ void i915_teardown_sysfs(struct drm_device *dev)
> sysfs_remove_files(&dev->primary->kdev.kobj, vlv_attrs);
> else
> sysfs_remove_files(&dev->primary->kdev.kobj, gen6_attrs);
> + device_remove_bin_file(&dev->primary->kdev, &dpf_attrs_1);
> device_remove_bin_file(&dev->primary->kdev, &dpf_attrs);
> #ifdef CONFIG_PM
> sysfs_unmerge_group(&dev->primary->kdev.kobj, &rc6_attr_group);
> diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
> index 686e5b2..3539b45 100644
> --- a/drivers/gpu/drm/i915/intel_ringbuffer.c
> +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
> @@ -570,7 +570,7 @@ static int init_render_ring(struct intel_ring_buffer *ring)
> I915_WRITE(INSTPM, _MASKED_BIT_ENABLE(INSTPM_FORCE_ORDERING));
>
> if (HAS_L3_GPU_CACHE(dev))
> - I915_WRITE_IMR(ring, ~GT_RENDER_L3_PARITY_ERROR_INTERRUPT);
> + I915_WRITE_IMR(ring, ~GT_PARITY_ERROR);
>
> return ret;
> }
> @@ -1000,7 +1000,7 @@ gen6_ring_get_irq(struct intel_ring_buffer *ring)
> if (HAS_L3_GPU_CACHE(dev) && ring->id == RCS)
> I915_WRITE_IMR(ring,
> ~(ring->irq_enable_mask |
> - GT_RENDER_L3_PARITY_ERROR_INTERRUPT));
> + GT_PARITY_ERROR));
> else
> I915_WRITE_IMR(ring, ~ring->irq_enable_mask);
> ilk_enable_gt_irq(dev_priv, ring->irq_enable_mask);
> @@ -1021,7 +1021,7 @@ gen6_ring_put_irq(struct intel_ring_buffer *ring)
> if (--ring->irq_refcount == 0) {
> if (HAS_L3_GPU_CACHE(dev) && ring->id == RCS)
> I915_WRITE_IMR(ring,
> - ~GT_RENDER_L3_PARITY_ERROR_INTERRUPT);
> + ~GT_PARITY_ERROR);
> else
> I915_WRITE_IMR(ring, ~0);
> ilk_disable_gt_irq(dev_priv, ring->irq_enable_mask);
> diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
> index 55bb572..3a4e97b 100644
> --- a/include/uapi/drm/i915_drm.h
> +++ b/include/uapi/drm/i915_drm.h
> @@ -38,10 +38,10 @@
> *
> * I915_L3_PARITY_UEVENT - Generated when the driver receives a parity mismatch
> * event from the gpu l3 cache. Additional information supplied is ROW,
> - * BANK, SUBBANK of the affected cacheline. Userspace should keep track of
> - * these events and if a specific cache-line seems to have a persistent
> - * error remap it with the l3 remapping tool supplied in intel-gpu-tools.
> - * The value supplied with the event is always 1.
> + * BANK, SUBBANK, SLICE of the affected cacheline. Userspace should keep
> + * track of these events and if a specific cache-line seems to have a
> + * persistent error remap it with the l3 remapping tool supplied in
> + * intel-gpu-tools. The value supplied with the event is always 1.
> *
> * I915_ERROR_UEVENT - Generated upon error detection, currently only via
> * hangcheck. The error detection event is a good indicator of when things
> --
> 1.8.4
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
--
Ville Syrjälä
Intel OTC
next prev parent reply other threads:[~2013-09-13 9:38 UTC|newest]
Thread overview: 40+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-09-13 5:28 [PATCH 0/8] DPF (GPU l3 parity detection) improvements Ben Widawsky
2013-09-13 5:28 ` [PATCH 1/8] drm/i915: Remove extra "ring" Ben Widawsky
2013-09-13 5:28 ` [PATCH 2/8] drm/i915: Round l3 parity reads down Ben Widawsky
2013-09-13 5:28 ` [PATCH 3/8] drm/i915: Fix l3 parity user buffer offset Ben Widawsky
2013-09-13 12:56 ` Daniel Vetter
2013-09-13 5:28 ` [PATCH 4/8] drm/i915: Fix HSW parity test Ben Widawsky
2013-09-13 8:17 ` Ville Syrjälä
2013-09-13 5:28 ` [PATCH 5/8] drm/i915: Add second slice l3 remapping Ben Widawsky
2013-09-13 9:38 ` Ville Syrjälä [this message]
2013-09-17 18:45 ` Ben Widawsky
2013-09-17 18:51 ` Bell, Bryan J
2013-09-17 19:02 ` Ville Syrjälä
2013-09-17 19:08 ` Bell, Bryan J
2013-09-13 5:28 ` [PATCH 6/8] drm/i915: Make l3 remapping use the ring Ben Widawsky
2013-09-13 16:16 ` Daniel Vetter
2013-09-13 5:28 ` [PATCH 7/8] drm/i915: Keep a list of all contexts Ben Widawsky
2013-09-13 5:28 ` [PATCH 8/8] drm/i915: Do remaps for " Ben Widawsky
2013-09-13 9:17 ` Ville Syrjälä
2013-09-13 9:20 ` Ville Syrjälä
2013-09-17 20:42 ` Ben Widawsky
2013-09-13 5:28 ` [PATCH 09/16] intel_l3_parity: Fix indentation Ben Widawsky
2013-09-13 5:28 ` [PATCH 10/16] intel_l3_parity: Assert all GEN7+ support Ben Widawsky
2013-09-16 18:18 ` Bell, Bryan J
2013-09-17 23:52 ` Ben Widawsky
2013-09-17 23:59 ` Ben Widawsky
2013-09-13 5:28 ` [PATCH 11/16] intel_l3_parity: Use getopt for the l3 parity tool Ben Widawsky
2013-09-13 5:28 ` [PATCH 12/16] intel_l3_parity: Hardware info argument Ben Widawsky
2013-09-13 5:28 ` [PATCH 13/16] intel_l3_parity: slice support Ben Widawsky
2013-09-13 5:28 ` [PATCH 14/16] intel_l3_parity: Actually support multiple slices Ben Widawsky
2013-09-13 5:28 ` [PATCH 15/16] intel_l3_parity: Support error injection Ben Widawsky
2013-09-13 9:12 ` Daniel Vetter
2013-09-13 15:54 ` Ben Widawsky
2013-09-13 16:14 ` Daniel Vetter
2013-09-13 16:29 ` Ben Widawsky
2013-09-13 5:28 ` [PATCH 16/16] intel_l3_parity: Support a daemonic mode Ben Widawsky
2013-09-13 9:44 ` [PATCH 0/8] DPF (GPU l3 parity detection) improvements Ville Syrjälä
2013-09-17 0:52 ` Bell, Bryan J
2013-09-17 4:15 ` Ben Widawsky
2013-09-17 7:27 ` Daniel Vetter
2013-09-17 18:23 ` Bell, Bryan J
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20130913093801.GN20128@intel.com \
--to=ville.syrjala@linux.intel.com \
--cc=ben@bwidawsk.net \
--cc=benjamin.widawsky@intel.com \
--cc=bryan.j.bell@intel.com \
--cc=intel-gfx@lists.freedesktop.org \
--cc=vishnu.venkatesh@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox