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

drm/exynos: fix lockdep for event_lock wrt. vbl_time_lock

Currently the exynos driver calls drm_vblank_off() with the event_lock
held, while drm_vblank_off() will lock vbl_time and vblank_time_lock.
This lock dependency chain conflicts with the one in drm_handle_vblank()
where we first lock vblank_time_lock and then the event_lock.

Fix this by removing the above drm_vblank_off() calls which are in fact
never executed: drm_dev->vblank_disable_allowed is only ever non-zero
during driver init, until it's set in {fimd,vidi}_subdrv_probe. Both the
driver init and open code is protected by drm_global_mutex, so the
earliest page flip ioctl can happen only after vblank_disable_allowed is
set to 1. Thus {fimd,vidi}_finish_pageflip - with pending flip events -
will always get called with vblank_disable_allowed being 1.

Signed-off-by: Imre Deak <imre.deak@intel.com>
Signed-off-by: Inki Dae <inki.dae@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>

authored by

Imre Deak and committed by
Inki Dae
9fb7dff5 e1f48ee5

-24
-12
drivers/gpu/drm/exynos/exynos_drm_fimd.c
··· 623 623 struct drm_pending_vblank_event *e, *t; 624 624 struct timeval now; 625 625 unsigned long flags; 626 - bool is_checked = false; 627 626 628 627 spin_lock_irqsave(&drm_dev->event_lock, flags); 629 628 ··· 632 633 if (crtc != e->pipe) 633 634 continue; 634 635 635 - is_checked = true; 636 - 637 636 do_gettimeofday(&now); 638 637 e->event.sequence = 0; 639 638 e->event.tv_sec = now.tv_sec; ··· 640 643 list_move_tail(&e->base.link, &e->base.file_priv->event_list); 641 644 wake_up_interruptible(&e->base.file_priv->event_wait); 642 645 drm_vblank_put(drm_dev, crtc); 643 - } 644 - 645 - if (is_checked) { 646 - /* 647 - * don't off vblank if vblank_disable_allowed is 1, 648 - * because vblank would be off by timer handler. 649 - */ 650 - if (!drm_dev->vblank_disable_allowed) 651 - drm_vblank_off(drm_dev, crtc); 652 646 } 653 647 654 648 spin_unlock_irqrestore(&drm_dev->event_lock, flags);
-12
drivers/gpu/drm/exynos/exynos_drm_vidi.c
··· 382 382 struct drm_pending_vblank_event *e, *t; 383 383 struct timeval now; 384 384 unsigned long flags; 385 - bool is_checked = false; 386 385 387 386 spin_lock_irqsave(&drm_dev->event_lock, flags); 388 387 ··· 391 392 if (crtc != e->pipe) 392 393 continue; 393 394 394 - is_checked = true; 395 - 396 395 do_gettimeofday(&now); 397 396 e->event.sequence = 0; 398 397 e->event.tv_sec = now.tv_sec; ··· 399 402 list_move_tail(&e->base.link, &e->base.file_priv->event_list); 400 403 wake_up_interruptible(&e->base.file_priv->event_wait); 401 404 drm_vblank_put(drm_dev, crtc); 402 - } 403 - 404 - if (is_checked) { 405 - /* 406 - * don't off vblank if vblank_disable_allowed is 1, 407 - * because vblank would be off by timer handler. 408 - */ 409 - if (!drm_dev->vblank_disable_allowed) 410 - drm_vblank_off(drm_dev, crtc); 411 405 } 412 406 413 407 spin_unlock_irqrestore(&drm_dev->event_lock, flags);