diff options
author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2015-11-24 04:00:36 -0500 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2015-12-05 16:44:07 -0500 |
commit | 0b8ebeacf5ef43a467c7ec5400ccc1ffc3fbdfba (patch) | |
tree | ae367b9b8dfa91535a38ec8a62d20184b804d58d /drivers/gpu/drm | |
parent | 4bd3fd443aa4bc3cede05de201e9cf3277059477 (diff) |
drm/armada: use a private mutex to protect priv->linear
Reusing the Big DRM Lock just leaks, and the few things left that
dev->struct_mutex protected are very well contained - it's just the
linear drm_mm manager.
With this armada is completely struct_mutex free!
v2: Convert things properly and also take the lock in
armada_gem_free_object, and remove the stale comment (Russell).
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'drivers/gpu/drm')
-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 | 14 |
4 files changed, 14 insertions, 8 deletions
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 3f1396e673dd..f7f47cb71db4 100644 --- a/drivers/gpu/drm/armada/armada_drv.c +++ b/drivers/gpu/drm/armada/armada_drv.c | |||
@@ -101,6 +101,7 @@ static int armada_drm_load(struct drm_device *dev, unsigned long flags) | |||
101 | dev->mode_config.preferred_depth = 24; | 101 | dev->mode_config.preferred_depth = 24; |
102 | dev->mode_config.funcs = &armada_drm_mode_config_funcs; | 102 | dev->mode_config.funcs = &armada_drm_mode_config_funcs; |
103 | drm_mm_init(&priv->linear, mem->start, resource_size(mem)); | 103 | drm_mm_init(&priv->linear, mem->start, resource_size(mem)); |
104 | mutex_init(&priv->linear_lock); | ||
104 | 105 | ||
105 | ret = component_bind_all(dev->dev, dev); | 106 | ret = component_bind_all(dev->dev, dev); |
106 | if (ret) | 107 | if (ret) |
diff --git a/drivers/gpu/drm/armada/armada_gem.c b/drivers/gpu/drm/armada/armada_gem.c index e3a86b96af2a..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; |