[PATCH v2 1/6] drm/rockchip: Convert psr_list_mutex to spinlock and use it
Yakir Yang
ykk at rock-chips.com
Wed Aug 17 02:29:59 UTC 2016
On 08/17/2016 09:11 AM, Sean Paul wrote:
> This patch converts the psr_list_mutex to a spinlock and locks
> all access to psr_list to avoid races (however unlikely they
> were).
>
> Signed-off-by: Sean Paul <seanpaul at chromium.org>
Reviewed-by: Yakir Yang <ykk at rock-chips.com>
> ---
>
> Changes in v2:
> - Rebased on https://cgit.freedesktop.org/~seanpaul/dogwood/log/?h=for-next
>
> drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 2 +-
> drivers/gpu/drm/rockchip/rockchip_drm_drv.h | 2 +-
> drivers/gpu/drm/rockchip/rockchip_drm_psr.c | 25 ++++++++++++++++++-------
> 3 files changed, 20 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
> index b43fe5d9..76eaf1d 100644
> --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
> @@ -157,7 +157,7 @@ static int rockchip_drm_bind(struct device *dev)
> drm_dev->dev_private = private;
>
> INIT_LIST_HEAD(&private->psr_list);
> - mutex_init(&private->psr_list_mutex);
> + spin_lock_init(&private->psr_list_lock);
>
> drm_mode_config_init(drm_dev);
>
> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
> index 9c34c9e..5c69845 100644
> --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
> @@ -63,7 +63,7 @@ struct rockchip_drm_private {
> struct drm_atomic_state *state;
>
> struct list_head psr_list;
> - struct mutex psr_list_mutex;
> + spinlock_t psr_list_lock;
> };
>
> int rockchip_register_crtc_funcs(struct drm_crtc *crtc,
> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_psr.c b/drivers/gpu/drm/rockchip/rockchip_drm_psr.c
> index a6d3bd25..bd25273 100644
> --- a/drivers/gpu/drm/rockchip/rockchip_drm_psr.c
> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_psr.c
> @@ -45,12 +45,18 @@ static struct psr_drv *find_psr_by_crtc(struct drm_crtc *crtc)
> {
> struct rockchip_drm_private *drm_drv = crtc->dev->dev_private;
> struct psr_drv *psr;
> + unsigned long flags;
>
> - list_for_each_entry(psr, &drm_drv->psr_list, list)
> + spin_lock_irqsave(&drm_drv->psr_list_lock, flags);
> + list_for_each_entry(psr, &drm_drv->psr_list, list) {
> if (psr->encoder->crtc == crtc)
> - return psr;
> + goto out;
> + }
> + psr = ERR_PTR(-ENODEV);
>
> - return ERR_PTR(-ENODEV);
> +out:
> + spin_unlock_irqrestore(&drm_drv->psr_list_lock, flags);
> + return psr;
> }
>
> static void psr_state_work(struct work_struct *work)
> @@ -173,7 +179,9 @@ void rockchip_drm_psr_flush(struct drm_device *dev)
> {
> struct rockchip_drm_private *drm_drv = dev->dev_private;
> struct psr_drv *psr;
> + unsigned long flags;
>
> + spin_lock_irqsave(&drm_drv->psr_list_lock, flags);
> list_for_each_entry(psr, &drm_drv->psr_list, list) {
> if (psr->request_state == PSR_DISABLE)
> continue;
> @@ -183,6 +191,7 @@ void rockchip_drm_psr_flush(struct drm_device *dev)
>
> psr_set_state(psr, PSR_FLUSH);
> }
> + spin_unlock_irqrestore(&drm_drv->psr_list_lock, flags);
> }
> EXPORT_SYMBOL(rockchip_drm_psr_flush);
>
> @@ -199,6 +208,7 @@ int rockchip_drm_psr_register(struct drm_encoder *encoder,
> {
> struct rockchip_drm_private *drm_drv = encoder->dev->dev_private;
> struct psr_drv *psr;
> + unsigned long flags;
>
> if (!encoder || !psr_set)
> return -EINVAL;
> @@ -215,9 +225,9 @@ int rockchip_drm_psr_register(struct drm_encoder *encoder,
> psr->encoder = encoder;
> psr->set = psr_set;
>
> - mutex_lock(&drm_drv->psr_list_mutex);
> + spin_lock_irqsave(&drm_drv->psr_list_lock, flags);
> list_add_tail(&psr->list, &drm_drv->psr_list);
> - mutex_unlock(&drm_drv->psr_list_mutex);
> + spin_unlock_irqrestore(&drm_drv->psr_list_lock, flags);
>
> return 0;
> }
> @@ -235,8 +245,9 @@ void rockchip_drm_psr_unregister(struct drm_encoder *encoder)
> {
> struct rockchip_drm_private *drm_drv = encoder->dev->dev_private;
> struct psr_drv *psr, *n;
> + unsigned long flags;
>
> - mutex_lock(&drm_drv->psr_list_mutex);
> + spin_lock_irqsave(&drm_drv->psr_list_lock, flags);
> list_for_each_entry_safe(psr, n, &drm_drv->psr_list, list) {
> if (psr->encoder == encoder) {
> del_timer(&psr->flush_timer);
> @@ -244,6 +255,6 @@ void rockchip_drm_psr_unregister(struct drm_encoder *encoder)
> kfree(psr);
> }
> }
> - mutex_unlock(&drm_drv->psr_list_mutex);
> + spin_unlock_irqrestore(&drm_drv->psr_list_lock, flags);
> }
> EXPORT_SYMBOL(rockchip_drm_psr_unregister);
More information about the dri-devel
mailing list