<div dir="auto"><div><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu., Jun. 3, 2021, 06:03 Daniel Vetter, <<a href="mailto:daniel@ffwll.ch">daniel@ffwll.ch</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">On Thu, Jun 03, 2021 at 04:20:18AM -0400, Marek Olšák wrote:<br>
> On Thu, Jun 3, 2021 at 3:47 AM Daniel Vetter <<a href="mailto:daniel@ffwll.ch" target="_blank" rel="noreferrer">daniel@ffwll.ch</a>> wrote:<br>
> <br>
> > On Wed, Jun 02, 2021 at 11:16:39PM -0400, Marek Olšák wrote:<br>
> > > On Wed, Jun 2, 2021 at 2:48 PM Daniel Vetter <<a href="mailto:daniel@ffwll.ch" target="_blank" rel="noreferrer">daniel@ffwll.ch</a>> wrote:<br>
> > ><br>
> > > > On Wed, Jun 02, 2021 at 05:38:51AM -0400, Marek Olšák wrote:<br>
> > > > > On Wed, Jun 2, 2021 at 5:34 AM Marek Olšák <<a href="mailto:maraeo@gmail.com" target="_blank" rel="noreferrer">maraeo@gmail.com</a>> wrote:<br>
> > > > ><br>
> > > > > > Yes, we can't break anything because we don't want to complicate<br>
> > things<br>
> > > > > > for us. It's pretty much all NAK'd already. We are trying to gather<br>
> > > > more<br>
> > > > > > knowledge and then make better decisions.<br>
> > > > > ><br>
> > > > > > The idea we are considering is that we'll expose memory-based sync<br>
> > > > objects<br>
> > > > > > to userspace for read only, and the kernel or hw will strictly<br>
> > control<br>
> > > > the<br>
> > > > > > memory writes to those sync objects. The hole in that idea is that<br>
> > > > > > userspace can decide not to signal a job, so even if userspace<br>
> > can't<br>
> > > > > > overwrite memory-based sync object states arbitrarily, it can still<br>
> > > > decide<br>
> > > > > > not to signal them, and then a future fence is born.<br>
> > > > > ><br>
> > > > ><br>
> > > > > This would actually be treated as a GPU hang caused by that context,<br>
> > so<br>
> > > > it<br>
> > > > > should be fine.<br>
> > > ><br>
> > > > This is practically what I proposed already, except your not doing it<br>
> > with<br>
> > > > dma_fence. And on the memory fence side this also doesn't actually give<br>
> > > > what you want for that compute model.<br>
> > > ><br>
> > > > This seems like a bit a worst of both worlds approach to me? Tons of<br>
> > work<br>
> > > > in the kernel to hide these not-dma_fence-but-almost, and still pain to<br>
> > > > actually drive the hardware like it should be for compute or direct<br>
> > > > display.<br>
> > > ><br>
> > > > Also maybe I've missed it, but I didn't see any replies to my<br>
> > suggestion<br>
> > > > how to fake the entire dma_fence stuff on top of new hw. Would be<br>
> > > > interesting to know what doesn't work there instead of amd folks going<br>
> > of<br>
> > > > into internal again and then coming back with another rfc from out of<br>
> > > > nowhere :-)<br>
> > > ><br>
> > ><br>
> > > Going internal again is probably a good idea to spare you the long<br>
> > > discussions and not waste your time, but we haven't talked about the<br>
> > > dma_fence stuff internally other than acknowledging that it can be<br>
> > solved.<br>
> > ><br>
> > > The compute use case already uses the hw as-is with no inter-process<br>
> > > sharing, which mostly keeps the kernel out of the picture. It uses<br>
> > glFinish<br>
> > > to sync with GL.<br>
> > ><br>
> > > The gfx use case needs new hardware logic to support implicit and<br>
> > explicit<br>
> > > sync. When we propose a solution, it's usually torn apart the next day by<br>
> > > ourselves.<br>
> > ><br>
> > > Since we are talking about next hw or next next hw, preemption should be<br>
> > > better.<br>
> > ><br>
> > > user queue = user-mapped ring buffer<br>
> > ><br>
> > > For implicit sync, we will only let userspace lock access to a buffer<br>
> > via a<br>
> > > user queue, which waits for the per-buffer sequence counter in memory to<br>
> > be<br>
> > > >= the number assigned by the kernel, and later unlock the access with<br>
> > > another command, which increments the per-buffer sequence counter in<br>
> > memory<br>
> > > with atomic_inc regardless of the number assigned by the kernel. The<br>
> > kernel<br>
> > > counter and the counter in memory can be out-of-sync, and I'll explain<br>
> > why<br>
> > > it's OK. If a process increments the kernel counter but not the memory<br>
> > > counter, that's its problem and it's the same as a GPU hang caused by<br>
> > that<br>
> > > process. If a process increments the memory counter but not the kernel<br>
> > > counter, the ">=" condition alongside atomic_inc guarantee that<br>
> > signaling n<br>
> > > will signal n+1, so it will never deadlock but also it will effectively<br>
> > > disable synchronization. This method of disabling synchronization is<br>
> > > similar to a process corrupting the buffer, which should be fine. Can you<br>
> > > find any flaw in it? I can't find any.<br>
> ><br>
> > Hm maybe I misunderstood what exactly you wanted to do earlier. That kind<br>
> > of "we let userspace free-wheel whatever it wants, kernel ensures<br>
> > correctness of the resulting chain of dma_fence with reset the entire<br>
> > context" is what I proposed too.<br>
> ><br>
> > Like you say, userspace is allowed to render garbage already.<br>
> ><br>
> > > The explicit submit can be done by userspace (if there is no<br>
> > > synchronization), but we plan to use the kernel to do it for implicit<br>
> > sync.<br>
> > > Essentially, the kernel will receive a buffer list and addresses of wait<br>
> > > commands in the user queue. It will assign new sequence numbers to all<br>
> > > buffers and write those numbers into the wait commands, and ring the hw<br>
> > > doorbell to start execution of that queue.<br>
> ><br>
> > Yeah for implicit sync I think kernel and using drm/scheduler to sort out<br>
> > the dma_fence dependencies is probably best. Since you can filter out<br>
> > which dma_fence you hand to the scheduler for dependency tracking you can<br>
> > filter out your own ones and let the hw handle those directly (depending<br>
> > how much your hw can do an all that). On i915 we might do that to be able<br>
> > to use MI_SEMAPHORE_WAIT/SIGNAL functionality in the hw and fw scheduler.<br>
> ><br>
> > For buffer tracking with implicit sync I think cleanest is probably to<br>
> > still keep them wrapped as dma_fence and stuffed into dma_resv, but<br>
> > conceptually it's the same. If we let every driver reinvent their own<br>
> > buffer tracking just because the hw works a bit different it'll be a mess.<br>
> ><br>
> > Wrt wait commands: I'm honestly not sure why you'd do that. Userspace gets<br>
> > to keep the pieces if it gets it wrong. You do still need to handle<br>
> > external dma_fence though, hence drm/scheduler frontend to sort these out.<br>
> ><br>
> <br>
> The reason is to disallow lower-privileged process to deadlock/hang a<br>
> higher-privileged process where the kernel can't tell who did it. If the<br>
> implicit-sync sequence counter is read only to userspace and only<br>
> incrementable by the unlock-signal command after the lock-wait command<br>
> appeared in the same queue (both together forming a critical section),<br>
> userspace can't manipulate it arbitrarily and we get almost the exact same<br>
> behavior as implicit sync has today. That means any implicitly-sync'd<br>
> buffer from any process can be fully trusted by a compositor to signal in a<br>
> finite time, and possibly even trusted by the kernel. The only thing that's<br>
> different is that a malicious process can disable implicit sync for a<br>
> buffer in all processes/kernel, but it can't hang other processes/kernel<br>
> (it can only hang itself and the kernel will be notified). So I'm a happy<br>
> panda now. :)<br>
<br>
Yeah I think that's not going to work too well, and is too many piled up<br>
hacks. Within a drm_file fd you can do whatever you feel like, since it's<br>
just one client.<br>
<br>
But once implicit sync kicks in I think you need to go with dma_fence and<br>
drm/scheduler to handle the dependencies, and tdr kicking it. With the<br>
dma_fence you do know who's the offender - you might not know why, but<br>
that doesn't matter, you just shred the entire context and let that<br>
userspace figure out the details.<br>
<br>
I think trying to make memory fences work as implicit sync directly,<br>
without wrapping them in a dma_fence and assorted guarantees, will just<br>
not work.<br>
<br>
And once you do wrap them in dma_fence, then all the other problems go<br>
away: cross-driver sync, syncfiles, ... So I really don't see the benefit<br>
of this half-way approach.<br>
<br>
Yes there's going to be a tad bit of overhead, but that's already there in<br>
the current model. And it can't hurt to have a bit of motivation for<br>
compositors to switch over to userspace memory fences properly.<br></blockquote></div></div><div dir="auto"><br></div><div dir="auto">Well, Christian thinks that we need a high level synchronization primitive in hw. I don't know myself and you may be right. A software scheduler with user queues might be one option. My part is only to find out how much of the scheduler logic can be moved to the hardware.</div><div dir="auto"><br></div><div dir="auto">We plan to have memory timeline semaphores, or simply monotonic counters, and a fence will be represented by the counter address and a constant sequence number for the <= comparison. One counter can represent up to 2^64 different fences. Giving any process write access to a fence is the same as giving it the power to manipulate the signalled state of a sequence of up to 2^64 fences. That could mess up a lot of things. However, if the hardware had a high level synchronization primitive with access rights and a limited set of clearly defined operations such that we can formally prove whether it's safe for everybody, we could have a solution where we don't have to involve the software scheduler and just let the hardware do everything.</div><div dir="auto"><br></div><div dir="auto">Marek</div><div dir="auto"><br></div><div dir="auto"><br></div><div dir="auto"><br></div><div dir="auto"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
-Daniel<br>
-- <br>
Daniel Vetter<br>
Software Engineer, Intel Corporation<br>
<a href="http://blog.ffwll.ch" rel="noreferrer noreferrer" target="_blank">http://blog.ffwll.ch</a><br>
</blockquote></div></div></div>