<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body>
    Am 16.11.23 um 23:23 schrieb Danilo Krummrich:<br>
    <blockquote type="cite" cite="mid:ZVaWVH+mX+PXKqfD@pollux">[SNIP]<span
      style="white-space: pre-wrap">
</span>
      <pre class="moz-quote-pre" wrap=""></pre>
      <blockquote type="cite">
        <pre class="moz-quote-pre" wrap="">+ *
+ * The lifetime of the scheduler is managed by the driver using it. Before
+ * destroying the scheduler the driver must ensure that all hardware processing
+ * involving this scheduler object has finished by calling for example
+ * disable_irq(). It is *not* sufficient to wait for the hardware fence here
+ * since this doesn't guarantee that all callback processing has finished.
</pre>
      </blockquote>
      <pre class="moz-quote-pre" wrap="">
This is the part I'm most concerned about, since I feel like we leave drivers
"up in the air" entirely. Hence, I think here we need to be more verbose and
detailed about the options drivers have to ensure that.

For instance, let's assume we have the single-entity-per-scheduler topology
because the driver only uses the GPU scheduler to feed a firmware scheduler with
dynamically allocated ring buffers.

In this case the entity, scheduler and ring buffer are bound to the lifetime of
a userspace process.

What do we expect the driver to do if the userspace process is killed? As you
mentioned, only waiting for the ring to be idle (which implies all HW fences
are signalled) is not enough. This doesn't guarantee all the free_job()
callbacks have been called yet and hence stopping the scheduler before the
pending_list is actually empty would leak the memory of the jobs on the
pending_list waiting to be freed.

I already brought this up when we were discussing Matt's Xe inspired scheduler
patch series and it seems there was no interest to provide drivers with some
common mechanism that gurantees that the pending_list is empty. Hence, I really
think we should at least give recommendations how drivers should deal with that.
</pre>
    </blockquote>
    <br>
    I put this work on hold to have time looking deeper into this and
    trying to find alternative ways for the handling.<br>
    <br>
    I think this is another good reason why the scheduler should really
    not be involved in freeing jobs, but let's first discuss another
    issue with this.<br>
    <br>
    It goes far down into the underlying dma_fence mechanism which gives
    you guarantees that hardware operations have finished, but not that
    the associated software callbacks are done.<br>
    <br>
    So what happens is that components like the scheduler can't just
    wait for dma_fences to be sure that a registered callback are not
    executed on another CPU.<br>
    <br>
    See this patch here for another example where this totally bites us
    in drivers, completely independent of the GPU scheduler:<br>
    <br>
    commit 7c703a7d3f2b50a6187267420a4d3d7e62fa3206<br>
    Author: xinhui pan <a class="moz-txt-link-rfc2396E" href="mailto:xinhui.pan@amd.com"><xinhui.pan@amd.com></a><br>
    Date:   Tue Apr 12 19:52:16 2022 +0800<br>
    <br>
        drm/amdgpu: Fix one use-after-free of VM<br>
    <br>
    Basically the solution amdgpu came up with is to take and drop the
    spinlock of the underlying dma_fence context:<br>
    <br>
    /* Make sure that all fence callbacks have completed */<br>
    spin_lock_irqsave(vm->last_tlb_flush->lock, flags);<br>
    spin_unlock_irqrestore(vm->last_tlb_flush->lock, flags);<br>
    <br>
    But this is just a hack only works because amdgpu knows the
    internals of his own dma_fence implementation.<br>
    <br>
    For the scheduler this is not applicable. I've mentioned this
    problem to Daniel before, but at least at this time he thought that
    this is a complete driver problem.<br>
    <br>
    Ideas?<br>
    <br>
    Regards,<br>
    Christian.<br>
    <br>
  </body>
</html>