Skip to content

ll_scheduler: add check for newly calculated timeout - #1768

Merged
tlauda merged 3 commits into
thesofproject:masterfrom
mrajwa:scheduler_dev
Sep 20, 2019
Merged

tlauda merged 3 commits into
thesofproject:masterfrom
mrajwa:scheduler_dev

Conversation

@mrajwa

@mrajwa mrajwa commented Aug 27, 2019 •

Copy link
Copy Markdown
Contributor

This patch checks if newly created timeout is not a
past time. Such issue will lead to dead scheduler.

NOTE! This will cause slight delay in tasks start time (only when previous tasks took more than scheduled period). I keep investigating what potential consequences it can cause, as for now it looks pretty safe.

Signed-off-by: Marcin Rajwa marcin.rajwa@linux.intel.com

Comment thread src/schedule/ll_schedule.c Outdated
Comment thread src/include/sof/schedule/ll_schedule.h Outdated

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On what platform have you measured it? I think it will differ for different XTAL frequencies.

@mrajwa mrajwa Aug 28, 2019 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The amount of ticks should be clock frequency independant. However it is DSP and compiler dependant so I related it with compiler used. I think it should be moved to arch directory as it is valid only for xtensa ISA

@tlauda

tlauda commented Aug 28, 2019

Copy link
Copy Markdown
Contributor

Now the question is, why do we have such situation?
What exact tasks have caused this?

@mrajwa

mrajwa commented Aug 28, 2019 •

Copy link
Copy Markdown
Contributor Author

Now the question is, why do we have such situation?
What exact tasks have caused this?

When FW is configured with more advanced, rich topologies like KWD + separate playback/capture or both then on startup and pause/suspend case we sporadically observe such issue. The reproduction rate is about 10%. To be clear 10% of cold starts or pause/suspends result in this issue, any other time we are safe.

Comment thread src/schedule/ll_schedule.c Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More efficient to do this

temp_ticks = ll_get_timer(queue) + TICKS_NEEDED_;
if (ticks < temp_ticks)
    ticks = temp_ticks;

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes sure, there is no need to call ll_get_timer() twice.

@tlauda

tlauda commented Sep 1, 2019

Copy link
Copy Markdown
Contributor

@mrajwa We need to add some kind of error message to notify late task processing and also we need to rootcause the reason of such behavior. Based on your description there is still no reason why timer interrupt is handled so late.

@mrajwa

mrajwa commented Sep 2, 2019

Copy link
Copy Markdown
Contributor Author

@tlauda, sure, I am OK with error message.
As for what exactly delayed the timer IRQ - as I presumed, it is IPC request which takes more than a millisecond to finish. This IPC request is params() method of KPB component. In that method KPB does a lot - allocated 2,1 second history buffer, clears it, searches for sinks, registers for notifications, initializes draining task and more. I can try to move one or two of these tasks to KPB_new() procedure however it will barely help since the allocation of history buffer alone takes 640 uS.

However this is not the only demanding IPC request. While debugging I have stumbled upon several others which takes like 400-500 uS to accomplish. So if they happen to end up on IRQ list in series before our scheduler handler like IPC_400_uS - IPC_500_uS - TIMER_IRQ we will end up with exact same situation. Although this is much much less likely.

@tlauda

tlauda commented Sep 2, 2019

Copy link
Copy Markdown
Contributor

@mrajwa IPC task is executed on lower irq level than timer scheduler, so it should be automatically preempted. We should analyze if the pipeline_params method really needs to disable global interrupts.

@mrajwa

mrajwa commented Sep 3, 2019

Copy link
Copy Markdown
Contributor Author

@tlauda, @lgirdwood PR is updated. Can we merge now?

@jajanusz
jajanusz requested a review from lgirdwood September 3, 2019 14:02
Comment thread src/include/sof/schedule/ll_schedule.h Outdated

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mrajwa @tlauda imho it should be platform/arch value

@mrajwa mrajwa Sep 5, 2019 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it will be overkill in this scenario - it's true that this value is architecture dependent (and we have it wrapped up by precompiler-architecture check) but in the same time it is dependent on scheduler implementation.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mrajwa it's platform/arch level config, lets put in all in one global place.

@tlauda

tlauda commented Sep 6, 2019

Copy link
Copy Markdown
Contributor

SOFCI TEST

@jajanusz

Copy link
Copy Markdown
Contributor

@mrajwa please split it to have irq fix and ticks workaround as separate PRs

@mrajwa

mrajwa commented Sep 10, 2019

Copy link
Copy Markdown
Contributor Author

@jajanusz it has just been opened here #1814.

@lgirdwood

Copy link
Copy Markdown
Member

@mrajwa Internal CI showing degredation in SNR for TGL ? Can you confirm the is false positive.

@mrajwa

mrajwa commented Sep 10, 2019

Copy link
Copy Markdown
Contributor Author

@lgirdwood interesting, where did you see that? Can you give me a reference so I can check? All tests already run passed fine (except pause/resume one but this is known issue)

Comment thread src/arch/xtensa/drivers/timer.c Outdated
Comment thread src/drivers/intel/baytrail/timer.c Outdated
Comment thread src/schedule/ll_schedule.c Outdated

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need to check it here. It's calculated from the current time, not last_tick.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes the argument to queue_calc_next_timeout() is current time but there is no guarantee the time returned from it will not be past time
return queue->ticks_per_msec * queue->timeout / 1000 + start;

In above statement its enough somebody sets queue->timeout to incorrect value and we may have problems.

To summarise I would keep this check here.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it's needed then please add some comments to this effect. This way other will understand why we do the check.

@tlauda

tlauda commented Sep 12, 2019

Copy link
Copy Markdown
Contributor

SOFCI TEST

Comment thread src/drivers/intel/cavs/timer.c Outdated

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function returns int and here we can have up to 64 bit value.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You suggest to return the 64 bit value which was set I assume. I was also thinking about that but the return of difference, or 0 if there is no diff would be aliggned better with other .set_timer() interfaces like for BYT platform for example. So the ABI is more a like. What do you think?

@paulstelian97 paulstelian97 Sep 12, 2019 •

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mrajwa Are we absolutely sure that the difference will fit into an "int", even in the worse cases where something will delay this code too much?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mrajwa @paulstelian97 This is what I was talking about. We can potentially have more than 32 bits here.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair point, lets make it int64_t then.

@mrajwa mrajwa Sep 12, 2019 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this scenario I also changed the return value itself to be a value written to compare register instead of a difference between requested and set ticks. Even though int64_t max value is half of what uin64_t can offer, it is still enough.

@mrajwa
mrajwa force-pushed the scheduler_dev branch 2 times, most recently from f0daed8 to ba522d5 Compare September 12, 2019 12:00
Comment thread CODEOWNERS Outdated
Comment thread src/schedule/ll_schedule.c Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it's needed then please add some comments to this effect. This way other will understand why we do the check.

Comment thread src/arch/xtensa/drivers/timer.c Outdated
@wenqingfu

Copy link
Copy Markdown

SOFCI TEST

@wenqingfu

Copy link
Copy Markdown

it looks pretty safe

massive CI failures. doesn't look safe...

@tlauda

tlauda commented Sep 17, 2019

Copy link
Copy Markdown
Contributor

@mrajwa Conflicts.

@mrajwa
mrajwa force-pushed the scheduler_dev branch 2 times, most recently from 2f86530 to 5dbb445 Compare September 17, 2019 09:34
@mrajwa

mrajwa commented Sep 18, 2019

Copy link
Copy Markdown
Contributor Author

@lgirdwood, updated is it OK for you now?

@mrajwa

mrajwa commented Sep 18, 2019

Copy link
Copy Markdown
Contributor Author

it looks pretty safe

massive CI failures. doesn't look safe...

It was due to conflicts in one file which happened in the meantime.

@lgirdwood

Copy link
Copy Markdown
Member

@mrajwa can you check and comment on the CI errors.

@wenqingfu

Copy link
Copy Markdown

Now the two CI test case failures are known issue in firmware/driver. thanks! @mrajwa @lgirdwood

@lgirdwood

Copy link
Copy Markdown
Member

@mrajwa good to merge once conflicts fixed.

This adds @tlauda and @mrajwa as codeowners of
src\scheduler directory so they will be
auto-requested for review in all changes related
to files under this directory.

Signed-off-by: Marcin Rajwa <marcin.rajwa@linux.intel.com>
This patch reworks cAVS timer_set() interface used
to write into timer's compare register.
This change takes care of ticks request which are
"past time". If such condition occur we set compare
register to current time so the latency is minimum.

Signed-off-by: Marcin Rajwa <marcin.rajwa@linux.intel.com>
This patch checks if during scheduling we were
delayed.
If such situation happens we log error message.

Signed-off-by: Marcin Rajwa <marcin.rajwa@linux.intel.com>
@tlauda
tlauda merged commit ccba8e0 into thesofproject:master Sep 20, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants