Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

agent: refactor agent to be more useful #1855

Merged
merged 7 commits into from
Oct 24, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/arch/xtensa/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ int slave_core_init(struct sof *sof)
platform_interrupt_init();

trace_point(TRACE_BOOT_PLATFORM_SCHED);
scheduler_init_edf(sof);
scheduler_init_edf();
scheduler_init_ll(platform_timer_domain);
scheduler_init_ll(platform_dma_domain);

Expand Down
7 changes: 0 additions & 7 deletions src/audio/kpb.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
#include <sof/debug/panic.h>
#include <sof/drivers/ipc.h>
#include <sof/drivers/timer.h>
#include <sof/lib/agent.h>
#include <sof/lib/alloc.h>
#include <sof/lib/clk.h>
#include <sof/lib/notifier.h>
Expand Down Expand Up @@ -987,9 +986,6 @@ static void kpb_init_draining(struct comp_dev *dev, struct kpb_client *cli)
/* Pause selector copy. */
kpb->sel_sink->sink->state = COMP_STATE_PAUSED;

/* Disable system agent during draining */
tlauda marked this conversation as resolved.
Show resolved Hide resolved
sa_disable();

/* Schedule draining task */
schedule_task(&kpb->draining_task, 0, 0);
}
Expand Down Expand Up @@ -1129,9 +1125,6 @@ static enum task_state kpb_draining_task(void *arg)
*/
(void)(draining_time_end - draining_time_start);

/* Enable system agent back */
sa_enable();

return SOF_TASK_STATE_COMPLETED;
}

Expand Down
11 changes: 4 additions & 7 deletions src/include/sof/lib/agent.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,12 @@ struct sof;

/* simple agent */
struct sa {
uint64_t last_idle; /* time of last idle */
uint64_t ticks;
uint64_t last_check; /* time of last activity checking */
uint64_t panic_timeout; /* threshold of panic */
uint64_t warn_timeout; /* threshold of warning */
struct task work;
bool is_active;
};

void sa_enter_idle(struct sof *sof);
void sa_init(struct sof *sof);
void sa_disable(void);
void sa_enable(void);
void sa_init(struct sof *sof, uint64_t timeout);

#endif /* __SOF_LIB_AGENT_H__ */
4 changes: 1 addition & 3 deletions src/include/sof/schedule/edf_schedule.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@
#include <user/trace.h>
#include <stdint.h>

struct sof;

/* schedule tracing */
#define trace_edf_sch(format, ...) \
trace_event(TRACE_CLASS_EDF, format, ##__VA_ARGS__)
Expand All @@ -35,6 +33,6 @@ struct edf_task_pdata {
void *ctx;
};

int scheduler_init_edf(struct sof *sof);
int scheduler_init_edf(void);

#endif /* __SOF_SCHEDULE_EDF_SCHEDULE_H__ */
2 changes: 1 addition & 1 deletion src/include/sof/schedule/task.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ enum task_state task_main_master_core(void *data);

enum task_state task_main_slave_core(void *data);

void task_main_init(struct sof *sof);
void task_main_init(void);

void task_main_free(void);

Expand Down
73 changes: 32 additions & 41 deletions src/lib/agent.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@

/*
* System Agent - Simple FW Monitor that can notify host drivers in the event
* of any FW errors. The SA assumes that each core will enter the idle state
* from time to time (within a period of PLATFORM_IDLE_TIME). If the core does
* not enter the idle loop through looping forever or scheduling some work
* continuously then the SA will emit trace and panic().
* of any FW errors. The SA checks if the DSP is still responsive and verifies
* the stability of the system by checking time elapsed between every timer
* tick. If the core exceeds the threshold by over 5% then the SA will emit
* error trace. However if it will be exceeded by over 100% the panic will be
* called.
*/

#include <sof/drivers/timer.h>
Expand All @@ -32,70 +33,60 @@
trace_event_atomic(TRACE_CLASS_SA, __e, ##__VA_ARGS__)
#define trace_sa_value(__e, ...) \
trace_value_atomic(__e, ##__VA_ARGS__)
#define trace_sa_error(__e, ...) \
trace_error(TRACE_CLASS_SA, __e, ##__VA_ARGS__)

struct sa *sa;

/*
* Notify the SA that we are about to enter idle state (WFI).
*/
void sa_enter_idle(struct sof *sof)
{
struct sa *sa = sof->sa;

sa->last_idle = platform_timer_get(platform_timer);
}

static enum task_state validate(void *data)
{
struct sa *sa = data;
uint64_t current;
uint64_t delta;

current = platform_timer_get(platform_timer);
delta = current - sa->last_idle;

/* were we last idle longer than timeout */
delta = current - sa->last_check;

if (delta > sa->ticks && sa->is_active) {
trace_sa("validate(), idle longer than timeout, delta = %u",
delta);
/* panic timeout */
if (delta > sa->panic_timeout)
panic(SOF_IPC_PANIC_IDLE);
}

/* warning timeout */
if (delta > sa->warn_timeout)
trace_sa_error("validate(), ll drift detected, delta = "
"%u", delta);

/* update last_check to current */
sa->last_check = current;

return SOF_TASK_STATE_RESCHEDULE;
}

void sa_init(struct sof *sof)
void sa_init(struct sof *sof, uint64_t timeout)
{
uint64_t ticks;

trace_sa("sa_init()");
trace_sa("sa_init(), timeout = %u", timeout);

sa = rzalloc(RZONE_SYS, SOF_MEM_CAPS_RAM, sizeof(*sa));
sof->sa = sa;

/* set default tick timeout */
sa->ticks = clock_ms_to_ticks(PLATFORM_DEFAULT_CLOCK, 1) *
PLATFORM_IDLE_TIME / 1000;
/* set default timeouts */
ticks = clock_ms_to_ticks(PLATFORM_DEFAULT_CLOCK, 1) * timeout / 1000;

trace_sa("sa_init(), sa->ticks = %u", sa->ticks);
/* TODO: change values after minimal drifts will be assured */
sa->panic_timeout = 2 * ticks; /* 100% delay */
sa->warn_timeout = ticks + ticks / 20; /* 5% delay */

/* set lst idle time to now to give time for boot completion */
sa->last_idle = platform_timer_get(platform_timer) + sa->ticks;
sa->is_active = true;
trace_sa("sa_init(), ticks = %u, sa->warn_timeout = %u, "
"sa->panic_timeout = %u", ticks, sa->warn_timeout,
sa->panic_timeout);

schedule_task_init(&sa->work, SOF_SCHEDULE_LL_TIMER, SOF_TASK_PRI_HIGH,
validate, NULL, sa, 0, 0);

schedule_task(&sa->work, PLATFORM_IDLE_TIME, PLATFORM_IDLE_TIME);
}
schedule_task(&sa->work, 0, timeout);

void sa_disable(void)
{
sa->is_active = false;
}

void sa_enable(void)
{
sa->is_active = true;
sa->last_idle = platform_timer_get(platform_timer);
/* set last check time to now to give time for boot completion */
sa->last_check = platform_timer_get(platform_timer);
}
9 changes: 9 additions & 0 deletions src/platform/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -236,4 +236,13 @@ config FIRMWARE_SHORT_NAME
3-characters long firmware identifer
used by rimage to decide how to build final binary

config SYSTICK_PERIOD
int "System tick period in microseconds"
default 1000
help
Defines platform system tick period. It is used to
drive timer based low latency scheduler and also
as a timeout check value for system agent.
Value should be provided in microseconds.

endmenu
8 changes: 0 additions & 8 deletions src/platform/apollolake/include/platform/platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,6 @@ struct timer;
#define PLATFORM_MAX_CHANNELS 8
#define PLATFORM_MAX_STREAMS 16

/*! \def PLATFORM_LL_DEFAULT_TIMEOUT
* \brief low latency scheduler default timeout in microseconds
*/
#define PLATFORM_LL_DEFAULT_TIMEOUT 1000

/* local buffer size of DMA tracing */
#define DMA_TRACE_LOCAL_SIZE (HOST_PAGE_SIZE * 2)

Expand All @@ -76,9 +71,6 @@ struct timer;
*/
#define DMA_TRACE_RESCHEDULE_TIME 500

/* DSP should be idle in this time frame */
#define PLATFORM_IDLE_TIME 750000

/* platform has DMA memory type */
#define PLATFORM_MEM_HAS_DMA

Expand Down
8 changes: 0 additions & 8 deletions src/platform/baytrail/include/platform/platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,6 @@ struct timer;
*/
#define PLATFORM_DEFAULT_CLOCK CLK_SSP

/*! \def PLATFORM_LL_DEFAULT_TIMEOUT
* \brief low latency scheduler default timeout in microseconds
*/
#define PLATFORM_LL_DEFAULT_TIMEOUT 1000

/* IPC Interrupt */
#define PLATFORM_IPC_INTERRUPT IRQ_NUM_EXT_IA
#define PLATFORM_IPC_INTERRUPT_NAME NULL
Expand Down Expand Up @@ -76,9 +71,6 @@ struct timer;
*/
#define DMA_TRACE_RESCHEDULE_TIME 100

/* DSP should be idle in this time frame */
#define PLATFORM_IDLE_TIME 750000

/* DSP default delay in cycles */
#define PLATFORM_DEFAULT_DELAY 12

Expand Down
6 changes: 3 additions & 3 deletions src/platform/baytrail/platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -190,12 +190,12 @@ int platform_init(struct sof *sof)
clock_init();

trace_point(TRACE_BOOT_PLATFORM_SCHED);
scheduler_init_edf(sof);
scheduler_init_edf();

/* init low latency timer domain and scheduler */
platform_timer_domain =
timer_domain_init(platform_timer, PLATFORM_DEFAULT_CLOCK,
PLATFORM_LL_DEFAULT_TIMEOUT);
CONFIG_SYSTICK_PERIOD);
scheduler_init_ll(platform_timer_domain);

/* init low latency multi channel DW-DMA domain and scheduler */
Expand All @@ -208,7 +208,7 @@ int platform_init(struct sof *sof)

/* init the system agent */
trace_point(TRACE_BOOT_PLATFORM_AGENT);
sa_init(sof);
sa_init(sof, CONFIG_SYSTICK_PERIOD);

/* Set CPU to default frequency for booting */
trace_point(TRACE_BOOT_PLATFORM_CPU_FREQ);
Expand Down
8 changes: 0 additions & 8 deletions src/platform/cannonlake/include/platform/platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,6 @@ struct timer;
*/
#define PLATFORM_DEFAULT_CLOCK CLK_SSP

/*! \def PLATFORM_LL_DEFAULT_TIMEOUT
* \brief low latency scheduler default timeout in microseconds
*/
#define PLATFORM_LL_DEFAULT_TIMEOUT 1000

#define MAX_GPDMA_COUNT 2

/* Host page size */
Expand Down Expand Up @@ -79,9 +74,6 @@ struct timer;
*/
#define DMA_TRACE_RESCHEDULE_TIME 500

/* DSP should be idle in this time frame */
#define PLATFORM_IDLE_TIME 750000

/* DSP default delay in cycles */
#define PLATFORM_DEFAULT_DELAY 12

Expand Down
8 changes: 0 additions & 8 deletions src/platform/haswell/include/platform/platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,6 @@ struct timer;
*/
#define PLATFORM_DEFAULT_CLOCK CLK_CPU(0)

/*! \def PLATFORM_LL_DEFAULT_TIMEOUT
* \brief low latency scheduler default timeout in microseconds
*/
#define PLATFORM_LL_DEFAULT_TIMEOUT 1000

/* IPC Interrupt */
#define PLATFORM_IPC_INTERRUPT IRQ_NUM_EXT_IA
#define PLATFORM_IPC_INTERRUPT_NAME NULL
Expand Down Expand Up @@ -72,9 +67,6 @@ struct timer;
*/
#define DMA_TRACE_RESCHEDULE_TIME 100

/* DSP should be idle in this time frame */
#define PLATFORM_IDLE_TIME 750000

/* DSP default delay in cycles */
#define PLATFORM_DEFAULT_DELAY 12

Expand Down
6 changes: 3 additions & 3 deletions src/platform/haswell/platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -178,12 +178,12 @@ int platform_init(struct sof *sof)
clock_init();

trace_point(TRACE_BOOT_PLATFORM_SCHED);
scheduler_init_edf(sof);
scheduler_init_edf();

/* init low latency timer domain and scheduler */
platform_timer_domain =
timer_domain_init(platform_timer, PLATFORM_DEFAULT_CLOCK,
PLATFORM_LL_DEFAULT_TIMEOUT);
CONFIG_SYSTICK_PERIOD);
scheduler_init_ll(platform_timer_domain);

/* init low latency multi channel DW-DMA domain and scheduler */
Expand All @@ -196,7 +196,7 @@ int platform_init(struct sof *sof)

/* init the system agent */
trace_point(TRACE_BOOT_PLATFORM_AGENT);
sa_init(sof);
sa_init(sof, CONFIG_SYSTICK_PERIOD);

/* Set CPU to default frequency for booting */
trace_point(TRACE_BOOT_PLATFORM_CPU_FREQ);
Expand Down
8 changes: 0 additions & 8 deletions src/platform/icelake/include/platform/platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,6 @@ struct timer;
*/
#define PLATFORM_DEFAULT_CLOCK CLK_SSP

/*! \def PLATFORM_LL_DEFAULT_TIMEOUT
* \brief low latency scheduler default timeout in microseconds
*/
#define PLATFORM_LL_DEFAULT_TIMEOUT 1000

#define MAX_GPDMA_COUNT 2

/* Host page size */
Expand Down Expand Up @@ -79,9 +74,6 @@ struct timer;
*/
#define DMA_TRACE_RESCHEDULE_TIME 500

/* DSP should be idle in this time frame */
#define PLATFORM_IDLE_TIME 750000

/* DSP default delay in cycles */
#define PLATFORM_DEFAULT_DELAY 12

Expand Down
8 changes: 0 additions & 8 deletions src/platform/imx8/include/platform/platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,6 @@ struct timer;
#define PLATFORM_DEFAULT_CLOCK CLK_CPU(0)
#define LPSRAM_SIZE 16384

/*! \def PLATFORM_LL_DEFAULT_TIMEOUT
* \brief low latency scheduler default timeout in microseconds
*/
#define PLATFORM_LL_DEFAULT_TIMEOUT 1000

/* IPC Interrupt */
#define PLATFORM_IPC_INTERRUPT IRQ_NUM_MU
#define PLATFORM_IPC_INTERRUPT_NAME NULL
Expand Down Expand Up @@ -61,9 +56,6 @@ struct timer;
*/
#define DMA_TRACE_RESCHEDULE_TIME 100

/* DSP should be idle in this time frame */
#define PLATFORM_IDLE_TIME 750000

/* DSP default delay in cycles */
#define PLATFORM_DEFAULT_DELAY 12

Expand Down
Loading