• Chris Wilson's avatar
    drm/i915: Split execlist priority queue into rbtree + linked list · 6c067579
    Chris Wilson authored
    All the requests at the same priority are executed in FIFO order. They
    do not need to be stored in the rbtree themselves, as they are a simple
    list within a level. If we move the requests at one priority into a list,
    we can then reduce the rbtree to the set of priorities. This should keep
    the height of the rbtree small, as the number of active priorities can not
    exceed the number of active requests and should be typically only a few.
    
    Currently, we have ~2k possible different priority levels, that may
    increase to allow even more fine grained selection. Allocating those in
    advance seems a waste (and may be impossible), so we opt for allocating
    upon first use, and freeing after its requests are depleted. To avoid
    the possibility of an allocation failure causing us to lose a request,
    we preallocate the default priority (0) and bump any request to that
    priority if we fail to allocate it the appropriate plist. Having a
    request (that is ready to run, so not leading to corruption) execute
    out-of-order is better than leaking the request (and its dependency
    tree) entirely.
    
    There should be a benefit to reducing execlists_dequeue() to principally
    using a simple list (and reducing the frequency of both rbtree iteration
    and balancing on erase) but for typical workloads, request coalescing
    should be small enough that we don't notice any change. The main gain is
    from improving PI calls to schedule, and the explicit list within a
    level should make request unwinding simpler (we just need to insert at
    the head of the list rather than the tail and not have to make the
    rbtree search more complicated).
    
    v2: Avoid use-after-free when deleting a depleted priolist
    
    v3: Michał found the solution to handling the allocation failure
    gracefully. If we disable all priority scheduling following the
    allocation failure, those requests will be executed in fifo and we will
    ensure that this request and its dependencies are in strict fifo (even
    when it doesn't realise it is only a single list). Normal scheduling is
    restored once we know the device is idle, until the next failure!
    Suggested-by: default avatarMichał Wajdeczko <michal.wajdeczko@intel.com>
    Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
    Cc: Michał Winiarski <michal.winiarski@intel.com>
    Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
    Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
    Reviewed-by: default avatarMichał Winiarski <michal.winiarski@intel.com>
    Reviewed-by: default avatarTvrtko Ursulin <tvrtko.ursulin@intel.com>
    Link: http://patchwork.freedesktop.org/patch/msgid/20170517121007.27224-8-chris@chris-wilson.co.uk
    6c067579
intel_engine_cs.c 35.6 KB