forked from Minki/linux
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
This commit is contained in:
commit
f884a507e6
@ -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,
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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 {
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
/* 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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user