Skip to content

Commit

Permalink
drm/i915/overlay: Fix unpinning along init error paths
Browse files Browse the repository at this point in the history
As pointed out by Dan Carpenter, it was seemingly possible to hit an error
whilst mapping the buffer for the regs (except the only likely error
returns should not happen during init) and so leak a pin count on the
bo. To handle this we would need to reacquire the struct mutex, so for
simplicity rearrange for the lock to be held for the entire function.
For extra pedagogy, test that we only call init once.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Keith Packard <keithp@keithp.com>
Signed-off-by: Keith Packard <keithp@keithp.com>
  • Loading branch information
Chris Wilson authored and Keith Packard committed Jun 30, 2011
1 parent dc501fb commit 79d2427
Showing 1 changed file with 10 additions and 7 deletions.
17 changes: 10 additions & 7 deletions drivers/gpu/drm/i915/intel_overlay.c
Original file line number Diff line number Diff line change
Expand Up @@ -1409,15 +1409,18 @@ void intel_setup_overlay(struct drm_device *dev)
overlay = kzalloc(sizeof(struct intel_overlay), GFP_KERNEL);
if (!overlay)
return;

mutex_lock(&dev->struct_mutex);
if (WARN_ON(dev_priv->overlay))
goto out_free;

overlay->dev = dev;

reg_bo = i915_gem_alloc_object(dev, PAGE_SIZE);
if (!reg_bo)
goto out_free;
overlay->reg_bo = reg_bo;

mutex_lock(&dev->struct_mutex);

if (OVERLAY_NEEDS_PHYSICAL(dev)) {
ret = i915_gem_attach_phys_object(dev, reg_bo,
I915_GEM_PHYS_OVERLAY_REGS,
Expand All @@ -1442,8 +1445,6 @@ void intel_setup_overlay(struct drm_device *dev)
}
}

mutex_unlock(&dev->struct_mutex);

/* init all values */
overlay->color_key = 0x0101fe;
overlay->brightness = -19;
Expand All @@ -1452,7 +1453,7 @@ void intel_setup_overlay(struct drm_device *dev)

regs = intel_overlay_map_regs(overlay);
if (!regs)
goto out_free_bo;
goto out_unpin_bo;

memset(regs, 0, sizeof(struct overlay_registers));
update_polyphase_filter(regs);
Expand All @@ -1461,15 +1462,17 @@ void intel_setup_overlay(struct drm_device *dev)
intel_overlay_unmap_regs(overlay, regs);

dev_priv->overlay = overlay;
mutex_unlock(&dev->struct_mutex);
DRM_INFO("initialized overlay support\n");
return;

out_unpin_bo:
i915_gem_object_unpin(reg_bo);
if (!OVERLAY_NEEDS_PHYSICAL(dev))
i915_gem_object_unpin(reg_bo);
out_free_bo:
drm_gem_object_unreference(&reg_bo->base);
mutex_unlock(&dev->struct_mutex);
out_free:
mutex_unlock(&dev->struct_mutex);
kfree(overlay);
return;
}
Expand Down

0 comments on commit 79d2427

Please sign in to comment.