diff options
author | Noralf Trønnes <noralf@tronnes.org> | 2018-03-28 10:38:35 +0300 |
---|---|---|
committer | Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com> | 2018-03-29 13:19:20 +0300 |
commit | bee330f3d67273a68dcb99f59480d59553c008b2 (patch) | |
tree | abe48e9b35c199bf691b02efc40a5291f2391b40 /include/drm | |
parent | 790861cc34f872015806cef311d5c64cc3167a0d (diff) | |
download | linux-stable-bee330f3d67273a68dcb99f59480d59553c008b2.tar.gz linux-stable-bee330f3d67273a68dcb99f59480d59553c008b2.tar.bz2 linux-stable-bee330f3d67273a68dcb99f59480d59553c008b2.zip |
drm: Use srcu to protect drm_device.unplugged
Use srcu to protect drm_device.unplugged in a race free manner.
Drivers can use drm_dev_enter()/drm_dev_exit() to protect and mark
sections preventing access to device resources that are not available
after the device is gone.
Suggested-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Noralf Trønnes <noralf@tronnes.org>
Signed-off-by: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
Reviewed-by: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
Tested-by: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
Cc: intel-gfx@lists.freedesktop.org
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: https://patchwork.freedesktop.org/patch/msgid/1522222715-11814-1-git-send-email-andr2000@gmail.com
Diffstat (limited to 'include/drm')
-rw-r--r-- | include/drm/drm_device.h | 9 | ||||
-rw-r--r-- | include/drm/drm_drv.h | 15 |
2 files changed, 19 insertions, 5 deletions
diff --git a/include/drm/drm_device.h b/include/drm/drm_device.h index 7c4fa32f3fc6..3a0eac2885b7 100644 --- a/include/drm/drm_device.h +++ b/include/drm/drm_device.h @@ -46,7 +46,14 @@ struct drm_device { /* currently active master for this device. Protected by master_mutex */ struct drm_master *master; - atomic_t unplugged; /**< Flag whether dev is dead */ + /** + * @unplugged: + * + * Flag to tell if the device has been unplugged. + * See drm_dev_enter() and drm_dev_is_unplugged(). + */ + bool unplugged; + struct inode *anon_inode; /**< inode for private address-space */ char *unique; /**< unique name of the device */ /*@} */ diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h index d32b688eb346..ff7312c40cd8 100644 --- a/include/drm/drm_drv.h +++ b/include/drm/drm_drv.h @@ -623,6 +623,8 @@ void drm_dev_get(struct drm_device *dev); void drm_dev_put(struct drm_device *dev); void drm_dev_unref(struct drm_device *dev); void drm_put_dev(struct drm_device *dev); +bool drm_dev_enter(struct drm_device *dev, int *idx); +void drm_dev_exit(int idx); void drm_dev_unplug(struct drm_device *dev); /** @@ -634,11 +636,16 @@ void drm_dev_unplug(struct drm_device *dev); * unplugged, these two functions guarantee that any store before calling * drm_dev_unplug() is visible to callers of this function after it completes */ -static inline int drm_dev_is_unplugged(struct drm_device *dev) +static inline bool drm_dev_is_unplugged(struct drm_device *dev) { - int ret = atomic_read(&dev->unplugged); - smp_rmb(); - return ret; + int idx; + + if (drm_dev_enter(dev, &idx)) { + drm_dev_exit(idx); + return false; + } + + return true; } |