<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body>
    Am 18.03.21 um 10:30 schrieb Li, Dennis:<br>
    <blockquote type="cite" cite="mid:DM5PR12MB253379E8C89D8A20C8A0245AED699@DM5PR12MB2533.namprd12.prod.outlook.com">
      
      <meta name="Generator" content="Microsoft Word 15 (filtered
        medium)">
      <!--[if !mso]><style>v\:* {behavior:url(#default#VML);}
o\:* {behavior:url(#default#VML);}
w\:* {behavior:url(#default#VML);}
.shape {behavior:url(#default#VML);}
</style><![endif]-->
      <style>@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}@font-face
        {font-family:等线;
        panose-1:2 1 6 0 3 1 1 1 1 1;}@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}@font-face
        {font-family:"\@等线";
        panose-1:2 1 6 0 3 1 1 1 1 1;}@font-face
        {font-family:"Segoe UI";
        panose-1:2 11 5 2 4 2 4 2 2 3;}p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0in;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;}a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:#0563C1;
        text-decoration:underline;}span.EmailStyle19
        {mso-style-type:personal-reply;
        font-family:"Calibri",sans-serif;
        color:windowtext;}.MsoChpDefault
        {mso-style-type:export-only;
        font-size:10.0pt;}div.WordSection1
        {page:WordSection1;}</style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
      <div class="WordSection1">
        <p class="MsoNormal">>>> The GPU reset doesn't complete
          the fences we wait for. It only completes the hardware fences
          as part of the reset.<o:p></o:p></p>
        <p class="MsoNormal">>>> So waiting for a fence while
          holding the reset lock is illegal and needs to be avoided.<o:p></o:p></p>
        <p class="MsoNormal">I understood your concern. It is more
          complex for DRM GFX, therefore I abandon adding lock
          protection for DRM ioctls now. Maybe we can try to add all
          kernel  dma_fence waiting in a list, and signal all in
          recovery threads. Do you have same concern for compute cases?
        </p>
      </div>
    </blockquote>
    <br>
    Yes, compute (KFD) is even harder to handle.<br>
    <br>
    See you can't signal the dma_fence waiting. Waiting for a dma_fence
    also means you wait for the GPU reset to finish.<br>
    <br>
    When we would signal the dma_fence during the GPU reset then we
    would run into memory corruption because the hardware jobs running
    after the GPU reset would access memory which is already freed.<br>
    <br>
    <blockquote type="cite" cite="mid:DM5PR12MB253379E8C89D8A20C8A0245AED699@DM5PR12MB2533.namprd12.prod.outlook.com">
      <div class="WordSection1">
        <p class="MsoNormal"><o:p></o:p></p>
        <p class="MsoNormal"><o:p> </o:p></p>
        <p class="MsoNormal">>>> Lockdep also complains about
          this when it is used correctly. The only reason it doesn't
          complain here is because you use an atomic+wait_event instead
          of a locking primitive.<o:p></o:p></p>
        <p class="MsoNormal">Agree. This approach will escape the
          monitor of lockdep.  Its goal is to block other threads when
          GPU recovery thread start. But I couldn’t find a better method
          to solve this problem. Do you have some suggestion?
        </p>
      </div>
    </blockquote>
    <br>
    Well, completely abandon those change here.<br>
    <br>
    What we need to do is to identify where hardware access happens and
    then insert taking the read side of the GPU reset lock so that we
    don't wait for a dma_fence or allocate memory, but still protect the
    hardware from concurrent access and reset.<br>
    <br>
    Regards,<br>
    Christian.<br>
    <br>
    <blockquote type="cite" cite="mid:DM5PR12MB253379E8C89D8A20C8A0245AED699@DM5PR12MB2533.namprd12.prod.outlook.com">
      <div class="WordSection1">
        <p class="MsoNormal"><o:p></o:p></p>
        <p class="MsoNormal"><o:p> </o:p></p>
        <p class="MsoNormal">Best Regards<o:p></o:p></p>
        <p class="MsoNormal">Dennis Li<o:p></o:p></p>
        <p class="MsoNormal"><o:p> </o:p></p>
        <div>
          <div style="border:none;border-top:solid #E1E1E1
            1.0pt;padding:3.0pt 0in 0in 0in">
            <p class="MsoNormal"><b>From:</b> Koenig, Christian
              <a class="moz-txt-link-rfc2396E" href="mailto:Christian.Koenig@amd.com"><Christian.Koenig@amd.com></a> <br>
              <b>Sent:</b> Thursday, March 18, 2021 4:59 PM<br>
              <b>To:</b> Li, Dennis <a class="moz-txt-link-rfc2396E" href="mailto:Dennis.Li@amd.com"><Dennis.Li@amd.com></a>;
              <a class="moz-txt-link-abbreviated" href="mailto:amd-gfx@lists.freedesktop.org">amd-gfx@lists.freedesktop.org</a>; Deucher, Alexander
              <a class="moz-txt-link-rfc2396E" href="mailto:Alexander.Deucher@amd.com"><Alexander.Deucher@amd.com></a>; Kuehling, Felix
              <a class="moz-txt-link-rfc2396E" href="mailto:Felix.Kuehling@amd.com"><Felix.Kuehling@amd.com></a>; Zhang, Hawking
              <a class="moz-txt-link-rfc2396E" href="mailto:Hawking.Zhang@amd.com"><Hawking.Zhang@amd.com></a><br>
              <b>Subject:</b> AW: [PATCH 0/4] Refine GPU recovery
              sequence to enhance its stability<o:p></o:p></p>
          </div>
        </div>
        <p class="MsoNormal"><o:p> </o:p></p>
        <div>
          <p class="MsoNormal"><span style="font-size:12.0pt;font-family:"Segoe
              UI",sans-serif;color:black">Exactly that's what you
              don't seem to understand.<o:p></o:p></span></p>
        </div>
        <div>
          <p class="MsoNormal"><span style="font-size:12.0pt;font-family:"Segoe
              UI",sans-serif;color:black"><o:p> </o:p></span></p>
        </div>
        <div>
          <p class="MsoNormal"><span style="font-size:12.0pt;font-family:"Segoe
              UI",sans-serif;color:black">The GPU reset doesn't
              complete the fences we wait for. It only completes the
              hardware fences as part of the reset.<o:p></o:p></span></p>
        </div>
        <div>
          <p class="MsoNormal"><span style="font-size:12.0pt;font-family:"Segoe
              UI",sans-serif;color:black"><o:p> </o:p></span></p>
        </div>
        <div>
          <p class="MsoNormal"><span style="font-size:12.0pt;font-family:"Segoe
              UI",sans-serif;color:black">So waiting for a fence
              while holding the reset lock is illegal and needs to be
              avoided.<o:p></o:p></span></p>
        </div>
        <div>
          <p class="MsoNormal"><span style="font-size:12.0pt;font-family:"Segoe
              UI",sans-serif;color:black"><o:p> </o:p></span></p>
        </div>
        <div>
          <p class="MsoNormal"><span style="font-size:12.0pt;font-family:"Segoe
              UI",sans-serif;color:black">Lockdep also complains
              about this when it is used correctly. The only reason it
              doesn't complain here is because you use an
              atomic+wait_event instead of a locking primitive.<o:p></o:p></span></p>
        </div>
        <div>
          <p class="MsoNormal"><span style="font-size:12.0pt;font-family:"Segoe
              UI",sans-serif;color:black"><o:p> </o:p></span></p>
        </div>
        <div>
          <p class="MsoNormal"><span style="font-size:12.0pt;font-family:"Segoe
              UI",sans-serif;color:black">Regards,<o:p></o:p></span></p>
        </div>
        <div>
          <p class="MsoNormal"><span style="font-size:12.0pt;font-family:"Segoe
              UI",sans-serif;color:black">Christian.<o:p></o:p></span></p>
        </div>
        <div>
          <p class="MsoNormal"><o:p> </o:p></p>
        </div>
        <div class="MsoNormal" style="text-align:center" align="center">
          <hr width="98%" size="2" align="center">
        </div>
        <div id="divRplyFwdMsg">
          <p class="MsoNormal"><b><span style="color:black">Von:</span></b><span style="color:black"> Li, Dennis <<a href="mailto:Dennis.Li@amd.com" moz-do-not-send="true">Dennis.Li@amd.com</a>><br>
              <b>Gesendet:</b> Donnerstag, 18. März 2021 09:28<br>
              <b>An:</b> Koenig, Christian <<a href="mailto:Christian.Koenig@amd.com" moz-do-not-send="true">Christian.Koenig@amd.com</a>>;
              <a href="mailto:amd-gfx@lists.freedesktop.org" moz-do-not-send="true">amd-gfx@lists.freedesktop.org</a>
              <<a href="mailto:amd-gfx@lists.freedesktop.org" moz-do-not-send="true">amd-gfx@lists.freedesktop.org</a>>;
              Deucher, Alexander <<a href="mailto:Alexander.Deucher@amd.com" moz-do-not-send="true">Alexander.Deucher@amd.com</a>>;
              Kuehling, Felix <<a href="mailto:Felix.Kuehling@amd.com" moz-do-not-send="true">Felix.Kuehling@amd.com</a>>;
              Zhang, Hawking <<a href="mailto:Hawking.Zhang@amd.com" moz-do-not-send="true">Hawking.Zhang@amd.com</a>><br>
              <b>Betreff:</b> RE: [PATCH 0/4] Refine GPU recovery
              sequence to enhance its stability</span>
            <o:p></o:p></p>
          <div>
            <p class="MsoNormal"> <o:p></o:p></p>
          </div>
        </div>
        <div>
          <div>
            <p class="MsoNormal">>>> Those two steps need to be
              exchanged or otherwise it is possible that new delayed
              work items etc are started before the lock is taken.<br>
              What about adding check for adev->in_gpu_reset in work
              item? If exchange the two steps, it maybe introduce the
              deadlock.  For example, the user thread hold the read lock
              and waiting for the fence, if recovery thread try to hold
              write lock and then complete fences, in this case,
              recovery thread will always be blocked.<o:p></o:p></p>
          </div>
          <div>
            <p class="MsoNormal" style="margin-bottom:12.0pt"><br>
              Best Regards<br>
              Dennis Li<br>
              -----Original Message-----<br>
              From: Koenig, Christian <<a href="mailto:Christian.Koenig@amd.com" moz-do-not-send="true">Christian.Koenig@amd.com</a>>
              <br>
              Sent: Thursday, March 18, 2021 3:54 PM<br>
              To: Li, Dennis <<a href="mailto:Dennis.Li@amd.com" moz-do-not-send="true">Dennis.Li@amd.com</a>>; <a href="mailto:amd-gfx@lists.freedesktop.org" moz-do-not-send="true">
                amd-gfx@lists.freedesktop.org</a>; Deucher, Alexander
              <<a href="mailto:Alexander.Deucher@amd.com" moz-do-not-send="true">Alexander.Deucher@amd.com</a>>;
              Kuehling, Felix <<a href="mailto:Felix.Kuehling@amd.com" moz-do-not-send="true">Felix.Kuehling@amd.com</a>>;
              Zhang, Hawking <<a href="mailto:Hawking.Zhang@amd.com" moz-do-not-send="true">Hawking.Zhang@amd.com</a>><br>
              Subject: Re: [PATCH 0/4] Refine GPU recovery sequence to
              enhance its stability<br>
              <br>
              Am 18.03.21 um 08:23 schrieb Dennis Li:<br>
              > We have defined two variables in_gpu_reset and
              reset_sem in adev object. The atomic type variable
              in_gpu_reset is used to avoid recovery thread reenter and
              make lower functions return more earlier when recovery
              start, but couldn't block recovery thread when it access
              hardware. The r/w semaphore reset_sem is used to solve
              these synchronization issues between recovery thread and
              other threads.<br>
              ><br>
              > The original solution locked registers' access in
              lower functions, which will introduce following issues:<br>
              ><br>
              > 1) many lower functions are used in both recovery
              thread and others. Firstly we must harvest these
              functions, it is easy to miss someones. Secondly these
              functions need select which lock (read lock or write lock)
              will be used, according to the thread it is running in. If
              the thread context isn't considered, the added lock will
              easily introduce deadlock. Besides that, in most time,
              developer easily forget to add locks for new functions.<br>
              ><br>
              > 2) performance drop. More lower functions are more
              frequently called.<br>
              ><br>
              > 3) easily introduce false positive lockdep complaint,
              because write lock has big range in recovery thread, but
              low level functions will hold read lock may be protected
              by other locks in other threads.<br>
              ><br>
              > Therefore the new solution will try to add lock
              protection for ioctls of kfd. Its goal is that there are
              no threads except for recovery thread or its children (for
              xgmi) to access hardware when doing GPU reset and resume.
              So refine recovery thread as the following:<br>
              ><br>
              > Step 0: atomic_cmpxchg(&adev->in_gpu_reset, 0,
              1)<br>
              >     1). if failed, it means system had a recovery
              thread running, current thread exit directly;<br>
              >     2). if success, enter recovery thread;<br>
              ><br>
              > Step 1: cancel all delay works, stop drm schedule,
              complete all unreceived fences and so on. It try to stop
              or pause other threads.<br>
              ><br>
              > Step 2: call down_write(&adev->reset_sem) to
              hold write lock, which will block recovery thread until
              other threads release read locks.<br>
              <br>
              Those two steps need to be exchanged or otherwise it is
              possible that new delayed work items etc are started
              before the lock is taken.<br>
              <br>
              Just to make it clear until this is fixed the whole patch
              set is a NAK.<br>
              <br>
              Regards,<br>
              Christian.<br>
              <br>
              ><br>
              > Step 3: normally, there is only recovery threads
              running to access hardware, it is safe to do gpu reset
              now.<br>
              ><br>
              > Step 4: do post gpu reset, such as call all ips'
              resume functions;<br>
              ><br>
              > Step 5: atomic set adev->in_gpu_reset as 0, wake
              up other threads and release write lock. Recovery thread
              exit normally.<br>
              ><br>
              > Other threads call the amdgpu_read_lock to
              synchronize with recovery thread. If it finds that
              in_gpu_reset is 1, it should release read lock if it has
              holden one, and then blocks itself to wait for recovery
              finished event. If thread successfully hold read lock and
              in_gpu_reset is 0, it continues. It will exit normally or
              be stopped by recovery thread in step 1.<br>
              ><br>
              > Dennis Li (4):<br>
              >    drm/amdgpu: remove reset lock from low level
              functions<br>
              >    drm/amdgpu: refine the GPU recovery sequence<br>
              >    drm/amdgpu: instead of using down/up_read directly<br>
              >    drm/amdkfd: add reset lock protection for kfd
              entry functions<br>
              ><br>
              >   drivers/gpu/drm/amd/amdgpu/amdgpu.h           |   6
              +<br>
              >   drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c   |  14
              +-<br>
              >   drivers/gpu/drm/amd/amdgpu/amdgpu_device.c    | 173
              +++++++++++++-----<br>
              >   .../gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c    |   8
              -<br>
              >   drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c        |   4
              +-<br>
              >   drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c         |   9
              +-<br>
              >   drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c         |   5
              +-<br>
              >   drivers/gpu/drm/amd/amdgpu/mxgpu_nv.c         |   5
              +-<br>
              >   drivers/gpu/drm/amd/amdkfd/kfd_chardev.c      | 172
              ++++++++++++++++-<br>
              >   drivers/gpu/drm/amd/amdkfd/kfd_priv.h         |   3
              +-<br>
              >   drivers/gpu/drm/amd/amdkfd/kfd_process.c      |   4
              +<br>
              >   .../amd/amdkfd/kfd_process_queue_manager.c    |  17
              ++<br>
              >   12 files changed, 345 insertions(+), 75
              deletions(-)<br>
              ><o:p></o:p></p>
          </div>
        </div>
      </div>
    </blockquote>
    <br>
  </body>
</html>