<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Thu, Nov 3, 2016 at 3:00 PM, Chris Wilson <span dir="ltr"><<a href="mailto:chris@chris-wilson.co.uk" target="_blank">chris@chris-wilson.co.uk</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">On Thu, Nov 03, 2016 at 02:19:01PM -0700, Jason Ekstrand wrote:<br>
<span class="">>    On Thu, Nov 3, 2016 at 1:53 AM, Chris Wilson <[1]<a href="mailto:chris@chris-wilson.co.uk">chris@chris-wilson.co.uk</a>><br>
>    wrote:<br>
><br>
>      Something to consider is just randomly assigning an address and using<br>
>      it. The kernel will relocate if it wants to, but in future the kernel<br>
>      will use your address as a hint and try to bind the object there (if<br>
>      that space is available). Like softpinning, but without failing with<br>
>      -EINVAL if the space is not available. Or you may of course do full<br>
>      client side address allocation under full-ppgtt (the hybrid scheme is<br>
>      still useful elsewhere). The advantage is avoiding the stall on first<br>
>      state use. The disadvantage is that until that patch lands, you walk the<br>
>      relocations for no gain (otoh, since the kernel will take its own sweet<br>
>      time doing the same, the inefficiency here will hopefully be<br>
>      negligible.)<br>
><br>
>    Does that really work?  My reading of the kernel sources indicates that<br>
>    NO_RELOC means the kernel will just assume that they match what it gave<br>
>    you in the last execbuf2.  It never checks that the offsets match unless<br>
>    it had to move something in the GTT.  If, on the other hand, you mark the<br>
>    object as PINNED and the offsets don't match, it will get flagged in<br>
>    eb_vma_misplaced, remapped, and the relocations *will* trigger.<br>
>     <br>
><br>
</span><span class="">>      /* The requirement for using NO_RELOC is:<br>
>       *<br>
>       *      The addresses written in the objects must match the<br>
>      corresponding<br>
>       *      reloc.presumed_offset which in turn must match the corresponding<br>
>       *      execobject.offset.<br>
>       *<br>
>       *      To avoid stalling, execobject.offset should match the current<br>
>       *      address of that object within the active context.<br>
><br>
>    Actually, from my reading of the i915 sources, the kernel doesn't check<br>
>    this.  It's your responsibility to ensure that they match the addresses<br>
>    returned by the previous execbuf2 ioctl.<br>
<br>
</span>As it stands today, using NO_RELOC without PINNED, the kernel will<br>
arbitrarily assign an address to each buffer. (The kernel doesn't move<br>
objects unless it has to, so that address is likely to match the last<br>
execbuf, and indeed guaranteed if it is still active.) If all the<br>
addresses the kernel choose match the addresses you pass in<br>
execobject[].offset, it will skip all the relocations. So it works best<br>
when passing back the offset from the previous execbuf.<br></blockquote><div><br></div><div>Are you sure it actually checks execobject[].offset?  I haven't been able to find that check anywhere in the code except for one check that's guarded by PINNED.  Also, I've gotten hangs (presumably because the kernel didn't relocate) when I passed NO_RELOC with offsets that didn't match the last execbuf2.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
The loop in reservation is:<br>
<br>
        for each bound object:<br>
                if address not suitable:<br>
                        unbind<br>
                else<br>
                        pin<br>
        for each unbound object:<br>
                bind<br>
                pin<br>
<br>
where the pin does the check of kernel address against<br>
execobject.offset, and marking up if it need_relocs.<br>
<br>
The patch I've been trying to land is for execbuf to first try to pin<br>
the object at the address given in the NO_RELOC execobj.offset,<br>
because then it can skip all the work. (Under normal scenarios, the<br>
object is already at that address. But it helps fix up the issues with<br>
relocations being shared in userspace between different contexts, bad<br>
libdrm_intel, bad.) Obviously, we don't want to kick anything already<br>
at that address (it's a balance between doing a relocation now, or<br>
causing ping-pong).<br>
<div class="HOEnZb"><div class="h5">-Chris<br>
<br>
--<br>
Chris Wilson, Intel Open Source Technology Centre<br>
</div></div></blockquote></div><br></div></div>