|
@@ -46,22 +46,26 @@ static size_t roundup_gem_size(size_t size)
|
|
|
return roundup(size, PAGE_SIZE);
|
|
|
}
|
|
|
|
|
|
-/* dev->struct_mutex is held here */
|
|
|
void armada_gem_free_object(struct drm_gem_object *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_gem_free_mmap_offset(&dobj->obj);
|
|
|
|
|
|
+ might_lock(&priv->linear_lock);
|
|
|
+
|
|
|
if (dobj->page) {
|
|
|
/* page backed memory */
|
|
|
unsigned int order = get_order(dobj->obj.size);
|
|
|
__free_pages(dobj->page, order);
|
|
|
} else if (dobj->linear) {
|
|
|
/* linear backed memory */
|
|
|
+ mutex_lock(&priv->linear_lock);
|
|
|
drm_mm_remove_node(dobj->linear);
|
|
|
+ mutex_unlock(&priv->linear_lock);
|
|
|
kfree(dobj->linear);
|
|
|
if (dobj->addr)
|
|
|
iounmap(dobj->addr);
|
|
@@ -144,10 +148,10 @@ armada_gem_linear_back(struct drm_device *dev, struct armada_gem_object *obj)
|
|
|
if (!node)
|
|
|
return -ENOSPC;
|
|
|
|
|
|
- mutex_lock(&dev->struct_mutex);
|
|
|
+ mutex_lock(&priv->linear_lock);
|
|
|
ret = drm_mm_insert_node(&priv->linear, node, size, align,
|
|
|
DRM_MM_SEARCH_DEFAULT);
|
|
|
- mutex_unlock(&dev->struct_mutex);
|
|
|
+ mutex_unlock(&priv->linear_lock);
|
|
|
if (ret) {
|
|
|
kfree(node);
|
|
|
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. */
|
|
|
ptr = ioremap_wc(obj->linear->start, size);
|
|
|
if (!ptr) {
|
|
|
- mutex_lock(&dev->struct_mutex);
|
|
|
+ mutex_lock(&priv->linear_lock);
|
|
|
drm_mm_remove_node(obj->linear);
|
|
|
- mutex_unlock(&dev->struct_mutex);
|
|
|
+ mutex_unlock(&priv->linear_lock);
|
|
|
kfree(obj->linear);
|
|
|
obj->linear = NULL;
|
|
|
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;
|
|
|
int ret = 0;
|
|
|
|
|
|
- mutex_lock(&dev->struct_mutex);
|
|
|
obj = armada_gem_object_lookup(dev, file, handle);
|
|
|
if (!obj) {
|
|
|
DRM_ERROR("failed to lookup gem object\n");
|
|
|
- ret = -EINVAL;
|
|
|
- goto err_unlock;
|
|
|
+ return -EINVAL;
|
|
|
}
|
|
|
|
|
|
/* Don't allow imported objects to be mapped */
|
|
|
if (obj->obj.import_attach) {
|
|
|
ret = -EINVAL;
|
|
|
- goto err_unlock;
|
|
|
+ goto err_unref;
|
|
|
}
|
|
|
|
|
|
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_gem_object_unreference(&obj->obj);
|
|
|
- err_unlock:
|
|
|
- mutex_unlock(&dev->struct_mutex);
|
|
|
+ err_unref:
|
|
|
+ drm_gem_object_unreference_unlocked(&obj->obj);
|
|
|
|
|
|
return ret;
|
|
|
}
|
|
@@ -352,13 +353,13 @@ int armada_gem_mmap_ioctl(struct drm_device *dev, void *data,
|
|
|
return -ENOENT;
|
|
|
|
|
|
if (!dobj->obj.filp) {
|
|
|
- drm_gem_object_unreference(&dobj->obj);
|
|
|
+ drm_gem_object_unreference_unlocked(&dobj->obj);
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
|
|
|
addr = vm_mmap(dobj->obj.filp, 0, args->size, PROT_READ | PROT_WRITE,
|
|
|
MAP_SHARED, args->offset);
|
|
|
- drm_gem_object_unreference(&dobj->obj);
|
|
|
+ drm_gem_object_unreference_unlocked(&dobj->obj);
|
|
|
if (IS_ERR_VALUE(addr))
|
|
|
return addr;
|
|
|
|