<html>
  <head>
    <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
  </head>
  <body text="#000000" bgcolor="#FFFFFF">
    <div class="moz-cite-prefix">Am 10.05.2017 um 13:50 schrieb Liu,
      Monk:<br>
    </div>
    <blockquote
cite="mid:CY4PR12MB1606BB848CEA7D400A1869DA84EC0@CY4PR12MB1606.namprd12.prod.outlook.com"
      type="cite">
      <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
      <meta name="Generator" content="Microsoft Word 15 (filtered
        medium)">
      <style><!--
/* Font Definitions */
@font-face
        {font-family:SimSun;
        panose-1:2 1 6 0 3 1 1 1 1 1;}
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
        {font-family:Consolas;
        panose-1:2 11 6 9 2 2 4 3 2 4;}
@font-face
        {font-family:"\@SimSun";
        panose-1:2 1 6 0 3 1 1 1 1 1;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0in;
        margin-bottom:.0001pt;
        font-size:12.0pt;
        font-family:"Times New Roman",serif;
        color:black;}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:purple;
        text-decoration:underline;}
p
        {mso-style-priority:99;
        mso-margin-top-alt:auto;
        margin-right:0in;
        mso-margin-bottom-alt:auto;
        margin-left:0in;
        font-size:12.0pt;
        font-family:"Times New Roman",serif;
        color:black;}
pre
        {mso-style-priority:99;
        mso-style-link:"HTML 预设格式 Char";
        margin:0in;
        margin-bottom:.0001pt;
        font-size:10.0pt;
        font-family:"Courier New";
        color:black;}
p.MsoListParagraph, li.MsoListParagraph, div.MsoListParagraph
        {mso-style-priority:34;
        margin-top:0in;
        margin-right:0in;
        margin-bottom:0in;
        margin-left:.5in;
        margin-bottom:.0001pt;
        font-size:12.0pt;
        font-family:"Times New Roman",serif;
        color:black;}
span.HTMLChar
        {mso-style-name:"HTML 预设格式 Char";
        mso-style-priority:99;
        mso-style-link:"HTML 预设格式";
        font-family:Consolas;
        color:black;}
p.emailquote, li.emailquote, div.emailquote
        {mso-style-name:emailquote;
        mso-style-priority:99;
        mso-margin-top-alt:auto;
        margin-right:0in;
        mso-margin-bottom-alt:auto;
        margin-left:1.0pt;
        font-size:12.0pt;
        font-family:"Times New Roman",serif;
        color:black;}
span.EmailStyle22
        {mso-style-type:personal;
        font-family:"Calibri",sans-serif;
        color:#1F497D;}
span.EmailStyle23
        {mso-style-type:personal;
        font-family:"Calibri",sans-serif;
        color:#1F497D;}
span.EmailStyle24
        {mso-style-type:personal;
        font-family:"Calibri",sans-serif;
        color:#1F497D;}
span.EmailStyle25
        {mso-style-type:personal;
        font-family:"Calibri",sans-serif;
        color:#1F497D;}
span.EmailStyle26
        {mso-style-type:personal-reply;
        font-family:"Calibri",sans-serif;
        color:#1F497D;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-size:10.0pt;}
@page WordSection1
        {size:8.5in 11.0in;
        margin:1.0in 1.0in 1.0in 1.0in;}
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">>Because stopping all the scheduler
          threads takes a moment and it is entirely possible that the
          job finishes within that time.<o:p></o:p></p>
        <p class="MsoNormal"><span
style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D"><o:p> </o:p></span></p>
        <p class="MsoNormal"><span
style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D">Sounds
            reasonable, but instead not, because if so why not increase
            timed_out value to + 0.5 sec ? that should cover the time on
            stop all schedulers,</span></p>
      </div>
    </blockquote>
    <br>
    That won't work, see you need to stop the scheduler to figure out if
    the job is actually hung.<br>
    <br>
    <blockquote
cite="mid:CY4PR12MB1606BB848CEA7D400A1869DA84EC0@CY4PR12MB1606.namprd12.prod.outlook.com"
      type="cite">
      <div class="WordSection1">
        <p class="MsoNormal"><span
style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D"><o:p></o:p></span></p>
        <p class="MsoNormal"><span
style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D">So
            the point is we should rely on and trust timedout parm since
            it is the only way to let kernel side aware GPU may hang …<o:p></o:p></span></p>
        <p class="MsoNormal"><span
style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D"><o:p> </o:p></span></p>
        <p class="MsoNormal"><span
style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D">If
            there is a way to detect GPU hang (actually we have such
            method, implemented in RLCV side) in kernel driver side,
            that will convince me
            <o:p></o:p></span></p>
        <p class="MsoNormal"><span
style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D">To
            check the fence at least one time, like:<o:p></o:p></span></p>
        <p class="MsoNormal"><span
style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D"><o:p> </o:p></span></p>
        <p class="MsoNormal"><span
style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D">Void
            Gpu_reset()<o:p></o:p></span></p>
        <p class="MsoNormal"><span
style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D">{<o:p></o:p></span></p>
        <p class="MsoNormal"><span
style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D">Hang
            = Check_gpu_hang_or_busy();<o:p></o:p></span></p>
        <p class="MsoNormal"><span
style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D">If
            (!hang) {<o:p></o:p></span></p>
        <p class="MsoNormal"><span
style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D">//looks
            like the job is still running, we can let it run …<o:p></o:p></span></p>
        <p class="MsoNormal"><span
style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D">  
            Return;<o:p></o:p></span></p>
        <p class="MsoNormal"><span
style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D">}
            else {<o:p></o:p></span></p>
        <p class="MsoNormal"><span
style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D"><span
              style="background:yellow;mso-highlight:yellow">Signaled =
              fence_signaled(job);</span><o:p></o:p></span></p>
        <p class="MsoNormal"><span
style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D">If
            (signaled) 
            <o:p></o:p></span></p>
        <p class="MsoNormal" style="text-indent:9.0pt"><span
style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D">Return;
            //do nothing<o:p></o:p></span></p>
        <p class="MsoNormal"><span
style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D">}<o:p></o:p></span></p>
        <p class="MsoNormal"><span
style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D">…<o:p></o:p></span></p>
        <p class="MsoNormal"><span
style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D">}</span></p>
      </div>
    </blockquote>
    <br>
    Well what we actually need to do is to stop the hardware from doing
    any processing, but that's easier said than done.<br>
    <br>
    <blockquote
cite="mid:CY4PR12MB1606BB848CEA7D400A1869DA84EC0@CY4PR12MB1606.namprd12.prod.outlook.com"
      type="cite">
      <div class="WordSection1">
        <p class="MsoNormal"><span
style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D"><o:p></o:p></span></p>
        <p class="MsoNormal"><span
style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D"><o:p></o:p></span><span
style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D"><o:p></o:p></span><span
style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D">I
            can say that we may still have chance to implement this
            hang_detection in kernel driver side, but it is not easy so
            currently I only trust timedout event
          </span></p>
      </div>
    </blockquote>
    <br>
    I still don't think that this is a good idea. At least on bare metal
    we need more checks than that to determine if we really should reset
    the hardware or not.<br>
    <br>
    Regards,<br>
    Christian.<br>
    <br>
    <blockquote
cite="mid:CY4PR12MB1606BB848CEA7D400A1869DA84EC0@CY4PR12MB1606.namprd12.prod.outlook.com"
      type="cite">
      <div class="WordSection1">
        <p class="MsoNormal"><span
style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D"><o:p></o:p></span></p>
        <p class="MsoNormal"><span
style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D"><o:p> </o:p></span></p>
        <p class="MsoNormal"><span
style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D">BR
            Monk<o:p></o:p></span></p>
        <p class="MsoNormal"><span
style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D"><o:p> </o:p></span></p>
        <div>
          <div style="border:none;border-top:solid #E1E1E1
            1.0pt;padding:3.0pt 0in 0in 0in">
            <p class="MsoNormal"><b><span
style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:windowtext">From:</span></b><span
style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:windowtext">
                Christian König [<a class="moz-txt-link-freetext" href="mailto:deathsimple@vodafone.de">mailto:deathsimple@vodafone.de</a>]
                <br>
                <b>Sent:</b> Wednesday, May 10, 2017 7:14 PM<br>
                <b>To:</b> Liu, Monk <a class="moz-txt-link-rfc2396E" href="mailto:Monk.Liu@amd.com"><Monk.Liu@amd.com></a>; Koenig,
                Christian <a class="moz-txt-link-rfc2396E" href="mailto:Christian.Koenig@amd.com"><Christian.Koenig@amd.com></a>;
                <a class="moz-txt-link-abbreviated" href="mailto:amd-gfx@lists.freedesktop.org">amd-gfx@lists.freedesktop.org</a><br>
                <b>Subject:</b> Re: [PATCH 4/4]
                drm/amdgpu/SRIOV:implement guilty job TDR (V2)<o:p></o:p></span></p>
          </div>
        </div>
        <p class="MsoNormal"><o:p> </o:p></p>
        <div>
          <blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
            <p class="MsoNormal">You still avoid my question: what’s the
              theoretical backend you that you think check once instead
              of twice or even more is good*<b>before</b>*
              hw_job_reset() ?<o:p></o:p></p>
          </blockquote>
          <p class="MsoNormal">Because stopping all the scheduler
            threads takes a moment and it is entirely possible that the
            job finishes within that time.<br>
            <br>
            <br>
            <o:p></o:p></p>
          <blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
            <p class="MsoNormal">1) if you check the fence and found it
              not signaled, then you will call hw_job_reset(), but there
              is still chance that between your check and the
              hw_job_reset() the
              <o:p></o:p></p>
            <p class="MsoNormal"
              style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">Sched
              fence could signaled , isn’t it ?  you still cannot avoid
              such race condition
              <o:p></o:p></p>
          </blockquote>
          <p class="MsoNormal">Crap, you're right. We would indeed need
            to check twice and that wouldn't be consistent anyway.<br>
            <br>
            Once after stopping the schedulers and before hw_job_reset()
            because then we can just start the schedulers again and
            continue as if nothing has happened.<br>
            <br>
            And another time after calling hw_job_reset() if we want to
            set the error code.<br>
            <br>
            <br>
            <o:p></o:p></p>
          <blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
            <p class="MsoNormal"
              style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">Don’t
              forget your approach still have chance to hit the race
              condition, and to me I don’t think the race condition
              matters that’s why I don’t even consider it
              <o:p></o:p></p>
          </blockquote>
          <p class="MsoNormal">Yeah, you convinced me. Please go ahead
            with the current approach, but at least add a comment that
            we might want to improve that.<br>
            <br>
            Regards,<br>
            Christian.<br>
            <br>
            Am 10.05.2017 um 13:02 schrieb Liu, Monk:<o:p></o:p></p>
        </div>
        <blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
          <p class="MsoNormal"><span
style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D">></span>
            Checking a second time is pointless since it can't signal
            any more after calling amd_sched_hw_job_reset().<o:p></o:p></p>
          <p class="MsoNormal"> <o:p></o:p></p>
          <p class="MsoNormal">[ML] you seems not response to me … I of
            cause know fence cannot signal after hw_job_reset() ….<o:p></o:p></p>
          <p class="MsoNormal">My question is , before you call
            hw_job_reset(), why you want to check the fence ? why not
            check twice ?<o:p></o:p></p>
          <p class="MsoNormal">You still avoid my question: what’s the
            theoretical backend you that you think check once instead of
            twice or even more is good*<b>before</b>* hw_job_reset() ?<o:p></o:p></p>
          <p class="MsoNormal"> <o:p></o:p></p>
          <p class="MsoNormal">>No, the timeout is pretty
            meaningless. It's just the trigger that we need to do
            something.<o:p></o:p></p>
          <p class="MsoNormal"><span
style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D">2)
              And even it signaled after entering gpu_reset(), it will
              automatically done like normal cases, that’s good. Why
              remove those callback instead ?</span><o:p></o:p></p>
          <p class="MsoNormal">> No, that's absolutely not good. We
            don't know if it's the hardware which results in the job
            being signaled or our reset code.<o:p></o:p></p>
          <p class="MsoNormal"> <o:p></o:p></p>
          <p class="MsoNormal">[ML] you are wrong, for SR-IOV case, the
            timeout is all that matters, because one VF can only have
            such time slice within timeout, and I’m doing the TDR on
            SR-IOV so don’t<o:p></o:p></p>
          <p class="MsoNormal">Always looks things with bare-metal mind
            <o:p></o:p></p>
          <p class="MsoNormal"> <o:p></o:p></p>
          <p class="MsoNormal">>Otherwise we have a race condition
            here where we can't determine if the reset finished the job
            or if it did just on it's own while we stopped the
            scheduler.<o:p></o:p></p>
          <p class="MsoNormal"> <o:p></o:p></p>
          <p class="MsoNormal">[ML] you are wrong : <br>
            1) if you check the fence and found it not signaled, then
            you will call hw_job_reset(), but there is still chance that
            between your check and the hw_job_reset() the
            <o:p></o:p></p>
          <p class="MsoNormal">Sched fence could signaled , isn’t it ? 
            you still cannot avoid such race condition
            <o:p></o:p></p>
          <p class="MsoNormal">2) I don’t care if the fence is signaled
            due to its own finish or because we force the hw fence
            signaled, for SR-IOV case, as long as the job exceeds
            timeout, we consider<o:p></o:p></p>
          <p class="MsoNormal">It hang. <o:p></o:p></p>
          <p class="MsoNormal">3) Even for bare-metal case, you still
            cannot sure if the fence is signaled due to its own or
            hw_fence force signal, reason is in #1)<o:p></o:p></p>
          <p class="MsoNormal"> <o:p></o:p></p>
          <p class="MsoNormal"> <o:p></o:p></p>
          <p class="MsoNormal"><span
style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D">>No,
              you are insist on a vague rules not strict, like I said,
              what is the theoretic to backend your approach that only
              check once on the in question job ? why not check again if
              not signaled ?</span><o:p></o:p></p>
          <p class="MsoNormal">>Because we have removed the
            connection between the job and the hardware fence and
            because of this the job can never signal.<o:p></o:p></p>
          <p class="MsoNormal"> <o:p></o:p></p>
          <p class="MsoNormal">[ML] like I said, before you call
            hw_job_reset(), you only check on the job once, why not
            check again and again ?  I don’t see you have a reason to
            only check once, and
            <o:p></o:p></p>
          <p class="MsoNormal">If you don’t have such reason I think you
            should not check at all.
            <o:p></o:p></p>
          <p class="MsoNormal">If you have such reason, prove me that
            only check once is good and enough.<o:p></o:p></p>
          <p class="MsoNormal">Don’t forget your approach still have
            chance to hit the race condition, and to me I don’t think
            the race condition matters that’s why I don’t even consider
            it
            <o:p></o:p></p>
          <p class="MsoNormal"> <o:p></o:p></p>
          <p class="MsoNormal"> <o:p></o:p></p>
          <p class="MsoNormal">BR Monk<o:p></o:p></p>
          <p class="MsoNormal"> <o:p></o:p></p>
          <p class="MsoNormal"><span
style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D"> </span><o:p></o:p></p>
          <p class="MsoNormal"><span
style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D"> </span><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><span
style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:windowtext">From:</span></b><span
style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:windowtext">
                  amd-gfx [<a moz-do-not-send="true"
                    href="mailto:amd-gfx-bounces@lists.freedesktop.org">mailto:amd-gfx-bounces@lists.freedesktop.org</a>]
                  <b>On Behalf Of </b>Christian König<br>
                  <b>Sent:</b> Wednesday, May 10, 2017 6:26 PM<br>
                  <b>To:</b> Liu, Monk <a moz-do-not-send="true"
                    href="mailto:Monk.Liu@amd.com"><Monk.Liu@amd.com></a>;
                  Koenig, Christian
                  <a moz-do-not-send="true"
                    href="mailto:Christian.Koenig@amd.com"><Christian.Koenig@amd.com></a>;
                  <a moz-do-not-send="true"
                    href="mailto:amd-gfx@lists.freedesktop.org">
                    amd-gfx@lists.freedesktop.org</a><br>
                  <b>Subject:</b> Re: [PATCH 4/4]
                  drm/amdgpu/SRIOV:implement guilty job TDR (V2)</span><o:p></o:p></p>
            </div>
          </div>
          <p class="MsoNormal"> <o:p></o:p></p>
          <div>
            <p class="MsoNormal">Am 10.05.2017 um 12:05 schrieb Liu,
              Monk:<o:p></o:p></p>
          </div>
          <blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
            <p class="MsoNormal"
              style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span
                style="color:#1F497D">[</span>ML] yes, but we cannot
              guarantee the job is 100% really hang when entering
              gpu_reset(), we can only trust our amdgpu_job_timeout as a
              deadline for each job.<o:p></o:p></p>
            <p class="MsoNormal"
              style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">You
              approach that check the fence first before charge it as
              guilty/hang is incorrect looks to me because why you not
              check it twice, triple, and even more loops ?
              <o:p></o:p></p>
            <p class="MsoNormal">Because the job can't signal any more
              after calling amd_sched_hw_job_reset().<o:p></o:p></p>
            <p class="MsoNormal"><span
style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D"> </span><o:p></o:p></p>
            <p class="MsoNormal"><span
style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D">[ML]
                No … that’s where I think your approach is vague:</span><o:p></o:p></p>
            <p class="MsoNormal"><span
style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D">1)
                see that you check after scheduler stopped, see if job
                signaled, my question is if the job is not signaled
                (like most usual case)</span><o:p></o:p></p>
            <p class="MsoNormal"><span
style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D">Why
                you not check it again and again ?  maybe the second
                time you will find it signaled …</span><o:p></o:p></p>
          </blockquote>
          <p class="MsoNormal"><br>
            Checking a second time is pointless since it can't signal
            any more after calling amd_sched_hw_job_reset().<br>
            <br>
            <br>
            <br>
            <o:p></o:p></p>
          <blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
            <p class="MsoNormal"><span
style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D">My
                point is the checking here is meaningless, we already
                have timedout for the guard.</span><o:p></o:p></p>
          </blockquote>
          <p class="MsoNormal">No, the timeout is pretty meaningless.
            It's just the trigger that we need to do something.<br>
            <br>
            But to determine what to do we first need to stop the
            scheduler, remove the hardware fence and THEN check the
            current status.<br>
            <br>
            Otherwise we have a race condition here where we can't
            determine if the reset finished the job or if it did just on
            it's own while we stopped the scheduler.<br>
            <br>
            <br>
            <br>
            <o:p></o:p></p>
          <blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
            <p class="MsoNormal"><span
style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D">2)
                And even it signaled after entering gpu_reset(), it will
                automatically done like normal cases, that’s good. Why
                remove those callback instead ?</span><o:p></o:p></p>
          </blockquote>
          <p class="MsoNormal">No, that's absolutely not good. We don't
            know if it's the hardware which results in the job being
            signaled or our reset code.<br>
            <br>
            <br>
            <br>
            <o:p></o:p></p>
          <blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
            <p class="MsoNormal"><br>
              <br>
              <br>
              <o:p></o:p></p>
            <blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
              <p class="MsoNormal"
                style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">So
                I refuse to check if @job is just signaled in gpu_reset,
                because this action is vague (and no one can guarantee
                the job won’t signal during gpu_reset, we should not
                argue on this event …), I prefer clean and restrict
                rules.<o:p></o:p></p>
            </blockquote>
            <p class="MsoNormal">Yeah, completely agree that we need to
              have struct rules for that. That's why I insists on doing
              this :)<o:p></o:p></p>
            <p class="MsoNormal"><span
style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D"> </span><o:p></o:p></p>
            <p class="MsoNormal"><span
style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D">No,
                you are insist on a vague rules not strict, like I said,
                what is the theoretic to backend your approach that only
                check once on the in question job ? why not check again
                if not signaled ?</span><o:p></o:p></p>
          </blockquote>
          <p class="MsoNormal">Because we have removed the connection
            between the job and the hardware fence and because of this
            the job can never signal.<br>
            <br>
            Regards,<br>
            Christian.<br>
            <br>
            <br>
            <br>
            <o:p></o:p></p>
          <blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
            <p class="MsoNormal"><span
style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D">I
                don’t agree this approach is clean and strict. You are
                abuse timedout parameter.</span><o:p></o:p></p>
            <p class="MsoNormal"><br>
              <br>
              See I just want to avoid problems for the case that the
              job signaled while we stop the scheduler (because stopping
              the scheduler actually can take a moment).<br>
              <br>
              Because when this happened the scheduler could already
              have pushed the next job to the hardware and then we abort
              it with the GPU reset and might create more problems than
              we solve.<o:p></o:p></p>
            <p class="MsoNormal"><br>
              <br>
              <br>
              <br>
              <br>
              <o:p></o:p></p>
            <blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
              <p class="MsoNormal"
                style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">[ML]
                I don’t see my approach will have chance to fence twice…
                on the contrast I think my approach is more clear: no
                matter the in question job finally signaled or not, I
                just kick it out from mirror-list<o:p></o:p></p>
              <p class="MsoNormal">Without remove the callback from hw
                fence, that way even it really signaled during the
                gpu_reset() period the logic is still perfect and its
                sched fence will act like usual …<o:p></o:p></p>
            </blockquote>
            <p class="MsoNormal">We want to set an error code on the job
              before signaling it don't we? So we need to be sure how
              and when the job is signaled as finished.<br>
              <br>
              I mean letting it signal when we force the hardware fence
              to complete will work as well, but I still think that this
              isn't as clean as signaling it manually.<br>
              <br>
              Please also see the helper function the Intel guys
              introduced drm_fence_set_error(), we will run into a
              BUG_ON if we can't guarantee the order of execution here.<br>
              <br>
              Regards,<br>
              Christian.<br>
              <br>
              Am 10.05.2017 um 06:00 schrieb Liu, Monk:<o:p></o:p></p>
            <blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
              <p class="MsoNormal">Christian, <o:p></o:p></p>
              <p class="MsoNormal"> <o:p></o:p></p>
              <p class="MsoNormal">Looks like we need more discuss with
                it…<o:p></o:p></p>
              <p class="MsoNormal"> <o:p></o:p></p>
              <p class="MsoNormal">Here is your approach:<o:p></o:p></p>
              <p class="MsoNormal">1. Stop the scheduler from feeding
                more jobs to the hardware when a jobs completes.  //this
                is where I agree with you<br>
                <br>
                2. Then call hw_job_reset to remove the connection
                between job and hardware fence.<br>
                <br>
                3. Test if job is now completed. It is entirely possible
                that the job completed while we started the work to
                reset the hardware.<br>
                <br>
                Removing the connection between the hardware fence and
                the job is the deadline, if the job completes after that
                it is lost.<br>
                <br>
                4. Check the karma and kick out the job if we found it
                guilty.<br>
                <br>
                5. Get the whole stuff working again, e.g. reset the
                hardware, restart the scheduler etc...<o:p></o:p></p>
              <p class="MsoNormal"> <o:p></o:p></p>
              <p class="MsoNormal"><b><i>[ML]: One thing I agree to
                    change with your way: in gpu_reset() we should first
                    stop the in question ring’s scheduler (not the all)
                    before kick out the guilty job.</i></b><o:p></o:p></p>
              <p class="MsoNormal"><span
style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D"> </span><o:p></o:p></p>
              <p class="MsoNormal"><span
style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D"> </span><o:p></o:p></p>
              <p class="MsoNormal"><span
style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D">></span>
                Indeed, but I still think that this is a bad approach
                cause we then reset the hardware without a good reason.<o:p></o:p></p>
              <p class="MsoNormal"> <o:p></o:p></p>
              <p class="MsoNormal">[ML] yes, but we cannot guarantee the
                job is 100% really hang when entering gpu_reset(), we
                can only trust our amdgpu_job_timeout as a deadline for
                each job.<o:p></o:p></p>
              <p class="MsoNormal">You approach that check the fence
                first before charge it as guilty/hang is incorrect looks
                to me because why you not check it twice, triple, and
                even more loops ?
                <o:p></o:p></p>
              <p class="MsoNormal"> <o:p></o:p></p>
              <p class="MsoNormal">You check it one time and you found
                it just signaled that’s great and lucky(really lucky…),
                But what if it didn’t signaled (like most usual case) ,
                why not check it again and again ? do you have a
                theoretic to support on how much time you need to check
                before finally consider it hang ? No I don’t think you
                have so please just cut this unnecessary checking, we
                already use amdgpu_job_timeout to give the deadline of
                each job.<o:p></o:p></p>
              <p class="MsoNormal"> <o:p></o:p></p>
              <p class="MsoNormal">So I refuse to check if @job is just
                signaled in gpu_reset, because this action is vague (and
                no one can guarantee the job won’t signal during
                gpu_reset, we should not argue on this event …), I
                prefer clean and restrict rules.<o:p></o:p></p>
              <p class="MsoNormal"><span
style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D"> </span><o:p></o:p></p>
              <p class="MsoNormal"><span
style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D"> </span><o:p></o:p></p>
              <p class="MsoNormal">>Force completion is not so much
                of the issue, but rather in which order you do things.<br>
                <br>
                >See the original code first stops the scheduler and
                removes the connection between hardware fence and job in
                an atomic manner. And THEN forces the hardware fence to
                complete.<br>
                <br>
                >This way we could be sure that nothing happened in
                parallel, e.g. that we don't try to signal the fence
                twice or something like that.<o:p></o:p></p>
              <p class="MsoNormal"> <o:p></o:p></p>
              <p class="MsoNormal">[ML] I don’t see my approach will
                have chance to fence twice… on the contrast I think my
                approach is more clear: no matter the in question job
                finally signaled or not, I just kick it out from
                mirror-list<o:p></o:p></p>
              <p class="MsoNormal">Without remove the callback from hw
                fence, that way even it really signaled during the
                gpu_reset() period the logic is still perfect and its
                sched fence will act like usual …<o:p></o:p></p>
              <p class="MsoNormal"> <o:p></o:p></p>
              <p class="MsoNormal">Please point out where or how my
                approach will go wrong like “e.g. that we don't try to
                signal the fence twice or something like that.”,
                otherwise I cannot be persuaded and fix my way …<o:p></o:p></p>
              <p class="MsoNormal"> <o:p></o:p></p>
              <p class="MsoNormal"> <o:p></o:p></p>
              <p class="MsoNormal">At last. I run the TDR test and it
                ends up with Hypervisor side error, the guest side is
                all perfect, here is what I ran:<o:p></o:p></p>
              <p class="MsoNormal">The vk_example and vulkan CTS test
                under MCBP case, we have all kinds of hang on compute
                ring, without TDR this test won’t suffer for 5 seconds,
                and with TDR although MCBP is buggy now but we can
                <o:p></o:p></p>
              <p class="MsoNormal">Finish this test (of cause test
                result is mismatch due to MCBP issue), and there are
                tongs of job_timed_out in dmesg, but guest driver didn’t
                have any error report.  I was also surprised this behave
                really stable …<o:p></o:p></p>
              <p class="MsoNormal"> <o:p></o:p></p>
              <p class="MsoNormal">The second test the using “watch” to
                trigger a gpu hang (bad command stream) every 2 seconds,
                with amdgpu_job_timeout also set to 2seconds, I can run
                it till hypervisor side hit VF FLR error, and guest side<o:p></o:p></p>
              <p class="MsoNormal">Still runs perfectly and nothing
                wrong happened, with hw fence seq number I can tell
                there are 3000 loops of TDR finished before Hypervisor
                hit error.<o:p></o:p></p>
              <p class="MsoNormal"> <o:p></o:p></p>
              <p class="MsoNormal">BR Monk<o:p></o:p></p>
              <p class="MsoNormal"><span
style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D"> </span><o:p></o:p></p>
              <p class="MsoNormal"><span
style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D"> </span><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><span
style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:windowtext">From:</span></b><span
style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:windowtext">
                      Koenig, Christian
                      <br>
                      <b>Sent:</b> Tuesday, May 09, 2017 8:52 PM<br>
                      <b>To:</b> Liu, Monk <a moz-do-not-send="true"
                        href="mailto:Monk.Liu@amd.com"><Monk.Liu@amd.com></a>;
                      Christian König
                      <a moz-do-not-send="true"
                        href="mailto:deathsimple@vodafone.de"><deathsimple@vodafone.de></a>;
                      <a moz-do-not-send="true"
                        href="mailto:amd-gfx@lists.freedesktop.org">
                        amd-gfx@lists.freedesktop.org</a><br>
                      <b>Subject:</b> Re: [PATCH 4/4]
                      drm/amdgpu/SRIOV:implement guilty job TDR (V2)</span><o:p></o:p></p>
                </div>
              </div>
              <p class="MsoNormal"> <o:p></o:p></p>
              <div>
                <blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
                  <p class="MsoNormal"
                    style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">[ML]
                    if the job complete, the job’s sched fence callback
                    will take this spin_lock and remove itself from
                    mirror_list, so we are still safe to call
                    amd_sched_job_kickout(), and it will do nothing if
                    so<o:p></o:p></p>
                </blockquote>
                <p class="MsoNormal">Indeed, but I still think that this
                  is a bad approach cause we then reset the hardware
                  without a good reason.<br>
                  <br>
                  <br>
                  <br>
                  <br>
                  <br>
                  <o:p></o:p></p>
                <blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
                  <p class="MsoNormal">Besides, original logic also
                    force complete the hw fence, and it works well …
                    <o:p></o:p></p>
                </blockquote>
                <p class="MsoNormal">Force completion is not so much of
                  the issue, but rather in which order you do things.<br>
                  <br>
                  See the original code first stops the scheduler and
                  removes the connection between hardware fence and job
                  in an atomic manner. And THEN forces the hardware
                  fence to complete.<br>
                  <br>
                  This way we could be sure that nothing happened in
                  parallel, e.g. that we don't try to signal the fence
                  twice or something like that.<br>
                  <br>
                  <br>
                  <br>
                  <br>
                  <br>
                  <o:p></o:p></p>
                <blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
                  <p class="MsoNormal">State like “You are missing that
                    it is entirely possible that the job will complete
                    while we are trying to kick it out.”<o:p></o:p></p>
                </blockquote>
                <p class="MsoNormal">Sorry I should have been more
                  clear.<br>
                  <br>
                  <br>
                  <br>
                  <br>
                  <br>
                  <o:p></o:p></p>
                <blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
                  <p class="MsoNormal">Is not a good reason to reject my
                    approach, because that is okay if the job just
                    completed …
                    <o:p></o:p></p>
                </blockquote>
                <p class="MsoNormal">We usually try to take a defensive
                  approach, so stopping everything, removing the
                  hardware fence connection and then explicitly kicking
                  out the job in question sounds much better than doing
                  it implicitly with the hardware fence completion.<br>
                  <br>
                  Even when this works (which I'm still not sure of)
                  that is a really awkward and hard to understand
                  approach.<br>
                  <br>
                  Regards,<br>
                  Christian.<br>
                  <br>
                  Am 09.05.2017 um 13:58 schrieb Liu, Monk:<o:p></o:p></p>
              </div>
              <blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
                <p class="MsoNormal"><span
style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D"> </span><o:p></o:p></p>
                <p class="MsoNormal">You are missing that it is entirely
                  possible that the job will complete while we are
                  trying to kick it out.<o:p></o:p></p>
                <p class="MsoNormal"> <o:p></o:p></p>
                <p class="MsoNormal">[ML] if the job complete, the job’s
                  sched fence callback will take this spin_lock and
                  remove itself from mirror_list, so we are still safe
                  to call amd_sched_job_kickout(), and it will do
                  nothing if so<o:p></o:p></p>
                <p class="MsoNormal">Please go through the whole steps
                  again,<o:p></o:p></p>
                <p class="MsoNormal"> <o:p></o:p></p>
                <p class="MsoNormal">Besides, original logic also force
                  complete the hw fence, and it works well …
                  <o:p></o:p></p>
                <p class="MsoNormal"> <o:p></o:p></p>
                <p class="MsoNormal">I don’t see the solid reason why
                  you insist on your approach, please go through the
                  steps again  and give me the details about where is
                  incorrect than I can fix it
                  <o:p></o:p></p>
                <p class="MsoNormal"> <o:p></o:p></p>
                <p class="MsoNormal">State like “You are missing that it
                  is entirely possible that the job will complete while
                  we are trying to kick it out.” Is not a good reason to
                  reject my approach, because that is okay if the job
                  just completed …<o:p></o:p></p>
                <p class="MsoNormal"> <o:p></o:p></p>
                <p class="MsoNormal">BR Monk<br>
                  <br>
                  <br>
                  <br>
                  <br>
                  <br>
                  <o:p></o:p></p>
                <p class="MsoNormal"><span
style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D"> </span><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><span
style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:windowtext">From:</span></b><span
style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:windowtext">
                        Koenig, Christian
                        <br>
                        <b>Sent:</b> Tuesday, May 09, 2017 3:49 PM<br>
                        <b>To:</b> Liu, Monk <a moz-do-not-send="true"
                          href="mailto:Monk.Liu@amd.com"><Monk.Liu@amd.com></a>;
                        Christian König
                        <a moz-do-not-send="true"
                          href="mailto:deathsimple@vodafone.de"><deathsimple@vodafone.de></a>;
                        <a moz-do-not-send="true"
                          href="mailto:amd-gfx@lists.freedesktop.org">
                          amd-gfx@lists.freedesktop.org</a><br>
                        <b>Subject:</b> Re: [PATCH 4/4]
                        drm/amdgpu/SRIOV:implement guilty job TDR (V2)</span><o:p></o:p></p>
                  </div>
                </div>
                <p class="MsoNormal"> <o:p></o:p></p>
                <div>
                  <blockquote
                    style="margin-top:5.0pt;margin-bottom:5.0pt">
                    <p class="MsoNormal"><span style="font-size:10.0pt">[ML]
                        Really not necessary, we have spin_lock to
                        protect the mirror-list, nothing will be messed
                        up ...</span><o:p></o:p></p>
                  </blockquote>
                  <p class="MsoNormal">You are missing that it is
                    entirely possible that the job will complete while
                    we are trying to kick it out.<br>
                    <br>
                    <br>
                    <br>
                    <br>
                    <br>
                    <br>
                    <o:p></o:p></p>
                  <blockquote
                    style="margin-top:5.0pt;margin-bottom:5.0pt">
                    <p class="MsoNormal"><span style="font-size:10.0pt">[ML]
                        why don't touch hardware fence at all ?  the
                        original/bare-metal gpu reset also signal all
                        ring's hardware fence first, I just follow the
                        original logic ...<br>
                        Scheduler fence will be auto signaled after hw
                        fence signaled, any problem with that ? what's
                        the concern ?</span><o:p></o:p></p>
                  </blockquote>
                  <p class="MsoNormal">The hardware runs async to the
                    CPU which tries to reset it, so we need to be
                    careful in which order things are done.<br>
                    <br>
                    <br>
                    <br>
                    <br>
                    <br>
                    <br>
                    <o:p></o:p></p>
                  <blockquote
                    style="margin-top:5.0pt;margin-bottom:5.0pt">
                    <p class="MsoNormal"><span style="font-size:10.0pt">[ML]
                        No I don't think so, the kickout must be prior
                        to the hw_job_reset, otherwise the scheduler
                        fence callback will be removed and you need
                        manually install it later , which is not
                        correct:<br>
                        For the guity job, we just kick it out before
                        job reset, in job_reset we only reset other
                        innocent jobs( and unbind the scheduler fence
                        callback for them), after hw fence<br>
                        Forcely set to drv_seq, all hw fence are
                        signaled (this is the way of original logic, I
                        didn't change that).  When go to
                        sched_recovery(), it will recover all innocent
                        job and hook<br>
                        The scheduler fence with new hw fence.  That way
                        only the guilty job is dropped forever.</span><o:p></o:p></p>
                  </blockquote>
                  <p class="MsoNormal">Again same problem here.<br>
                    <br>
                    To be absolutely sure that everything works as
                    expected we need to do it in the following order:<br>
                    <br>
                    1. Stop the scheduler from feeding more jobs to the
                    hardware when a jobs completes.<br>
                    <br>
                    2. Then call hw_job_reset to remove the connection
                    between job and hardware fence.<br>
                    <br>
                    3. Test if job is now completed. It is entirely
                    possible that the job completed while we started the
                    work to reset the hardware.<br>
                    <br>
                    Removing the connection between the hardware fence
                    and the job is the deadline, if the job completes
                    after that it is lost.<br>
                    <br>
                    4. Check the karma and kick out the job if we found
                    it guilty.<br>
                    <br>
                    5. Get the whole stuff working again, e.g. reset the
                    hardware, restart the scheduler etc...<br>
                    <br>
                    Regards,<br>
                    Christian.<br>
                    <br>
                    Am 09.05.2017 um 04:45 schrieb Liu, Monk:<o:p></o:p></p>
                </div>
                <blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
                  <div>
                    <p class="MsoNormal" style="margin-bottom:12.0pt"><span
                        style="font-size:10.0pt">>  
                        <br>
                        > -     /* block scheduler */<br>
                        > -     for (i = 0; i < AMDGPU_MAX_RINGS;
                        ++i) {<br>
                        > -             ring = adev->rings[i];<br>
                        > +     /* we start from the ring trigger GPU
                        hang */<br>
                        > +     j = job ? job->ring->idx : 0;<br>
                        > +<br>
                        > +     if (job)<br>
                        > +             if
                        (amd_sched_invalidate_job(&job->base,
                        amdgpu_job_hang_limit))<br>
                        > +                    
                        amd_sched_job_kickout(&job->base);<br>
                        <br>
                        Well that looks like the wrong order to me. We
                        should probably stop the scheduler before trying
                        to mess anything with the job.<br>
                        <br>
                        [ML] Really not necessary, we have spin_lock to
                        protect the mirror-list, nothing will be messed
                        up ...<br>
                        <br>
                        <br>
                        >   <br>
                        > +void
                        amdgpu_fence_driver_force_completion_ring(struct
                        amdgpu_ring<br>
                        > +*ring) {<br>
                        > +     if (ring)<br>
                        > +             amdgpu_fence_write(ring,
                        ring->fence_drv.sync_seq); }<br>
                        > +<br>
                        <br>
                        The coding style is completely off.<br>
                        <br>
                        [ML] I don't know why at email side it looks
                        wrong coding style, but I'm sure it is correct
                        at my side, check here:<br>
                        void
                        amdgpu_fence_driver_force_completion_ring(struct
                        amdgpu_ring *ring)<br>
                        {<br>
                                if (ring)<br>
                                        amdgpu_fence_write(ring,
                        ring->fence_drv.sync_seq);<br>
                        }<br>
                        <br>
                        Additional to that I don't think that this is a
                        good idea. We should probably rather just signal
                        all scheduler fences instead and don't touch the
                        hardware fence at all.<br>
                        <br>
                        [ML] why don't touch hardware fence at all ? 
                        the original/bare-metal gpu reset also signal
                        all ring's hardware fence first, I just follow
                        the original logic ...<br>
                        Scheduler fence will be auto signaled after hw
                        fence signaled, any problem with that ? what's
                        the concern ?<br>
                        <br>
                        <br>
                        > -     for (i = 0; i < AMDGPU_MAX_RINGS;
                        ++i) {<br>
                        > -             struct amdgpu_ring *ring =
                        adev->rings[i];<br>
                        > +     for (i = j; i < j +
                        AMDGPU_MAX_RINGS; ++i) {<br>
                        > +             ring = adev->rings[i %
                        AMDGPU_MAX_RINGS];<br>
                        >                if (!ring ||
                        !ring->sched.thread)<br>
                        >                        continue;<br>
                        >   <br>
                        > +             if (job && j != i) {<br>
                        > +                    
                        kthread_unpark(ring->sched.thread);<br>
                        > +                     continue;<br>
                        > +             }<br>
                        > +<br>
                        <br>
                        Please split up that patch a bit further. E.g.
                        first the handling to only hw_job_reset the ring
                        in question, then the kickout handling.<br>
                        <br>
                        [ML] No I don't think so, the kickout must be
                        prior to the hw_job_reset, otherwise the
                        scheduler fence callback will be removed and you
                        need manually install it later , which is not
                        correct:<br>
                        For the guity job, we just kick it out before
                        job reset, in job_reset we only reset other
                        innocent jobs( and unbind the scheduler fence
                        callback for them), after hw fence<br>
                        Forcely set to drv_seq, all hw fence are
                        signaled (this is the way of original logic, I
                        didn't change that).  When go to
                        sched_recovery(), it will recover all innocent
                        job and hook<br>
                        The scheduler fence with new hw fence.  That way
                        only the guilty job is dropped forever.<br>
                        <br>
                        -----Original Message-----<br>
                        From: Christian König [<a moz-do-not-send="true"
                          href="mailto:deathsimple@vodafone.de">mailto:deathsimple@vodafone.de</a>]
                        <br>
                        Sent: Monday, May 08, 2017 9:12 PM<br>
                        To: Liu, Monk <a moz-do-not-send="true"
                          href="mailto:Monk.Liu@amd.com"><Monk.Liu@amd.com></a>;
                        <a moz-do-not-send="true"
                          href="mailto:amd-gfx@lists.freedesktop.org">
                          amd-gfx@lists.freedesktop.org</a><br>
                        Cc: Koenig, Christian <a moz-do-not-send="true"
                          href="mailto:Christian.Koenig@amd.com"><Christian.Koenig@amd.com></a><br>
                        Subject: Re: [PATCH 4/4]
                        drm/amdgpu/SRIOV:implement guilty job TDR (V2)<br>
                        <br>
                        Am 08.05.2017 um 09:01 schrieb Liu, Monk:<br>
                        > @Christian<br>
                        ><br>
                        > This one is changed to guilty job scheme
                        accordingly with your <br>
                        > response<br>
                        ><br>
                        > BR Monk<br>
                        ><br>
                        > -----Original Message-----<br>
                        > From: Monk Liu [<a moz-do-not-send="true"
                          href="mailto:Monk.Liu@amd.com">mailto:Monk.Liu@amd.com</a>]<br>
                        > Sent: Monday, May 08, 2017 3:00 PM<br>
                        > To: <a moz-do-not-send="true"
                          href="mailto:amd-gfx@lists.freedesktop.org">amd-gfx@lists.freedesktop.org</a><br>
                        > Cc: Liu, Monk <a moz-do-not-send="true"
                          href="mailto:Monk.Liu@amd.com"><Monk.Liu@amd.com></a><br>
                        > Subject: [PATCH] drm/amdgpu/SRIOV:implement
                        guilty job TDR (V2)<br>
                        ><br>
                        > 1,TDR will kickout guilty job if it hang
                        exceed the threshold of the given one from
                        kernel paramter "job_hang_limit", that way a bad
                        command stream will not infinitly cause GPU
                        hang.<br>
                        ><br>
                        > by default this threshold is 1 so a job
                        will be kicked out after it hang.<br>
                        ><br>
                        > 2,if a job timeout TDR routine will not
                        reset all sched/ring, instead if will only reset
                        on the givn one which is indicated by @job of
                        amdgpu_sriov_gpu_reset, that way we don't need
                        to reset and recover each sched/ring if we
                        already know which job cause GPU hang.<br>
                        ><br>
                        > 3,unblock sriov_gpu_reset for AI family.<br>
                        > 4,don't init entity for KIQ<br>
                        ><br>
                        > TODO:<br>
                        > when a job is considered as guilty, we
                        should mark some flag in its fence status flag,
                        and let UMD side aware that this fence signaling
                        is not due to job complete but job hang.<br>
                        ><br>
                        > Change-Id:
                        I7b89c19a3de93249db570d0a80522176b1525a09<br>
                        > Signed-off-by: Monk Liu <a
                          moz-do-not-send="true"
                          href="mailto:Monk.Liu@amd.com"><Monk.Liu@amd.com></a><br>
                        > ---<br>
                        >  
                        drivers/gpu/drm/amd/amdgpu/amdgpu.h           | 
                        1 +<br>
                        >  
                        drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c       | 
                        4 +++<br>
                        >  
                        drivers/gpu/drm/amd/amdgpu/amdgpu_device.c    |
                        36 ++++++++++++++++++++-------<br>
                        >  
                        drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c       | 
                        4 +++<br>
                        >  
                        drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c     | 
                        6 +++++<br>
                        >  
                        drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h      | 
                        1 +<br>
                        >  
                        drivers/gpu/drm/amd/scheduler/gpu_scheduler.c |
                        11 +++++++- 
                        drivers/gpu/drm/amd/scheduler/gpu_scheduler.h | 
                        7 ++++++<br>
                        >   8 files changed, 60 insertions(+), 10
                        deletions(-)<br>
                        ><br>
                        > diff --git
                        a/drivers/gpu/drm/amd/amdgpu/amdgpu.h <br>
                        > b/drivers/gpu/drm/amd/amdgpu/amdgpu.h<br>
                        > index 90a69bf..93bcea2 100644<br>
                        > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h<br>
                        > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h<br>
                        > @@ -111,6 +111,7 @@ extern int
                        amdgpu_prim_buf_per_se;  extern int <br>
                        > amdgpu_pos_buf_per_se;  extern int
                        amdgpu_cntl_sb_buf_per_se;  extern <br>
                        > int amdgpu_param_buf_per_se;<br>
                        > +extern int amdgpu_job_hang_limit;<br>
                        >   <br>
                        >   #define
                        AMDGPU_DEFAULT_GTT_SIZE_MB          3072ULL /*
                        3GB by default */<br>
                        >   #define
                        AMDGPU_WAIT_IDLE_TIMEOUT_IN_MS              3000<br>
                        > diff --git
                        a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c <br>
                        > b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c<br>
                        > index b4bbbb3..23afc58 100644<br>
                        > ---
                        a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c<br>
                        > +++
                        b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c<br>
                        > @@ -52,6 +52,10 @@ static int
                        amdgpu_ctx_init(struct amdgpu_device *adev,
                        struct amdgpu_ctx *ctx)<br>
                        >                struct amd_sched_rq *rq;<br>
                        >   <br>
                        >                rq =
                        &ring->sched.sched_rq[AMD_SCHED_PRIORITY_NORMAL];<br>
                        > +<br>
                        > +             if (ring ==
                        &adev->gfx.kiq.ring)<br>
                        > +                     continue;<br>
                        > +<br>
                        <br>
                        That looks like a bug fix and should probably go
                        into a separate patch.<br>
                        <br>
                        >                r =
                        amd_sched_entity_init(&ring->sched,
                        &ctx->rings[i].entity,<br>
                        >                                         
                        rq, amdgpu_sched_jobs);<br>
                        >                if (r)<br>
                        > diff --git
                        a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c <br>
                        >
                        b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c<br>
                        > index 0e5f314..f3990fe 100644<br>
                        > ---
                        a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c<br>
                        > +++
                        b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c<br>
                        > @@ -2537,7 +2537,7 @@ static int
                        amdgpu_recover_vram_from_shadow(struct
                        amdgpu_device *adev,<br>
                        >    */<br>
                        >   int amdgpu_sriov_gpu_reset(struct
                        amdgpu_device *adev, struct amdgpu_job *job)  {<br>
                        > -     int i, r = 0;<br>
                        > +     int i, j, r = 0;<br>
                        >        int resched;<br>
                        >        struct amdgpu_bo *bo, *tmp;<br>
                        >        struct amdgpu_ring *ring;<br>
                        > @@ -2550,19 +2550,30 @@ int
                        amdgpu_sriov_gpu_reset(struct amdgpu_device
                        *adev, struct amdgpu_job *job)<br>
                        >        /* block TTM */<br>
                        >        resched =
                        ttm_bo_lock_delayed_workqueue(&adev->mman.bdev);<br>
                        >   <br>
                        > -     /* block scheduler */<br>
                        > -     for (i = 0; i < AMDGPU_MAX_RINGS;
                        ++i) {<br>
                        > -             ring = adev->rings[i];<br>
                        > +     /* we start from the ring trigger GPU
                        hang */<br>
                        > +     j = job ? job->ring->idx : 0;<br>
                        > +<br>
                        > +     if (job)<br>
                        > +             if
                        (amd_sched_invalidate_job(&job->base,
                        amdgpu_job_hang_limit))<br>
                        > +                    
                        amd_sched_job_kickout(&job->base);<br>
                        <br>
                        Well that looks like the wrong order to me. We
                        should probably stop the scheduler before trying
                        to mess anything with the job.<br>
                        <br>
                        >   <br>
                        > +     /* block scheduler */<br>
                        > +     for (i = j; i < j +
                        AMDGPU_MAX_RINGS; ++i) {<br>
                        > +             ring = adev->rings[i %
                        AMDGPU_MAX_RINGS];<br>
                        >                if (!ring ||
                        !ring->sched.thread)<br>
                        >                        continue;<br>
                        >   <br>
                        >               
                        kthread_park(ring->sched.thread);<br>
                        > +<br>
                        > +             if (job && j != i)<br>
                        > +                     continue;<br>
                        > +<br>
                        > +             /* only do job_reset on the
                        hang ring if @job not NULL */<br>
                        >               
                        amd_sched_hw_job_reset(&ring->sched);<br>
                        > -     }<br>
                        >   <br>
                        > -     /* after all hw jobs are reset, hw
                        fence is meaningless, so force_completion */<br>
                        > -    
                        amdgpu_fence_driver_force_completion(adev);<br>
                        > +             /* after all hw jobs are
                        reset, hw fence is meaningless, so
                        force_completion */<br>
                        > +            
                        amdgpu_fence_driver_force_completion_ring(ring);<br>
                        > +     }<br>
                        >   <br>
                        >        /* request to take full control of
                        GPU before re-initialization  */<br>
                        >        if (job)<br>
                        > @@ -2615,11 +2626,16 @@ int
                        amdgpu_sriov_gpu_reset(struct amdgpu_device
                        *adev, struct amdgpu_job *job)<br>
                        >        }<br>
                        >        fence_put(fence);<br>
                        >   <br>
                        > -     for (i = 0; i < AMDGPU_MAX_RINGS;
                        ++i) {<br>
                        > -             struct amdgpu_ring *ring =
                        adev->rings[i];<br>
                        > +     for (i = j; i < j +
                        AMDGPU_MAX_RINGS; ++i) {<br>
                        > +             ring = adev->rings[i %
                        AMDGPU_MAX_RINGS];<br>
                        >                if (!ring ||
                        !ring->sched.thread)<br>
                        >                        continue;<br>
                        >   <br>
                        > +             if (job && j != i) {<br>
                        > +                    
                        kthread_unpark(ring->sched.thread);<br>
                        > +                     continue;<br>
                        > +             }<br>
                        > +<br>
                        <br>
                        Please split up that patch a bit further. E.g.
                        first the handling to only hw_job_reset the ring
                        in question, then the kickout handling.<br>
                        <br>
                        >               
                        amd_sched_job_recovery(&ring->sched);<br>
                        >               
                        kthread_unpark(ring->sched.thread);<br>
                        >        }<br>
                        > @@ -2629,6 +2645,8 @@ int
                        amdgpu_sriov_gpu_reset(struct amdgpu_device
                        *adev, struct amdgpu_job *job)<br>
                        >        if (r) {<br>
                        >                /* bad news, how to tell it
                        to userspace ? */<br>
                        >                dev_info(adev->dev, "GPU
                        reset failed\n");<br>
                        > +     } else {<br>
                        > +             dev_info(adev->dev, "GPU
                        reset successed!\n");<br>
                        >        }<br>
                        >   <br>
                        >        adev->gfx.in_reset = false;<br>
                        > diff --git
                        a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c <br>
                        > b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c<br>
                        > index 416908a..fd3691a8 100644<br>
                        > ---
                        a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c<br>
                        > +++
                        b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c<br>
                        > @@ -112,6 +112,7 @@ int
                        amdgpu_prim_buf_per_se = 0;  int <br>
                        > amdgpu_pos_buf_per_se = 0;  int
                        amdgpu_cntl_sb_buf_per_se = 0;  int <br>
                        > amdgpu_param_buf_per_se = 0;<br>
                        > +int amdgpu_job_hang_limit = 0;<br>
                        >   <br>
                        >   MODULE_PARM_DESC(vramlimit, "Restrict
                        VRAM for testing, in <br>
                        > megabytes");  module_param_named(vramlimit,
                        amdgpu_vram_limit, int, <br>
                        > 0600); @@ -237,6 +238,9 @@
                        module_param_named(cntl_sb_buf_per_se, <br>
                        > amdgpu_cntl_sb_buf_per_se, int, 0444);  <br>
                        > MODULE_PARM_DESC(param_buf_per_se, "the
                        size of Off-Chip Pramater <br>
                        > Cache per Shader Engine (default depending
                        on gfx)");  <br>
                        > module_param_named(param_buf_per_se,
                        amdgpu_param_buf_per_se, int, <br>
                        > 0444);<br>
                        >   <br>
                        > +MODULE_PARM_DESC(job_hang_limit, "how much
                        time allow a job hang and <br>
                        > +not drop it (default 0)");
                        module_param_named(job_hang_limit,<br>
                        > +amdgpu_job_hang_limit, int ,0444);<br>
                        > +<br>
                        >   <br>
                        >   static const struct pci_device_id
                        pciidlist[] = {  #ifdef  <br>
                        > CONFIG_DRM_AMDGPU_SI diff --git <br>
                        > a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
                        <br>
                        > b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c<br>
                        > index d7523d1..8de3bd3 100644<br>
                        > ---
                        a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c<br>
                        > +++
                        b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c<br>
                        > @@ -541,6 +541,12 @@ void
                        amdgpu_fence_driver_force_completion(struct
                        amdgpu_device *adev)<br>
                        >        }<br>
                        >   }<br>
                        >   <br>
                        > +void
                        amdgpu_fence_driver_force_completion_ring(struct
                        amdgpu_ring<br>
                        > +*ring) {<br>
                        > +     if (ring)<br>
                        > +             amdgpu_fence_write(ring,
                        ring->fence_drv.sync_seq); }<br>
                        > +<br>
                        <br>
                        The coding style is completely off.<br>
                        <br>
                        Additional to that I don't think that this is a
                        good idea. We should probably rather just signal
                        all scheduler fences instead and don't touch the
                        hardware fence at all.<br>
                        <br>
                        >   /*<br>
                        >    * Common fence implementation<br>
                        >    */<br>
                        > diff --git
                        a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h <br>
                        > b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h<br>
                        > index 981ef08..03e88c6 100644<br>
                        > ---
                        a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h<br>
                        > +++
                        b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h<br>
                        > @@ -76,6 +76,7 @@ struct
                        amdgpu_fence_driver {  int <br>
                        > amdgpu_fence_driver_init(struct
                        amdgpu_device *adev);  void <br>
                        > amdgpu_fence_driver_fini(struct
                        amdgpu_device *adev);  void <br>
                        > amdgpu_fence_driver_force_completion(struct
                        amdgpu_device *adev);<br>
                        > +void
                        amdgpu_fence_driver_force_completion_ring(struct
                        amdgpu_ring <br>
                        > +*ring);<br>
                        >   <br>
                        >   int amdgpu_fence_driver_init_ring(struct
                        amdgpu_ring *ring,<br>
                        >                                  unsigned
                        num_hw_submission);<br>
                        > diff --git
                        a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c
                        <br>
                        >
                        b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c<br>
                        > index 6f4e31f..4e97e6d 100644<br>
                        > ---
                        a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c<br>
                        > +++
                        b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c<br>
                        > @@ -390,9 +390,18 @@ void
                        amd_sched_hw_job_reset(struct amd_gpu_scheduler
                        *sched)<br>
                        >                                         
                        &s_job->s_fence->cb)) {<br>
                        >                       
                        fence_put(s_job->s_fence->parent);<br>
                        >                       
                        s_job->s_fence->parent = NULL;<br>
                        > +                    
                        atomic_dec(&sched->hw_rq_count);<br>
                        >                }<br>
                        >        }<br>
                        > -    
                        atomic_set(&sched->hw_rq_count, 0);<br>
                        > +    
                        spin_unlock(&sched->job_list_lock);<br>
                        > +}<br>
                        > +<br>
                        > +void amd_sched_job_kickout(struct
                        amd_sched_job *s_job) {<br>
                        > +     struct amd_gpu_scheduler *sched =
                        s_job->sched;<br>
                        > +<br>
                        > +    
                        spin_lock(&sched->job_list_lock);<br>
                        > +     list_del_init(&s_job->node);<br>
                        >       
                        spin_unlock(&sched->job_list_lock);<br>
                        >   }<br>
                        >   <br>
                        > diff --git
                        a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h
                        <br>
                        >
                        b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h<br>
                        > index 8cb41d3..59694f3 100644<br>
                        > ---
                        a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h<br>
                        > +++
                        b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h<br>
                        > @@ -81,6 +81,7 @@ struct amd_sched_job {<br>
                        >        struct list_head               
                        node;<br>
                        >        struct delayed_work            
                        work_tdr;<br>
                        >        uint64_t                        id;<br>
                        > +     atomic_t karma;<br>
                        >   };<br>
                        >   <br>
                        >   extern const struct fence_ops
                        amd_sched_fence_ops_scheduled; @@ -96,6 +97,11
                        @@ static inline struct amd_sched_fence
                        *to_amd_sched_fence(struct fence *f)<br>
                        >        return NULL;<br>
                        >   }<br>
                        >   <br>
                        > +static inline bool
                        amd_sched_invalidate_job(struct amd_sched_job <br>
                        > +*s_job, int threshold) {<br>
                        > +     return (s_job &&
                        atomic_inc_return(&s_job->karma) >
                        threshold); }<br>
                        > +<br>
                        <br>
                        Again coding style is completely off.<br>
                        <br>
                        Christian.<br>
                        <br>
                        >   /**<br>
                        >    * Define the backend operations called
                        by the scheduler,<br>
                        >    * these functions should be implemented
                        in driver side @@ -158,4 +164,5 @@ int
                        amd_sched_job_init(struct amd_sched_job *job,<br>
                        >                       void *owner);<br>
                        >   void amd_sched_hw_job_reset(struct
                        amd_gpu_scheduler *sched);  void <br>
                        > amd_sched_job_recovery(struct
                        amd_gpu_scheduler *sched);<br>
                        > +void amd_sched_job_kickout(struct
                        amd_sched_job *s_job);<br>
                        >   #endif<br>
                        > --<br>
                        > 2.7.4<br>
                        ><br>
                        >
                        _______________________________________________<br>
                        > amd-gfx mailing list<br>
                        > <a moz-do-not-send="true"
                          href="mailto:amd-gfx@lists.freedesktop.org">amd-gfx@lists.freedesktop.org</a><br>
                        > <a moz-do-not-send="true"
                          href="https://lists.freedesktop.org/mailman/listinfo/amd-gfx">https://lists.freedesktop.org/mailman/listinfo/amd-gfx</a><br>
                        <br>
                        <br>
                        <br>
                        <br>
                        <br>
                      </span><o:p></o:p></p>
                  </div>
                </blockquote>
                <p> <o:p></o:p></p>
              </blockquote>
              <p> <o:p></o:p></p>
              <p class="MsoNormal"><br>
                <br>
                <br>
                <br>
                <br>
                <o:p></o:p></p>
              <pre>_______________________________________________<o:p></o:p></pre>
              <pre>amd-gfx mailing list<o:p></o:p></pre>
              <pre><a moz-do-not-send="true" href="mailto:amd-gfx@lists.freedesktop.org">amd-gfx@lists.freedesktop.org</a><o:p></o:p></pre>
              <pre><a moz-do-not-send="true" href="https://lists.freedesktop.org/mailman/listinfo/amd-gfx">https://lists.freedesktop.org/mailman/listinfo/amd-gfx</a><o:p></o:p></pre>
            </blockquote>
            <p> <o:p></o:p></p>
          </blockquote>
          <p> <o:p></o:p></p>
        </blockquote>
        <p><o:p> </o:p></p>
      </div>
      <br>
      <fieldset class="mimeAttachmentHeader"></fieldset>
      <br>
      <pre wrap="">_______________________________________________
amd-gfx mailing list
<a class="moz-txt-link-abbreviated" href="mailto:amd-gfx@lists.freedesktop.org">amd-gfx@lists.freedesktop.org</a>
<a class="moz-txt-link-freetext" href="https://lists.freedesktop.org/mailman/listinfo/amd-gfx">https://lists.freedesktop.org/mailman/listinfo/amd-gfx</a>
</pre>
    </blockquote>
    <p><br>
    </p>
  </body>
</html>