Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Daniel Vetter and committed by
Russell King
0b8ebeac 4bd3fd44

+14 -8
+2 -2
drivers/gpu/drm/armada/armada_debugfs.c
··· 21 21 struct armada_private *priv = dev->dev_private; 22 22 int ret; 23 23 24 - mutex_lock(&dev->struct_mutex); 24 + mutex_lock(&priv->linear_lock); 25 25 ret = drm_mm_dump_table(m, &priv->linear); 26 - mutex_unlock(&dev->struct_mutex); 26 + mutex_unlock(&priv->linear_lock); 27 27 28 28 return ret; 29 29 }
+2 -1
drivers/gpu/drm/armada/armada_drm.h
··· 57 57 DECLARE_KFIFO(fb_unref, struct drm_framebuffer *, 8); 58 58 struct drm_fb_helper *fbdev; 59 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 62 struct drm_property *csc_yuv_prop; 62 63 struct drm_property *csc_rgb_prop; 63 64 struct drm_property *colorkey_prop;
+1
drivers/gpu/drm/armada/armada_drv.c
··· 101 101 dev->mode_config.preferred_depth = 24; 102 102 dev->mode_config.funcs = &armada_drm_mode_config_funcs; 103 103 drm_mm_init(&priv->linear, mem->start, resource_size(mem)); 104 + mutex_init(&priv->linear_lock); 104 105 105 106 ret = component_bind_all(dev->dev, dev); 106 107 if (ret)
+9 -5
drivers/gpu/drm/armada/armada_gem.c
··· 46 46 return roundup(size, PAGE_SIZE); 47 47 } 48 48 49 - /* dev->struct_mutex is held here */ 50 49 void armada_gem_free_object(struct drm_gem_object *obj) 51 50 { 52 51 struct armada_gem_object *dobj = drm_to_armada_gem(obj); 52 + struct armada_private *priv = obj->dev->dev_private; 53 53 54 54 DRM_DEBUG_DRIVER("release obj %p\n", dobj); 55 55 56 56 drm_gem_free_mmap_offset(&dobj->obj); 57 + 58 + might_lock(&priv->linear_lock); 57 59 58 60 if (dobj->page) { 59 61 /* page backed memory */ ··· 63 61 __free_pages(dobj->page, order); 64 62 } else if (dobj->linear) { 65 63 /* linear backed memory */ 64 + mutex_lock(&priv->linear_lock); 66 65 drm_mm_remove_node(dobj->linear); 66 + mutex_unlock(&priv->linear_lock); 67 67 kfree(dobj->linear); 68 68 if (dobj->addr) 69 69 iounmap(dobj->addr); ··· 148 144 if (!node) 149 145 return -ENOSPC; 150 146 151 - mutex_lock(&dev->struct_mutex); 147 + mutex_lock(&priv->linear_lock); 152 148 ret = drm_mm_insert_node(&priv->linear, node, size, align, 153 149 DRM_MM_SEARCH_DEFAULT); 154 - mutex_unlock(&dev->struct_mutex); 150 + mutex_unlock(&priv->linear_lock); 155 151 if (ret) { 156 152 kfree(node); 157 153 return ret; ··· 162 158 /* Ensure that the memory we're returning is cleared. */ 163 159 ptr = ioremap_wc(obj->linear->start, size); 164 160 if (!ptr) { 165 - mutex_lock(&dev->struct_mutex); 161 + mutex_lock(&priv->linear_lock); 166 162 drm_mm_remove_node(obj->linear); 167 - mutex_unlock(&dev->struct_mutex); 163 + mutex_unlock(&priv->linear_lock); 168 164 kfree(obj->linear); 169 165 obj->linear = NULL; 170 166 return -ENOMEM;