aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2015-12-22 18:19:58 -0500
committerDave Airlie <airlied@redhat.com>2015-12-22 18:19:58 -0500
commitf884a507e631a1d8b270c8bfd95dbde813a0f447 (patch)
tree5c96624dfd93b4b64d153c9b75cc0dd8decdba10
parent0239c75978a9b9bdadfe07cdc60d40bdedb93a07 (diff)
parent0b8ebeacf5ef43a467c7ec5400ccc1ffc3fbdfba (diff)
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
-rw-r--r--drivers/gpu/drm/armada/armada_crtc.c9
-rw-r--r--drivers/gpu/drm/armada/armada_debugfs.c4
-rw-r--r--drivers/gpu/drm/armada/armada_drm.h3
-rw-r--r--drivers/gpu/drm/armada/armada_drv.c1
-rw-r--r--drivers/gpu/drm/armada/armada_gem.c29
5 files changed, 22 insertions, 24 deletions
diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c
index 4123680933a6..0293eb74d777 100644
--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ b/drivers/gpu/drm/armada/armada_crtc.c
@@ -928,11 +928,10 @@ static int armada_drm_crtc_cursor_set(struct drm_crtc *crtc,
928 } 928 }
929 } 929 }
930 930
931 mutex_lock(&dev->struct_mutex);
932 if (dcrtc->cursor_obj) { 931 if (dcrtc->cursor_obj) {
933 dcrtc->cursor_obj->update = NULL; 932 dcrtc->cursor_obj->update = NULL;
934 dcrtc->cursor_obj->update_data = NULL; 933 dcrtc->cursor_obj->update_data = NULL;
935 drm_gem_object_unreference(&dcrtc->cursor_obj->obj); 934 drm_gem_object_unreference_unlocked(&dcrtc->cursor_obj->obj);
936 } 935 }
937 dcrtc->cursor_obj = obj; 936 dcrtc->cursor_obj = obj;
938 dcrtc->cursor_w = w; 937 dcrtc->cursor_w = w;
@@ -942,14 +941,12 @@ static int armada_drm_crtc_cursor_set(struct drm_crtc *crtc,
942 obj->update_data = dcrtc; 941 obj->update_data = dcrtc;
943 obj->update = cursor_update; 942 obj->update = cursor_update;
944 } 943 }
945 mutex_unlock(&dev->struct_mutex);
946 944
947 return ret; 945 return ret;
948} 946}
949 947
950static int armada_drm_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) 948static int armada_drm_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
951{ 949{
952 struct drm_device *dev = crtc->dev;
953 struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc); 950 struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
954 int ret; 951 int ret;
955 952
@@ -957,11 +954,9 @@ static int armada_drm_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
957 if (!dcrtc->variant->has_spu_adv_reg) 954 if (!dcrtc->variant->has_spu_adv_reg)
958 return -EFAULT; 955 return -EFAULT;
959 956
960 mutex_lock(&dev->struct_mutex);
961 dcrtc->cursor_x = x; 957 dcrtc->cursor_x = x;
962 dcrtc->cursor_y = y; 958 dcrtc->cursor_y = y;
963 ret = armada_drm_crtc_cursor_update(dcrtc, false); 959 ret = armada_drm_crtc_cursor_update(dcrtc, false);
964 mutex_unlock(&dev->struct_mutex);
965 960
966 return ret; 961 return ret;
967} 962}
@@ -972,7 +967,7 @@ static void armada_drm_crtc_destroy(struct drm_crtc *crtc)
972 struct armada_private *priv = crtc->dev->dev_private; 967 struct armada_private *priv = crtc->dev->dev_private;
973 968
974 if (dcrtc->cursor_obj) 969 if (dcrtc->cursor_obj)
975 drm_gem_object_unreference(&dcrtc->cursor_obj->obj); 970 drm_gem_object_unreference_unlocked(&dcrtc->cursor_obj->obj);
976 971
977 priv->dcrtc[dcrtc->num] = NULL; 972 priv->dcrtc[dcrtc->num] = NULL;
978 drm_crtc_cleanup(&dcrtc->crtc); 973 drm_crtc_cleanup(&dcrtc->crtc);
diff --git a/drivers/gpu/drm/armada/armada_debugfs.c b/drivers/gpu/drm/armada/armada_debugfs.c
index 471e45627f1e..d4f7ab0a30d4 100644
--- a/drivers/gpu/drm/armada/armada_debugfs.c
+++ b/drivers/gpu/drm/armada/armada_debugfs.c
@@ -21,9 +21,9 @@ static int armada_debugfs_gem_linear_show(struct seq_file *m, void *data)
21 struct armada_private *priv = dev->dev_private; 21 struct armada_private *priv = dev->dev_private;
22 int ret; 22 int ret;
23 23
24 mutex_lock(&dev->struct_mutex); 24 mutex_lock(&priv->linear_lock);
25 ret = drm_mm_dump_table(m, &priv->linear); 25 ret = drm_mm_dump_table(m, &priv->linear);
26 mutex_unlock(&dev->struct_mutex); 26 mutex_unlock(&priv->linear_lock);
27 27
28 return ret; 28 return ret;
29} 29}
diff --git a/drivers/gpu/drm/armada/armada_drm.h b/drivers/gpu/drm/armada/armada_drm.h
index 4df6f2af2b21..3b2bb6128d40 100644
--- a/drivers/gpu/drm/armada/armada_drm.h
+++ b/drivers/gpu/drm/armada/armada_drm.h
@@ -57,7 +57,8 @@ struct armada_private {
57 DECLARE_KFIFO(fb_unref, struct drm_framebuffer *, 8); 57 DECLARE_KFIFO(fb_unref, struct drm_framebuffer *, 8);
58 struct drm_fb_helper *fbdev; 58 struct drm_fb_helper *fbdev;
59 struct armada_crtc *dcrtc[2]; 59 struct armada_crtc *dcrtc[2];
60 struct drm_mm linear; 60 struct drm_mm linear; /* protected by linear_lock */
61 struct mutex linear_lock;
61 struct drm_property *csc_yuv_prop; 62 struct drm_property *csc_yuv_prop;
62 struct drm_property *csc_rgb_prop; 63 struct drm_property *csc_rgb_prop;
63 struct drm_property *colorkey_prop; 64 struct drm_property *colorkey_prop;
diff --git a/drivers/gpu/drm/armada/armada_drv.c b/drivers/gpu/drm/armada/armada_drv.c
index 77ab93d60125..3bd7e1cde99e 100644
--- a/drivers/gpu/drm/armada/armada_drv.c
+++ b/drivers/gpu/drm/armada/armada_drv.c
@@ -102,6 +102,7 @@ static int armada_drm_load(struct drm_device *dev, unsigned long flags)
102 dev->mode_config.preferred_depth = 24; 102 dev->mode_config.preferred_depth = 24;
103 dev->mode_config.funcs = &armada_drm_mode_config_funcs; 103 dev->mode_config.funcs = &armada_drm_mode_config_funcs;
104 drm_mm_init(&priv->linear, mem->start, resource_size(mem)); 104 drm_mm_init(&priv->linear, mem->start, resource_size(mem));
105 mutex_init(&priv->linear_lock);
105 106
106 ret = component_bind_all(dev->dev, dev); 107 ret = component_bind_all(dev->dev, dev);
107 if (ret) 108 if (ret)
diff --git a/drivers/gpu/drm/armada/armada_gem.c b/drivers/gpu/drm/armada/armada_gem.c
index 60a688ef81c7..6e731db31aa4 100644
--- a/drivers/gpu/drm/armada/armada_gem.c
+++ b/drivers/gpu/drm/armada/armada_gem.c
@@ -46,22 +46,26 @@ static size_t roundup_gem_size(size_t size)
46 return roundup(size, PAGE_SIZE); 46 return roundup(size, PAGE_SIZE);
47} 47}
48 48
49/* dev->struct_mutex is held here */
50void armada_gem_free_object(struct drm_gem_object *obj) 49void armada_gem_free_object(struct drm_gem_object *obj)
51{ 50{
52 struct armada_gem_object *dobj = drm_to_armada_gem(obj); 51 struct armada_gem_object *dobj = drm_to_armada_gem(obj);
52 struct armada_private *priv = obj->dev->dev_private;
53 53
54 DRM_DEBUG_DRIVER("release obj %p\n", dobj); 54 DRM_DEBUG_DRIVER("release obj %p\n", dobj);
55 55
56 drm_gem_free_mmap_offset(&dobj->obj); 56 drm_gem_free_mmap_offset(&dobj->obj);
57 57
58 might_lock(&priv->linear_lock);
59
58 if (dobj->page) { 60 if (dobj->page) {
59 /* page backed memory */ 61 /* page backed memory */
60 unsigned int order = get_order(dobj->obj.size); 62 unsigned int order = get_order(dobj->obj.size);
61 __free_pages(dobj->page, order); 63 __free_pages(dobj->page, order);
62 } else if (dobj->linear) { 64 } else if (dobj->linear) {
63 /* linear backed memory */ 65 /* linear backed memory */
66 mutex_lock(&priv->linear_lock);
64 drm_mm_remove_node(dobj->linear); 67 drm_mm_remove_node(dobj->linear);
68 mutex_unlock(&priv->linear_lock);
65 kfree(dobj->linear); 69 kfree(dobj->linear);
66 if (dobj->addr) 70 if (dobj->addr)
67 iounmap(dobj->addr); 71 iounmap(dobj->addr);
@@ -144,10 +148,10 @@ armada_gem_linear_back(struct drm_device *dev, struct armada_gem_object *obj)
144 if (!node) 148 if (!node)
145 return -ENOSPC; 149 return -ENOSPC;
146 150
147 mutex_lock(&dev->struct_mutex); 151 mutex_lock(&priv->linear_lock);
148 ret = drm_mm_insert_node(&priv->linear, node, size, align, 152 ret = drm_mm_insert_node(&priv->linear, node, size, align,
149 DRM_MM_SEARCH_DEFAULT); 153 DRM_MM_SEARCH_DEFAULT);
150 mutex_unlock(&dev->struct_mutex); 154 mutex_unlock(&priv->linear_lock);
151 if (ret) { 155 if (ret) {
152 kfree(node); 156 kfree(node);
153 return ret; 157 return ret;
@@ -158,9 +162,9 @@ armada_gem_linear_back(struct drm_device *dev, struct armada_gem_object *obj)
158 /* Ensure that the memory we're returning is cleared. */ 162 /* Ensure that the memory we're returning is cleared. */
159 ptr = ioremap_wc(obj->linear->start, size); 163 ptr = ioremap_wc(obj->linear->start, size);
160 if (!ptr) { 164 if (!ptr) {
161 mutex_lock(&dev->struct_mutex); 165 mutex_lock(&priv->linear_lock);
162 drm_mm_remove_node(obj->linear); 166 drm_mm_remove_node(obj->linear);
163 mutex_unlock(&dev->struct_mutex); 167 mutex_unlock(&priv->linear_lock);
164 kfree(obj->linear); 168 kfree(obj->linear);
165 obj->linear = NULL; 169 obj->linear = NULL;
166 return -ENOMEM; 170 return -ENOMEM;
@@ -274,18 +278,16 @@ int armada_gem_dumb_map_offset(struct drm_file *file, struct drm_device *dev,
274 struct armada_gem_object *obj; 278 struct armada_gem_object *obj;
275 int ret = 0; 279 int ret = 0;
276 280
277 mutex_lock(&dev->struct_mutex);
278 obj = armada_gem_object_lookup(dev, file, handle); 281 obj = armada_gem_object_lookup(dev, file, handle);
279 if (!obj) { 282 if (!obj) {
280 DRM_ERROR("failed to lookup gem object\n"); 283 DRM_ERROR("failed to lookup gem object\n");
281 ret = -EINVAL; 284 return -EINVAL;
282 goto err_unlock;
283 } 285 }
284 286
285 /* Don't allow imported objects to be mapped */ 287 /* Don't allow imported objects to be mapped */
286 if (obj->obj.import_attach) { 288 if (obj->obj.import_attach) {
287 ret = -EINVAL; 289 ret = -EINVAL;
288 goto err_unlock; 290 goto err_unref;
289 } 291 }
290 292
291 ret = drm_gem_create_mmap_offset(&obj->obj); 293 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 DRM_DEBUG_DRIVER("handle %#x offset %llx\n", handle, *offset); 296 DRM_DEBUG_DRIVER("handle %#x offset %llx\n", handle, *offset);
295 } 297 }
296 298
297 drm_gem_object_unreference(&obj->obj); 299 err_unref:
298 err_unlock: 300 drm_gem_object_unreference_unlocked(&obj->obj);
299 mutex_unlock(&dev->struct_mutex);
300 301
301 return ret; 302 return ret;
302} 303}
@@ -352,13 +353,13 @@ int armada_gem_mmap_ioctl(struct drm_device *dev, void *data,
352 return -ENOENT; 353 return -ENOENT;
353 354
354 if (!dobj->obj.filp) { 355 if (!dobj->obj.filp) {
355 drm_gem_object_unreference(&dobj->obj); 356 drm_gem_object_unreference_unlocked(&dobj->obj);
356 return -EINVAL; 357 return -EINVAL;
357 } 358 }
358 359
359 addr = vm_mmap(dobj->obj.filp, 0, args->size, PROT_READ | PROT_WRITE, 360 addr = vm_mmap(dobj->obj.filp, 0, args->size, PROT_READ | PROT_WRITE,
360 MAP_SHARED, args->offset); 361 MAP_SHARED, args->offset);
361 drm_gem_object_unreference(&dobj->obj); 362 drm_gem_object_unreference_unlocked(&dobj->obj);
362 if (IS_ERR_VALUE(addr)) 363 if (IS_ERR_VALUE(addr))
363 return addr; 364 return addr;
364 365