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

drm: Move legacy device list out of drm_driver

The drm_driver structure contains a single field (legacy_dev_list) that
is modified by the DRM core, used to store a linked list of legacy DRM
devices associated with the driver. In order to make the structure
const, move the field out to a global variable. This requires locking
access to the global where the local field didn't require serialization,
but this only affects legacy drivers, and isn't in any hot path.

While at it, compile-out the legacy_dev_list field when DRM_LEGACY isn't
defined.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Reviewed-by: Emil Velikov <emil.velikov@collabora.com>

+20 -17
+17 -8
drivers/gpu/drm/drm_pci.c
··· 24 24 25 25 #include <linux/dma-mapping.h> 26 26 #include <linux/export.h> 27 + #include <linux/list.h> 28 + #include <linux/mutex.h> 27 29 #include <linux/pci.h> 28 30 #include <linux/slab.h> 29 31 ··· 38 36 #include "drm_legacy.h" 39 37 40 38 #ifdef CONFIG_DRM_LEGACY 39 + /* List of devices hanging off drivers with stealth attach. */ 40 + static LIST_HEAD(legacy_dev_list); 41 + static DEFINE_MUTEX(legacy_dev_list_lock); 41 42 42 43 /** 43 44 * drm_pci_alloc - Allocate a PCI consistent memory block, for DMA. ··· 230 225 if (ret) 231 226 goto err_agp; 232 227 233 - /* No locking needed since shadow-attach is single-threaded since it may 234 - * only be called from the per-driver module init hook. */ 235 - if (drm_core_check_feature(dev, DRIVER_LEGACY)) 236 - list_add_tail(&dev->legacy_dev_list, &driver->legacy_dev_list); 228 + if (drm_core_check_feature(dev, DRIVER_LEGACY)) { 229 + mutex_lock(&legacy_dev_list_lock); 230 + list_add_tail(&dev->legacy_dev_list, &legacy_dev_list); 231 + mutex_unlock(&legacy_dev_list_lock); 232 + } 237 233 238 234 return 0; 239 235 ··· 267 261 return -EINVAL; 268 262 269 263 /* If not using KMS, fall back to stealth mode manual scanning. */ 270 - INIT_LIST_HEAD(&driver->legacy_dev_list); 271 264 for (i = 0; pdriver->id_table[i].vendor != 0; i++) { 272 265 pid = &pdriver->id_table[i]; 273 266 ··· 309 304 if (!(driver->driver_features & DRIVER_LEGACY)) { 310 305 WARN_ON(1); 311 306 } else { 312 - list_for_each_entry_safe(dev, tmp, &driver->legacy_dev_list, 307 + mutex_lock(&legacy_dev_list_lock); 308 + list_for_each_entry_safe(dev, tmp, &legacy_dev_list, 313 309 legacy_dev_list) { 314 - list_del(&dev->legacy_dev_list); 315 - drm_put_dev(dev); 310 + if (dev->driver == driver) { 311 + list_del(&dev->legacy_dev_list); 312 + drm_put_dev(dev); 313 + } 316 314 } 315 + mutex_unlock(&legacy_dev_list_lock); 317 316 } 318 317 DRM_INFO("Module unloaded\n"); 319 318 }
+3 -7
include/drm/drm_device.h
··· 51 51 * may contain multiple heads. 52 52 */ 53 53 struct drm_device { 54 - /** 55 - * @legacy_dev_list: 56 - * 57 - * List of devices per driver for stealth attach cleanup 58 - */ 59 - struct list_head legacy_dev_list; 60 - 61 54 /** @if_version: Highest interface version set */ 62 55 int if_version; 63 56 ··· 329 336 /* Everything below here is for legacy driver, never use! */ 330 337 /* private: */ 331 338 #if IS_ENABLED(CONFIG_DRM_LEGACY) 339 + /* List of devices per driver for stealth attach cleanup */ 340 + struct list_head legacy_dev_list; 341 + 332 342 /* Context handle management - linked list of context handles */ 333 343 struct list_head ctxlist; 334 344
-2
include/drm/drm_drv.h
··· 499 499 /* Everything below here is for legacy driver, never use! */ 500 500 /* private: */ 501 501 502 - /* List of devices hanging off this driver with stealth attach. */ 503 - struct list_head legacy_dev_list; 504 502 int (*firstopen) (struct drm_device *); 505 503 void (*preclose) (struct drm_device *, struct drm_file *file_priv); 506 504 int (*dma_ioctl) (struct drm_device *dev, void *data, struct drm_file *file_priv);