• V
    drm: Fix deadlock between event_lock and vbl_lock/vblank_time_lock · 56cc279b
    Ville Syrjälä 提交于
    Currently both drm_irq.c and several drivers call drm_vblank_put()
    while holding event_lock. Now that drm_vblank_put() can disable the
    vblank interrupt directly it may need to grab vbl_lock and
    vblank_time_lock. That causes deadlocks since we take the locks
    in the opposite order in two places in drm_irq.c. So let's make
    sure the locking order is always event_lock->vbl_lock->vblank_time_lock.
    
    In drm_vblank_off() pull up event_lock from underneath vbl_lock. Hold
    the event_lock across the whole operation to make sure we only send
    out the events that were on the queue when we disabled the interrupt,
    and not ones that got added just after (assuming drm_vblank_on() already
    managed to get called somewhere between).
    
    To sort the other deadlock pull the event_lock out from
    drm_handle_vblank_events() into drm_handle_vblank() to be taken outside
    vblank_time_lock. Add the appropriate assert_spin_locked() to
    drm_handle_vblank_events().
    Reviewed-by: NMatt Roper <matthew.d.roper@intel.com>
    Signed-off-by: NVille Syrjälä <ville.syrjala@linux.intel.com>
    Signed-off-by: NDaniel Vetter <daniel.vetter@ffwll.ch>
    56cc279b
drm_irq.c 45.3 KB