Commit cefcff8f authored by Joonas Lahtinen's avatar Joonas Lahtinen

drm/i915: Do not leak dev_priv->l3_parity.remap_info[]

Add intel_irq_fini() for placing the deinitialization code,
starting with freeing dev_priv->l3_parity.remap_info[].
Signed-off-by: default avatarJoonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Cc: Mika Kuoppala <mika.kuoppala@intel.com>
Reviewed-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Link: http://patchwork.freedesktop.org/patch/msgid/1493366319-18515-1-git-send-email-joonas.lahtinen@linux.intel.com
parent a021880f
...@@ -852,7 +852,7 @@ static int i915_driver_init_early(struct drm_i915_private *dev_priv, ...@@ -852,7 +852,7 @@ static int i915_driver_init_early(struct drm_i915_private *dev_priv,
intel_init_audio_hooks(dev_priv); intel_init_audio_hooks(dev_priv);
ret = i915_gem_load_init(dev_priv); ret = i915_gem_load_init(dev_priv);
if (ret < 0) if (ret < 0)
goto err_workqueues; goto err_irq;
intel_display_crc_init(dev_priv); intel_display_crc_init(dev_priv);
...@@ -864,7 +864,8 @@ static int i915_driver_init_early(struct drm_i915_private *dev_priv, ...@@ -864,7 +864,8 @@ static int i915_driver_init_early(struct drm_i915_private *dev_priv,
return 0; return 0;
err_workqueues: err_irq:
intel_irq_fini(dev_priv);
i915_workqueues_cleanup(dev_priv); i915_workqueues_cleanup(dev_priv);
err_engines: err_engines:
i915_engines_cleanup(dev_priv); i915_engines_cleanup(dev_priv);
...@@ -879,6 +880,7 @@ static void i915_driver_cleanup_early(struct drm_i915_private *dev_priv) ...@@ -879,6 +880,7 @@ static void i915_driver_cleanup_early(struct drm_i915_private *dev_priv)
{ {
i915_perf_fini(dev_priv); i915_perf_fini(dev_priv);
i915_gem_load_cleanup(dev_priv); i915_gem_load_cleanup(dev_priv);
intel_irq_fini(dev_priv);
i915_workqueues_cleanup(dev_priv); i915_workqueues_cleanup(dev_priv);
i915_engines_cleanup(dev_priv); i915_engines_cleanup(dev_priv);
} }
......
...@@ -3057,6 +3057,7 @@ void i915_handle_error(struct drm_i915_private *dev_priv, ...@@ -3057,6 +3057,7 @@ void i915_handle_error(struct drm_i915_private *dev_priv,
const char *fmt, ...); const char *fmt, ...);
extern void intel_irq_init(struct drm_i915_private *dev_priv); extern void intel_irq_init(struct drm_i915_private *dev_priv);
extern void intel_irq_fini(struct drm_i915_private *dev_priv);
int intel_irq_install(struct drm_i915_private *dev_priv); int intel_irq_install(struct drm_i915_private *dev_priv);
void intel_irq_uninstall(struct drm_i915_private *dev_priv); void intel_irq_uninstall(struct drm_i915_private *dev_priv);
......
...@@ -1236,7 +1236,7 @@ static void gen6_pm_rps_work(struct work_struct *work) ...@@ -1236,7 +1236,7 @@ static void gen6_pm_rps_work(struct work_struct *work)
static void ivybridge_parity_work(struct work_struct *work) static void ivybridge_parity_work(struct work_struct *work)
{ {
struct drm_i915_private *dev_priv = struct drm_i915_private *dev_priv =
container_of(work, struct drm_i915_private, l3_parity.error_work); container_of(work, typeof(*dev_priv), l3_parity.error_work);
u32 error_status, row, bank, subbank; u32 error_status, row, bank, subbank;
char *parity_event[6]; char *parity_event[6];
uint32_t misccpctl; uint32_t misccpctl;
...@@ -4233,11 +4233,15 @@ static void i965_irq_uninstall(struct drm_device * dev) ...@@ -4233,11 +4233,15 @@ static void i965_irq_uninstall(struct drm_device * dev)
void intel_irq_init(struct drm_i915_private *dev_priv) void intel_irq_init(struct drm_i915_private *dev_priv)
{ {
struct drm_device *dev = &dev_priv->drm; struct drm_device *dev = &dev_priv->drm;
int i;
intel_hpd_init_work(dev_priv); intel_hpd_init_work(dev_priv);
INIT_WORK(&dev_priv->rps.work, gen6_pm_rps_work); INIT_WORK(&dev_priv->rps.work, gen6_pm_rps_work);
INIT_WORK(&dev_priv->l3_parity.error_work, ivybridge_parity_work); INIT_WORK(&dev_priv->l3_parity.error_work, ivybridge_parity_work);
for (i = 0; i < MAX_L3_SLICES; ++i)
dev_priv->l3_parity.remap_info[i] = NULL;
if (HAS_GUC_SCHED(dev_priv)) if (HAS_GUC_SCHED(dev_priv))
dev_priv->pm_guc_events = GEN9_GUC_TO_HOST_INT_EVENT; dev_priv->pm_guc_events = GEN9_GUC_TO_HOST_INT_EVENT;
...@@ -4362,6 +4366,20 @@ void intel_irq_init(struct drm_i915_private *dev_priv) ...@@ -4362,6 +4366,20 @@ void intel_irq_init(struct drm_i915_private *dev_priv)
} }
} }
/**
* intel_irq_fini - deinitializes IRQ support
* @i915: i915 device instance
*
* This function deinitializes all the IRQ support.
*/
void intel_irq_fini(struct drm_i915_private *i915)
{
int i;
for (i = 0; i < MAX_L3_SLICES; ++i)
kfree(i915->l3_parity.remap_info[i]);
}
/** /**
* intel_irq_install - enables the hardware interrupt * intel_irq_install - enables the hardware interrupt
* @dev_priv: i915 device instance * @dev_priv: i915 device instance
......
...@@ -181,8 +181,8 @@ i915_l3_write(struct file *filp, struct kobject *kobj, ...@@ -181,8 +181,8 @@ i915_l3_write(struct file *filp, struct kobject *kobj,
struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev); struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev);
struct drm_device *dev = &dev_priv->drm; struct drm_device *dev = &dev_priv->drm;
struct i915_gem_context *ctx; struct i915_gem_context *ctx;
u32 *temp = NULL; /* Just here to make handling failures easy */
int slice = (int)(uintptr_t)attr->private; int slice = (int)(uintptr_t)attr->private;
u32 **remap_info;
int ret; int ret;
ret = l3_access_valid(dev_priv, offset); ret = l3_access_valid(dev_priv, offset);
...@@ -193,11 +193,12 @@ i915_l3_write(struct file *filp, struct kobject *kobj, ...@@ -193,11 +193,12 @@ i915_l3_write(struct file *filp, struct kobject *kobj,
if (ret) if (ret)
return ret; return ret;
if (!dev_priv->l3_parity.remap_info[slice]) { remap_info = &dev_priv->l3_parity.remap_info[slice];
temp = kzalloc(GEN7_L3LOG_SIZE, GFP_KERNEL); if (!*remap_info) {
if (!temp) { *remap_info = kzalloc(GEN7_L3LOG_SIZE, GFP_KERNEL);
mutex_unlock(&dev->struct_mutex); if (!*remap_info) {
return -ENOMEM; ret = -ENOMEM;
goto out;
} }
} }
...@@ -205,18 +206,18 @@ i915_l3_write(struct file *filp, struct kobject *kobj, ...@@ -205,18 +206,18 @@ i915_l3_write(struct file *filp, struct kobject *kobj,
* aren't propagated. Since I cannot find a stable way to reset the GPU * aren't propagated. Since I cannot find a stable way to reset the GPU
* at this point it is left as a TODO. * at this point it is left as a TODO.
*/ */
if (temp) memcpy(*remap_info + (offset/4), buf, count);
dev_priv->l3_parity.remap_info[slice] = temp;
memcpy(dev_priv->l3_parity.remap_info[slice] + (offset/4), buf, count);
/* NB: We defer the remapping until we switch to the context */ /* NB: We defer the remapping until we switch to the context */
list_for_each_entry(ctx, &dev_priv->context_list, link) list_for_each_entry(ctx, &dev_priv->context_list, link)
ctx->remap_slice |= (1<<slice); ctx->remap_slice |= (1<<slice);
ret = count;
out:
mutex_unlock(&dev->struct_mutex); mutex_unlock(&dev->struct_mutex);
return count; return ret;
} }
static struct bin_attribute dpf_attrs = { static struct bin_attribute dpf_attrs = {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment