<html>
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
</head>
<body text="#000000" bgcolor="#FFFFFF">
<div class="moz-cite-prefix">
<blockquote type="cite">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() ?</blockquote>
Because stopping all the scheduler threads takes a moment and it
is entirely possible that the job finishes within that time.<br>
<br>
<blockquote type="cite">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 class="MsoNormal">Sched fence could signaled , isn’t it ?
you still cannot avoid such race condition
</p>
</blockquote>
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>
<blockquote type="cite">
<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>
</blockquote>
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:<br>
</div>
<blockquote
cite="mid:DM5PR12MB161019F5CF787CE172E64D8084EC0@DM5PR12MB1610.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-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"><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"><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">
amd-gfx [<a class="moz-txt-link-freetext" 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 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>
<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>
<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>
<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>
<o:p></o:p></p>
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<p class="MsoNormal"><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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
</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>
<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>
</div>
</blockquote>
<p><br>
</p>
</body>
</html>