Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cefcff8f authored by Joonas Lahtinen's avatar Joonas Lahtinen
Browse files

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
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -852,7 +852,7 @@ static int i915_driver_init_early(struct drm_i915_private *dev_priv,
	intel_init_audio_hooks(dev_priv);
	ret = i915_gem_load_init(dev_priv);
	if (ret < 0)
		goto err_workqueues;
		goto err_irq;

	intel_display_crc_init(dev_priv);

@@ -864,7 +864,8 @@ static int i915_driver_init_early(struct drm_i915_private *dev_priv,

	return 0;

err_workqueues:
err_irq:
	intel_irq_fini(dev_priv);
	i915_workqueues_cleanup(dev_priv);
err_engines:
	i915_engines_cleanup(dev_priv);
@@ -879,6 +880,7 @@ static void i915_driver_cleanup_early(struct drm_i915_private *dev_priv)
{
	i915_perf_fini(dev_priv);
	i915_gem_load_cleanup(dev_priv);
	intel_irq_fini(dev_priv);
	i915_workqueues_cleanup(dev_priv);
	i915_engines_cleanup(dev_priv);
}
+1 −0
Original line number Diff line number Diff line
@@ -3057,6 +3057,7 @@ void i915_handle_error(struct drm_i915_private *dev_priv,
		       const char *fmt, ...);

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);
void intel_irq_uninstall(struct drm_i915_private *dev_priv);

+19 −1
Original line number Diff line number Diff line
@@ -1236,7 +1236,7 @@ static void gen6_pm_rps_work(struct work_struct *work)
static void ivybridge_parity_work(struct work_struct *work)
{
	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;
	char *parity_event[6];
	uint32_t misccpctl;
@@ -4233,11 +4233,15 @@ static void i965_irq_uninstall(struct drm_device * dev)
void intel_irq_init(struct drm_i915_private *dev_priv)
{
	struct drm_device *dev = &dev_priv->drm;
	int i;

	intel_hpd_init_work(dev_priv);

	INIT_WORK(&dev_priv->rps.work, gen6_pm_rps_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))
		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)
	}
}

/**
 * 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
 * @dev_priv: i915 device instance
+12 −11
Original line number Diff line number Diff line
@@ -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_device *dev = &dev_priv->drm;
	struct i915_gem_context *ctx;
	u32 *temp = NULL; /* Just here to make handling failures easy */
	int slice = (int)(uintptr_t)attr->private;
	u32 **remap_info;
	int ret;

	ret = l3_access_valid(dev_priv, offset);
@@ -193,11 +193,12 @@ i915_l3_write(struct file *filp, struct kobject *kobj,
	if (ret)
		return ret;

	if (!dev_priv->l3_parity.remap_info[slice]) {
		temp = kzalloc(GEN7_L3LOG_SIZE, GFP_KERNEL);
		if (!temp) {
			mutex_unlock(&dev->struct_mutex);
			return -ENOMEM;
	remap_info = &dev_priv->l3_parity.remap_info[slice];
	if (!*remap_info) {
		*remap_info = kzalloc(GEN7_L3LOG_SIZE, GFP_KERNEL);
		if (!*remap_info) {
			ret = -ENOMEM;
			goto out;
		}
	}

@@ -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
	 * at this point it is left as a TODO.
	*/
	if (temp)
		dev_priv->l3_parity.remap_info[slice] = temp;

	memcpy(dev_priv->l3_parity.remap_info[slice] + (offset/4), buf, count);
	memcpy(*remap_info + (offset/4), buf, count);

	/* NB: We defer the remapping until we switch to the context */
	list_for_each_entry(ctx, &dev_priv->context_list, link)
		ctx->remap_slice |= (1<<slice);

	ret = count;

out:
	mutex_unlock(&dev->struct_mutex);

	return count;
	return ret;
}

static struct bin_attribute dpf_attrs = {