Commit f884a507 authored by Dave Airlie's avatar Dave Airlie

Merge branch 'drm-armada-devel' of git://ftp.arm.linux.org.uk/~rmk/linux-arm into drm-next

These are the patches from Daniel Vetter, getting rid of struct_mutex
from the Armada DRM driver.

* 'drm-armada-devel' of git://ftp.arm.linux.org.uk/~rmk/linux-arm:
  drm/armada: use a private mutex to protect priv->linear
  drm/armada: drop struct_mutex from cursor paths
  drm/armada: don't grab dev->struct_mutex for in mmap offset ioctl
  drm/armada: plug leak in dumb_map_offset
  drm/armada: use unlocked gem unreferencing
parents 0239c759 0b8ebeac
...@@ -928,11 +928,10 @@ static int armada_drm_crtc_cursor_set(struct drm_crtc *crtc, ...@@ -928,11 +928,10 @@ static int armada_drm_crtc_cursor_set(struct drm_crtc *crtc,
} }
} }
mutex_lock(&dev->struct_mutex);
if (dcrtc->cursor_obj) { if (dcrtc->cursor_obj) {
dcrtc->cursor_obj->update = NULL; dcrtc->cursor_obj->update = NULL;
dcrtc->cursor_obj->update_data = NULL; dcrtc->cursor_obj->update_data = NULL;
drm_gem_object_unreference(&dcrtc->cursor_obj->obj); drm_gem_object_unreference_unlocked(&dcrtc->cursor_obj->obj);
} }
dcrtc->cursor_obj = obj; dcrtc->cursor_obj = obj;
dcrtc->cursor_w = w; dcrtc->cursor_w = w;
...@@ -942,14 +941,12 @@ static int armada_drm_crtc_cursor_set(struct drm_crtc *crtc, ...@@ -942,14 +941,12 @@ static int armada_drm_crtc_cursor_set(struct drm_crtc *crtc,
obj->update_data = dcrtc; obj->update_data = dcrtc;
obj->update = cursor_update; obj->update = cursor_update;
} }
mutex_unlock(&dev->struct_mutex);
return ret; return ret;
} }
static int armada_drm_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) static int armada_drm_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
{ {
struct drm_device *dev = crtc->dev;
struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc); struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
int ret; int ret;
...@@ -957,11 +954,9 @@ static int armada_drm_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) ...@@ -957,11 +954,9 @@ static int armada_drm_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
if (!dcrtc->variant->has_spu_adv_reg) if (!dcrtc->variant->has_spu_adv_reg)
return -EFAULT; return -EFAULT;
mutex_lock(&dev->struct_mutex);
dcrtc->cursor_x = x; dcrtc->cursor_x = x;
dcrtc->cursor_y = y; dcrtc->cursor_y = y;
ret = armada_drm_crtc_cursor_update(dcrtc, false); ret = armada_drm_crtc_cursor_update(dcrtc, false);
mutex_unlock(&dev->struct_mutex);
return ret; return ret;
} }
...@@ -972,7 +967,7 @@ static void armada_drm_crtc_destroy(struct drm_crtc *crtc) ...@@ -972,7 +967,7 @@ static void armada_drm_crtc_destroy(struct drm_crtc *crtc)
struct armada_private *priv = crtc->dev->dev_private; struct armada_private *priv = crtc->dev->dev_private;
if (dcrtc->cursor_obj) if (dcrtc->cursor_obj)
drm_gem_object_unreference(&dcrtc->cursor_obj->obj); drm_gem_object_unreference_unlocked(&dcrtc->cursor_obj->obj);
priv->dcrtc[dcrtc->num] = NULL; priv->dcrtc[dcrtc->num] = NULL;
drm_crtc_cleanup(&dcrtc->crtc); drm_crtc_cleanup(&dcrtc->crtc);
......
...@@ -21,9 +21,9 @@ static int armada_debugfs_gem_linear_show(struct seq_file *m, void *data) ...@@ -21,9 +21,9 @@ static int armada_debugfs_gem_linear_show(struct seq_file *m, void *data)
struct armada_private *priv = dev->dev_private; struct armada_private *priv = dev->dev_private;
int ret; int ret;
mutex_lock(&dev->struct_mutex); mutex_lock(&priv->linear_lock);
ret = drm_mm_dump_table(m, &priv->linear); ret = drm_mm_dump_table(m, &priv->linear);
mutex_unlock(&dev->struct_mutex); mutex_unlock(&priv->linear_lock);
return ret; return ret;
} }
......
...@@ -57,7 +57,8 @@ struct armada_private { ...@@ -57,7 +57,8 @@ struct armada_private {
DECLARE_KFIFO(fb_unref, struct drm_framebuffer *, 8); DECLARE_KFIFO(fb_unref, struct drm_framebuffer *, 8);
struct drm_fb_helper *fbdev; struct drm_fb_helper *fbdev;
struct armada_crtc *dcrtc[2]; struct armada_crtc *dcrtc[2];
struct drm_mm linear; struct drm_mm linear; /* protected by linear_lock */
struct mutex linear_lock;
struct drm_property *csc_yuv_prop; struct drm_property *csc_yuv_prop;
struct drm_property *csc_rgb_prop; struct drm_property *csc_rgb_prop;
struct drm_property *colorkey_prop; struct drm_property *colorkey_prop;
......
...@@ -102,6 +102,7 @@ static int armada_drm_load(struct drm_device *dev, unsigned long flags) ...@@ -102,6 +102,7 @@ static int armada_drm_load(struct drm_device *dev, unsigned long flags)
dev->mode_config.preferred_depth = 24; dev->mode_config.preferred_depth = 24;
dev->mode_config.funcs = &armada_drm_mode_config_funcs; dev->mode_config.funcs = &armada_drm_mode_config_funcs;
drm_mm_init(&priv->linear, mem->start, resource_size(mem)); drm_mm_init(&priv->linear, mem->start, resource_size(mem));
mutex_init(&priv->linear_lock);
ret = component_bind_all(dev->dev, dev); ret = component_bind_all(dev->dev, dev);
if (ret) if (ret)
......
...@@ -46,22 +46,26 @@ static size_t roundup_gem_size(size_t size) ...@@ -46,22 +46,26 @@ static size_t roundup_gem_size(size_t size)
return roundup(size, PAGE_SIZE); return roundup(size, PAGE_SIZE);
} }
/* dev->struct_mutex is held here */
void armada_gem_free_object(struct drm_gem_object *obj) void armada_gem_free_object(struct drm_gem_object *obj)
{ {
struct armada_gem_object *dobj = drm_to_armada_gem(obj); struct armada_gem_object *dobj = drm_to_armada_gem(obj);
struct armada_private *priv = obj->dev->dev_private;
DRM_DEBUG_DRIVER("release obj %p\n", dobj); DRM_DEBUG_DRIVER("release obj %p\n", dobj);
drm_gem_free_mmap_offset(&dobj->obj); drm_gem_free_mmap_offset(&dobj->obj);
might_lock(&priv->linear_lock);
if (dobj->page) { if (dobj->page) {
/* page backed memory */ /* page backed memory */
unsigned int order = get_order(dobj->obj.size); unsigned int order = get_order(dobj->obj.size);
__free_pages(dobj->page, order); __free_pages(dobj->page, order);
} else if (dobj->linear) { } else if (dobj->linear) {
/* linear backed memory */ /* linear backed memory */
mutex_lock(&priv->linear_lock);
drm_mm_remove_node(dobj->linear); drm_mm_remove_node(dobj->linear);
mutex_unlock(&priv->linear_lock);
kfree(dobj->linear); kfree(dobj->linear);
if (dobj->addr) if (dobj->addr)
iounmap(dobj->addr); iounmap(dobj->addr);
...@@ -144,10 +148,10 @@ armada_gem_linear_back(struct drm_device *dev, struct armada_gem_object *obj) ...@@ -144,10 +148,10 @@ armada_gem_linear_back(struct drm_device *dev, struct armada_gem_object *obj)
if (!node) if (!node)
return -ENOSPC; return -ENOSPC;
mutex_lock(&dev->struct_mutex); mutex_lock(&priv->linear_lock);
ret = drm_mm_insert_node(&priv->linear, node, size, align, ret = drm_mm_insert_node(&priv->linear, node, size, align,
DRM_MM_SEARCH_DEFAULT); DRM_MM_SEARCH_DEFAULT);
mutex_unlock(&dev->struct_mutex); mutex_unlock(&priv->linear_lock);
if (ret) { if (ret) {
kfree(node); kfree(node);
return ret; return ret;
...@@ -158,9 +162,9 @@ armada_gem_linear_back(struct drm_device *dev, struct armada_gem_object *obj) ...@@ -158,9 +162,9 @@ armada_gem_linear_back(struct drm_device *dev, struct armada_gem_object *obj)
/* Ensure that the memory we're returning is cleared. */ /* Ensure that the memory we're returning is cleared. */
ptr = ioremap_wc(obj->linear->start, size); ptr = ioremap_wc(obj->linear->start, size);
if (!ptr) { if (!ptr) {
mutex_lock(&dev->struct_mutex); mutex_lock(&priv->linear_lock);
drm_mm_remove_node(obj->linear); drm_mm_remove_node(obj->linear);
mutex_unlock(&dev->struct_mutex); mutex_unlock(&priv->linear_lock);
kfree(obj->linear); kfree(obj->linear);
obj->linear = NULL; obj->linear = NULL;
return -ENOMEM; return -ENOMEM;
...@@ -274,18 +278,16 @@ int armada_gem_dumb_map_offset(struct drm_file *file, struct drm_device *dev, ...@@ -274,18 +278,16 @@ int armada_gem_dumb_map_offset(struct drm_file *file, struct drm_device *dev,
struct armada_gem_object *obj; struct armada_gem_object *obj;
int ret = 0; int ret = 0;
mutex_lock(&dev->struct_mutex);
obj = armada_gem_object_lookup(dev, file, handle); obj = armada_gem_object_lookup(dev, file, handle);
if (!obj) { if (!obj) {
DRM_ERROR("failed to lookup gem object\n"); DRM_ERROR("failed to lookup gem object\n");
ret = -EINVAL; return -EINVAL;
goto err_unlock;
} }
/* Don't allow imported objects to be mapped */ /* Don't allow imported objects to be mapped */
if (obj->obj.import_attach) { if (obj->obj.import_attach) {
ret = -EINVAL; ret = -EINVAL;
goto err_unlock; goto err_unref;
} }
ret = drm_gem_create_mmap_offset(&obj->obj); ret = drm_gem_create_mmap_offset(&obj->obj);
...@@ -294,9 +296,8 @@ int armada_gem_dumb_map_offset(struct drm_file *file, struct drm_device *dev, ...@@ -294,9 +296,8 @@ int armada_gem_dumb_map_offset(struct drm_file *file, struct drm_device *dev,
DRM_DEBUG_DRIVER("handle %#x offset %llx\n", handle, *offset); DRM_DEBUG_DRIVER("handle %#x offset %llx\n", handle, *offset);
} }
drm_gem_object_unreference(&obj->obj); err_unref:
err_unlock: drm_gem_object_unreference_unlocked(&obj->obj);
mutex_unlock(&dev->struct_mutex);
return ret; return ret;
} }
...@@ -352,13 +353,13 @@ int armada_gem_mmap_ioctl(struct drm_device *dev, void *data, ...@@ -352,13 +353,13 @@ int armada_gem_mmap_ioctl(struct drm_device *dev, void *data,
return -ENOENT; return -ENOENT;
if (!dobj->obj.filp) { if (!dobj->obj.filp) {
drm_gem_object_unreference(&dobj->obj); drm_gem_object_unreference_unlocked(&dobj->obj);
return -EINVAL; return -EINVAL;
} }
addr = vm_mmap(dobj->obj.filp, 0, args->size, PROT_READ | PROT_WRITE, addr = vm_mmap(dobj->obj.filp, 0, args->size, PROT_READ | PROT_WRITE,
MAP_SHARED, args->offset); MAP_SHARED, args->offset);
drm_gem_object_unreference(&dobj->obj); drm_gem_object_unreference_unlocked(&dobj->obj);
if (IS_ERR_VALUE(addr)) if (IS_ERR_VALUE(addr))
return addr; return addr;
......
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