• Chris Wilson's avatar
    drm/i915: Flush pages on acquisition · a679f58d
    Chris Wilson authored
    When we return pages to the system, we ensure that they are marked as
    being in the CPU domain since any external access is uncontrolled and we
    must assume the worst. This means that we need to always flush the pages
    on acquisition if we need to use them on the GPU, and from the beginning
    have used set-domain. Set-domain is overkill for the purpose as it is a
    general synchronisation barrier, but our intent is to only flush the
    pages being swapped in. If we move that flush into the pages acquisition
    phase, we know then that when we have obj->mm.pages, they are coherent
    with the GPU and need only maintain that status without resorting to
    heavy handed use of set-domain.
    
    The principle knock-on effect for userspace is through mmap-gtt
    pagefaulting. Our uAPI has always implied that the GTT mmap was async
    (especially as when any pagefault occurs is unpredicatable to userspace)
    and so userspace had to apply explicit domain control itself
    (set-domain). However, swapping is transparent to the kernel, and so on
    first fault we need to acquire the pages and make them coherent for
    access through the GTT. Our use of set-domain here leaks into the uABI
    that the first pagefault was synchronous. This is unintentional and
    baring a few igt should be unoticed, nevertheless we bump the uABI
    version for mmap-gtt to reflect the change in behaviour.
    
    Another implication of the change is that gem_create() is presumed to
    create an object that is coherent with the CPU and is in the CPU write
    domain, so a set-domain(CPU) following a gem_create() would be a minor
    operation that merely checked whether we could allocate all pages for
    the object. On applying this change, a set-domain(CPU) causes a clflush
    as we acquire the pages. This will have a small impact on mesa as we move
    the clflush here on !llc from execbuf time to create, but that should
    have minimal performance impact as the same clflush exists but is now
    done early and because of the clflush issue, userspace recycles bo and
    so should resist allocating fresh objects.
    
    Internally, the presumption that objects are created in the CPU
    write-domain and remain so through writes to obj->mm.mapping is more
    prevalent than I expected; but easy enough to catch and apply a manual
    flush.
    
    For the future, we should push the page flush from the central
    set_pages() into the callers so that we can more finely control when it
    is applied, but for now doing it one location is easier to validate, at
    the cost of sometimes flushing when there is no need.
    Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
    Cc: Matthew Auld <matthew.william.auld@gmail.com>
    Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
    Cc: Antonio Argenziano <antonio.argenziano@intel.com>
    Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
    Reviewed-by: default avatarMatthew Auld <matthew.william.auld@gmail.com>
    Link: https://patchwork.freedesktop.org/patch/msgid/20190321161908.8007-1-chris@chris-wilson.co.uk
    a679f58d
intel_ringbuffer.c 59.8 KB