<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 17.03.2017 um 03:35 schrieb Zhou,
David(ChunMing):<br>
</div>
<blockquote
cite="mid:MWHPR1201MB0206DC9ED4550D01BE31DBAAB4390@MWHPR1201MB0206.namprd12.prod.outlook.com"
type="cite">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="Generator" content="Microsoft Exchange Server">
<!-- converted from text -->
<style><!-- .EmailQuote { margin-left: 1pt; padding-left: 4pt; border-left: #800000 2px solid; } --></style>
<font size="2"><span style="font-size:10pt;">
<div class="PlainText">Hi Christian, Andres,<br>
<br>
I understand your mean, especially high priority queue from
Andres is for VR, which is liking an engine to himself, but
our scheduler is a generic thing, which is used by multiple
case.<br>
From scheduler perspective, scheduling policy is popular,
e.g. CPU scheduler, it provides different time piece for
different priority queue, high priority has long time to
execute, low has short time, but everyone has the chance to
run, just sooner or later.<br>
<br>
</div>
</span></font></blockquote>
<br>
As Michel pointed out even the CPU scheduler allows for a process to
dominate everyone else when you have the right privileges and is
useful for the use case.<br>
<br>
<blockquote
cite="mid:MWHPR1201MB0206DC9ED4550D01BE31DBAAB4390@MWHPR1201MB0206.namprd12.prod.outlook.com"
type="cite"><font size="2"><span style="font-size:10pt;">
<div class="PlainText">
The proposal I send is same goal for gpu scheduler, we don't
desire to one engine is occupied by one person, high
priority can have more chance to run, low priority has less,
but low priority must to have. The ratio is power of 2 in
current implementation, we can adjust it for more different
situations if necessary. Even we can put a parameter to be
adusted convenience. <br>
For Andres case, he can pass a big time piece to it so that
the efficiency is same with occupied previous.<br>
</div>
</span></font></blockquote>
<br>
We perfectly understand what your patch is doing, it's just not that
we want this behavior.<br>
<br>
When there is high priority work available it should completely
dominate everything else.<br>
<br>
Regards,<br>
Christian.<br>
<br>
<blockquote
cite="mid:MWHPR1201MB0206DC9ED4550D01BE31DBAAB4390@MWHPR1201MB0206.namprd12.prod.outlook.com"
type="cite"><font size="2"><span style="font-size:10pt;">
<div class="PlainText">
<br>
Regards,<br>
David Zhou<br>
<br>
<br>
-----Original Message-----<br>
From: Andres Rodriguez [<a moz-do-not-send="true"
href="mailto:andresx7@gmail.com">mailto:andresx7@gmail.com</a>]
<br>
Sent: Friday, March 17, 2017 12:32 AM<br>
To: Christian König <a class="moz-txt-link-rfc2396E" href="mailto:deathsimple@vodafone.de"><deathsimple@vodafone.de></a>; Zhou,
David(ChunMing) <a class="moz-txt-link-rfc2396E" href="mailto:David1.Zhou@amd.com"><David1.Zhou@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>
Subject: Re: [PATCH 2/2] drm/amd/sched: add schuduling
policy<br>
<br>
<br>
<br>
On 2017-03-16 12:01 PM, Christian König wrote:<br>
> Am 16.03.2017 um 16:31 schrieb Andres Rodriguez:<br>
>><br>
>><br>
>> On 2017-03-16 11:13 AM, Andres Rodriguez wrote:<br>
>>><br>
>>><br>
>>> On 2017-03-16 05:15 AM, zhoucm1 wrote:<br>
>>>><br>
>>>><br>
>>>> On 2017年03月16日 17:10, Christian König
wrote:<br>
>>>>> Am 16.03.2017 um 10:00 schrieb Chunming
Zhou:<br>
>>>>>> if high priority rq is full, then
process with low priority could <br>
>>>>>> be starve.<br>
>>>>>> Add policy for this problem, the
high proiority can ahead of next <br>
>>>>>> priority queue, the ratio is 2 : 1.<br>
>>>>>><br>
>>>>>> Change-Id:
I58f4a6b9cdce8689b18dd8e83dd6e2cf5f99d5fb<br>
>>>>>> Signed-off-by: Chunming Zhou
<a class="moz-txt-link-rfc2396E" href="mailto:David1.Zhou@amd.com"><David1.Zhou@amd.com></a><br>
>>>>><br>
>>>>> Well, the idea behind the high priority
queues is to actually <br>
>>>>> starve the low priority queues to a
certain amount.<br>
>>>>><br>
>>>>> At least for the kernel queue that is
really desired.<br>
>>>> Yes, agree, but we certainly don't want
low priority queue is <br>
>>>> totally dead, which doesn't have chance to
run if high priority <br>
>>>> queue is always full and busy.<br>
>>>> If without Andres changes, it doesn't
matter. But after Andres <br>
>>>> changes upstream, we need scheduling
policy.<br>
>>>><br>
>>>> Regards,<br>
>>>> David Zhou<br>
>>><br>
>>> Hey David,<br>
>>><br>
>>> The desired behavior is actually starvation.
This is why allocating <br>
>>> a high priority context is locked behind root
privileges at the moment.<br>
><br>
> Thanks for the quick response, and yes that's what I
was expecting as <br>
> requirement for that feature as well.<br>
><br>
>>><br>
>>> High priority work includes many different
features intended for the <br>
>>> safety of the user wearing the headset. These
include:<br>
>>> - stopping the user from tripping over
furniture<br>
>>> - preventing motion sickness<br>
>>><br>
>>> We cannot compromise these safety features in
order to run <br>
>>> non-critical tasks.<br>
>>><br>
>>> The current approach also has the disadvantage
of heavily <br>
>>> interleaving work. This is going to have two
undesired side effects. <br>
>>> First, there will be a performance overhead
from having the queue <br>
>>> context switch so often.<br>
>>><br>
>>> Second, this approach improves concurrency of
work in a ring with <br>
>>> mixed priority work, but actually decreases
overall system <br>
>>> concurrency. When a ring's HW queue has any
high priority work <br>
>>> committed, the whole ring will be executing at
high priority. So <br>
>>> interleaving the work will result in extending
the time a ring <br>
>>> spends in high priority mode. This effectively
extends time that a <br>
>>> ring might spend with CU's reserved which will
have a performance impact on other rings.<br>
>>><br>
>>> The best approach here is to make sure we don't
map high priority <br>
>>> work and regular priority work to the same
ring. This is why the LRU <br>
>>> policy for userspace ring ids to kernel ring
ids was introduced. <br>
>>> This policy provides the guarantee as a side
effect.<br>
>><br>
>> Wanted to correct myself here. The LRU policy
doesn't actually <br>
>> provide a guarantee. It approximates it.<br>
><br>
> What David is perfectly right with is that this has the
potential for <br>
> undesired side effects.<br>
><br>
> But I completely agree that deadline or fair queue
scheduling is <br>
> tricky to implement even when it is desired.<br>
><br>
> So letting a submission dominate all other is perfectly
ok for me as <br>
> long as it is limited to a certain set of processes
somehow.<br>
><br>
> Christian.<br>
<br>
I also wanted to comment that I think policies for the
gpu_scheduler are something interesting to explore. Not just
at single ring level, but also policies that tie all the
gpu_schedulers for a single ASIC together. Currently they
all operate independently, but technically they share the
underlying HW so there is some resource aliasing.<br>
<br>
There has been a lot of experimentation on this area in the
VR world by other OS vendors. Enhancing the policies
provided by the SPI through SW can have some pretty great
benefits. Although because of restrictions these kind of
changes are only activated for certain HMDs.<br>
<br>
I think we have a good opportunity here to make the linux
version of VR better for all HMDs, and not just the ones
associated with the OS vendor.<br>
<br>
Regards,<br>
Andres<br>
<br>
><br>
>><br>
>> Regards,<br>
>> Andres<br>
>><br>
>>> But further work there could be<br>
>>> useful to actually check context priorities
when doing the ring mapping.<br>
>>><br>
>>> By placing work on different rings, we let the
hardware actually <br>
>>> dispatch work according to wave parameters like
VGPR usage, etc. <br>
>>> Trying to deduce all this information in the
GPU scheduler will get <br>
>>> very complicated.<br>
>>><br>
>>> This is NAK'd by me.<br>
>>><br>
>>> Regards,<br>
>>> Andres<br>
>>><br>
>>><br>
>>>>><br>
>>>>> Christian.<br>
>>>>><br>
>>>>>> ---<br>
>>>>>>
drivers/gpu/drm/amd/scheduler/gpu_scheduler.c | 26<br>
>>>>>> +++++++++++++++++++++++---<br>
>>>>>>
drivers/gpu/drm/amd/scheduler/gpu_scheduler.h | 2 ++<br>
>>>>>> 2 files changed, 25
insertions(+), 3 deletions(-)<br>
>>>>>><br>
>>>>>> diff --git
a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c<br>
>>>>>>
b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c<br>
>>>>>> index 0f439dd..4637b6f 100644<br>
>>>>>> ---
a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c<br>
>>>>>> +++
b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c<br>
>>>>>> @@ -35,11 +35,16 @@<br>
>>>>>> static void
amd_sched_process_job(struct fence *f, struct <br>
>>>>>> fence_cb *cb);<br>
>>>>>> /* Initialize a given run queue
struct */ -static void <br>
>>>>>> amd_sched_rq_init(struct
amd_sched_rq *rq)<br>
>>>>>> +static void
amd_sched_rq_init(struct amd_gpu_scheduler *sched, enum<br>
>>>>>> +
amd_sched_priority pri)<br>
>>>>>> {<br>
>>>>>> + struct amd_sched_rq *rq =
&sched->sched_rq[pri];<br>
>>>>>> +<br>
>>>>>>
spin_lock_init(&rq->lock);<br>
>>>>>>
INIT_LIST_HEAD(&rq->entities);<br>
>>>>>> rq->current_entity = NULL;<br>
>>>>>> + rq->wait_base = pri * 2;<br>
>>>>>> + rq->wait =
rq->wait_base;<br>
>>>>>> }<br>
>>>>>> static void
amd_sched_rq_add_entity(struct amd_sched_rq *rq, <br>
>>>>>> @@ -494,17 +499,32 @@ static void
amd_sched_wakeup(struct <br>
>>>>>> amd_gpu_scheduler *sched)<br>
>>>>>> {<br>
>>>>>> struct amd_sched_entity
*entity;<br>
>>>>>> int i;<br>
>>>>>> + bool skip;<br>
>>>>>> if
(!amd_sched_ready(sched))<br>
>>>>>> return NULL;<br>
>>>>>> +retry:<br>
>>>>>> + skip = false;<br>
>>>>>> /* Kernel run queue has
higher priority than normal run queue*/<br>
>>>>>> for (i =
AMD_SCHED_PRIORITY_MAX - 1; i >= <br>
>>>>>> AMD_SCHED_PRIORITY_MIN; i--) {<br>
>>>>>> + if ((i >
AMD_SCHED_PRIORITY_MIN) &&<br>
>>>>>> + (sched->sched_rq[i
- 1].wait >=<br>
>>>>>> sched->sched_rq[i].wait_base)) {<br>
>>>>>> + sched->sched_rq[i -
1].wait = sched->sched_rq[i -<br>
>>>>>> 1].wait_base;<br>
>>>>>> + skip = true;<br>
>>>>>> + continue;<br>
>>>>>> + }<br>
>>>>>> entity =
amd_sched_rq_select_entity(&sched->sched_rq[i]);<br>
>>>>>> - if (entity)<br>
>>>>>> + if (entity) {<br>
>>>>>> + if (i >
AMD_SCHED_PRIORITY_MIN)<br>
>>>>>> +
sched->sched_rq[i - 1].wait++;<br>
>>>>>> break;<br>
>>>>>> + }<br>
>>>>>> }<br>
>>>>>> + if (!entity && skip)<br>
>>>>>> + goto retry;<br>
>>>>>> +<br>
>>>>>> return entity;<br>
>>>>>> }<br>
>>>>>> @@ -608,7 +628,7 @@ int
amd_sched_init(struct amd_gpu_scheduler <br>
>>>>>> *sched,<br>
>>>>>> sched->name = name;<br>
>>>>>> sched->timeout = timeout;<br>
>>>>>> for (i =
AMD_SCHED_PRIORITY_MIN; i < <br>
>>>>>> AMD_SCHED_PRIORITY_MAX;<br>
>>>>>> i++)<br>
>>>>>> -
amd_sched_rq_init(&sched->sched_rq[i]);<br>
>>>>>> + amd_sched_rq_init(sched,
i);<br>
>>>>>>
init_waitqueue_head(&sched->wake_up_worker);<br>
>>>>>>
init_waitqueue_head(&sched->job_scheduled);<br>
>>>>>> diff --git
a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h<br>
>>>>>>
b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h<br>
>>>>>> index 99f0240..4caed30 100644<br>
>>>>>> ---
a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h<br>
>>>>>> +++
b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h<br>
>>>>>> @@ -64,6 +64,8 @@ struct
amd_sched_rq {<br>
>>>>>> spinlock_t lock;<br>
>>>>>> struct list_head entities;<br>
>>>>>> struct amd_sched_entity
*current_entity;<br>
>>>>>> + int wait_base;<br>
>>>>>> + int wait;<br>
>>>>>> };<br>
>>>>>> struct amd_sched_fence {<br>
>>>>><br>
>>>>><br>
>>>><br>
>> _______________________________________________<br>
>> amd-gfx mailing list<br>
>> <a class="moz-txt-link-abbreviated" 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>
</div>
</span></font>
</blockquote>
<p><br>
</p>
</body>
</html>