• Dave Airlie's avatar
    Merge branch 'drm-kms-locking' of git://people.freedesktop.org/~danvet/drm-intel into drm-next · 735dc0d1
    Dave Airlie authored
    The aim of this locking rework is that ioctls which a compositor should be
    might call for every frame (set_cursor, page_flip, addfb, rmfb and
    getfb/create_handle) should not be able to block on kms background
    activities like output detection. And since each EDID read takes about
    25ms (in the best case), that always means we'll drop at least one frame.
    
    The solution is to add per-crtc locking for these ioctls, and restrict
    background activities to only use the global lock. Change-the-world type
    of events (modeset, dpms, ...) need to grab all locks.
    
    Two tricky parts arose in the conversion:
    - A lot of current code assumes that a kms fb object can't disappear while
      holding the global lock, since the current code serializes fb
      destruction with it. Hence proper lifetime management using the already
      created refcounting for fbs need to be instantiated for all ioctls and
      interfaces/users.
    
    - The rmfb ioctl removes the to-be-deleted fb from all active users. But
      unconditionally taking the global kms lock to do so introduces an
      unacceptable potential stall point. And obviously changing the userspace
      abi isn't on the table, either. Hence this conversion opportunistically
      checks whether the rmfb ioctl holds the very last reference, which
      guarantees that the fb isn't in active use on any crtc or plane (thanks
      to the conversion to the new lifetime rules using proper refcounting).
      Only if this is not the case will the code go through the slowpath and
      grab all modeset locks. Sane compositors will never hit this path and so
      avoid the stall, but userspace relying on these semantics will also not
      break.
    
    All these cases are exercised by the newly added subtests for the i-g-t
    kms_flip, tested on a machine where a full detect cycle takes around 100
    ms.  It works, and no frames are dropped any more with these patches
    applied.  kms_flip also contains a special case to exercise the
    above-describe rmfb slowpath.
    
    * 'drm-kms-locking' of git://people.freedesktop.org/~danvet/drm-intel: (335 commits)
      drm/fb_helper: check whether fbcon is bound
      drm/doc: updates for new framebuffer lifetime rules
      drm: don't hold crtc mutexes for connector ->detect callbacks
      drm: only grab the crtc lock for pageflips
      drm: optimize drm_framebuffer_remove
      drm/vmwgfx: add proper framebuffer refcounting
      drm/i915: dump refcount into framebuffer debugfs file
      drm: refcounting for crtc framebuffers
      drm: refcounting for sprite framebuffers
      drm: fb refcounting for dirtyfb_ioctl
      drm: don't take modeset locks in getfb ioctl
      drm: push modeset_lock_all into ->fb_create driver callbacks
      drm: nest modeset locks within fpriv->fbs_lock
      drm: reference framebuffers which are on the idr
      drm: revamp framebuffer cleanup interfaces
      drm: create drm_framebuffer_lookup
      drm: revamp locking around fb creation/destruction
      drm: only take the crtc lock for ->cursor_move
      drm: only take the crtc lock for ->cursor_set
      drm: add per-crtc locks
      ...
    735dc0d1
drm_mm.c 20.7 KB