diff options
author | Dave Airlie <airlied@redhat.com> | 2015-12-22 18:19:58 -0500 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2015-12-22 18:19:58 -0500 |
commit | f884a507e631a1d8b270c8bfd95dbde813a0f447 (patch) | |
tree | 5c96624dfd93b4b64d153c9b75cc0dd8decdba10 | |
parent | 0239c75978a9b9bdadfe07cdc60d40bdedb93a07 (diff) | |
parent | 0b8ebeacf5ef43a467c7ec5400ccc1ffc3fbdfba (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.c | 9 | ||||
-rw-r--r-- | drivers/gpu/drm/armada/armada_debugfs.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/armada/armada_drm.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/armada/armada_drv.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/armada/armada_gem.c | 29 |
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 | ||
950 | static int armada_drm_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) | 948 | static 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 */ | ||
50 | void armada_gem_free_object(struct drm_gem_object *obj) | 49 | void 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 | ||