arch: We can use an independent SIG interrupt to handle async pause, which can save processing time.
Signed-off-by: hujun5 <hujun5@xiaomi.com>
This commit is contained in:
parent
ed998c08c4
commit
a8717c6453
@ -208,6 +208,34 @@ int up_cpu_paused_restore(void)
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: arm_pause_async_handler
|
||||
*
|
||||
* Description:
|
||||
* This is the handler for async pause.
|
||||
*
|
||||
* 1. It saves the current task state at the head of the current assigned
|
||||
* task list.
|
||||
* 2. It porcess g_delivertasks
|
||||
* 3. Returns from interrupt, restoring the state of the new task at the
|
||||
* head of the ready to run list.
|
||||
*
|
||||
* Input Parameters:
|
||||
* Standard interrupt handling
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero on success; a negated errno value on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int arm_pause_async_handler(int irq, void *context, void *arg)
|
||||
{
|
||||
int cpu = this_cpu();
|
||||
|
||||
nxsched_process_delivered(cpu);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: arm_pause_handler
|
||||
*
|
||||
@ -256,8 +284,6 @@ int arm_pause_handler(int irq, void *context, void *arg)
|
||||
leave_critical_section(flags);
|
||||
}
|
||||
|
||||
nxsched_process_delivered(cpu);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
@ -282,7 +308,7 @@ int arm_pause_handler(int irq, void *context, void *arg)
|
||||
|
||||
inline_function int up_cpu_pause_async(int cpu)
|
||||
{
|
||||
arm_cpu_sgi(GIC_SMP_CPUPAUSE, (1 << cpu));
|
||||
arm_cpu_sgi(GIC_SMP_CPUPAUSE_ASYNC, (1 << cpu));
|
||||
|
||||
return OK;
|
||||
}
|
||||
@ -331,7 +357,7 @@ int up_cpu_pause(int cpu)
|
||||
spin_lock(&g_cpu_wait[cpu]);
|
||||
spin_lock(&g_cpu_paused[cpu]);
|
||||
|
||||
up_cpu_pause_async(cpu);
|
||||
arm_cpu_sgi(GIC_SMP_CPUPAUSE, (1 << cpu));
|
||||
|
||||
/* Wait for the other CPU to unlock g_cpu_paused meaning that
|
||||
* it is fully paused and ready for up_cpu_resume();
|
||||
|
@ -215,6 +215,8 @@ void arm_gic0_initialize(void)
|
||||
|
||||
DEBUGVERIFY(irq_attach(GIC_SMP_CPUSTART, arm_start_handler, NULL));
|
||||
DEBUGVERIFY(irq_attach(GIC_SMP_CPUPAUSE, arm_pause_handler, NULL));
|
||||
DEBUGVERIFY(irq_attach(GIC_SMP_CPUPAUSE_ASYNC,
|
||||
arm_pause_async_handler, NULL));
|
||||
DEBUGVERIFY(irq_attach(GIC_SMP_CPUCALL,
|
||||
nxsched_smp_call_handler, NULL));
|
||||
#endif
|
||||
|
@ -619,10 +619,12 @@
|
||||
# define GIC_SMP_CPUSTART GIC_IRQ_SGI9
|
||||
# define GIC_SMP_CPUPAUSE GIC_IRQ_SGI10
|
||||
# define GIC_SMP_CPUCALL GIC_IRQ_SGI11
|
||||
# define GIC_SMP_CPUPAUSE_ASYNC GIC_IRQ_SGI12
|
||||
#else
|
||||
# define GIC_SMP_CPUSTART GIC_IRQ_SGI1
|
||||
# define GIC_SMP_CPUPAUSE GIC_IRQ_SGI2
|
||||
# define GIC_SMP_CPUCALL GIC_IRQ_SGI3
|
||||
# define GIC_SMP_CPUPAUSE_ASYNC GIC_IRQ_SGI4
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
@ -839,6 +841,29 @@ int arm_start_handler(int irq, void *context, void *arg);
|
||||
int arm_pause_handler(int irq, void *context, void *arg);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: arm_pause_async_handler
|
||||
*
|
||||
* Description:
|
||||
* This is the handler for async pause.
|
||||
*
|
||||
* 1. It saves the current task state at the head of the current assigned
|
||||
* task list.
|
||||
* 2. It porcess g_delivertasks
|
||||
* 3. Returns from interrupt, restoring the state of the new task at the
|
||||
* head of the ready to run list.
|
||||
*
|
||||
* Input Parameters:
|
||||
* Standard interrupt handling
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero on success; a negated errno value on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
int arm_pause_async_handler(int irq, void *context, void *arg);
|
||||
#endif
|
||||
/****************************************************************************
|
||||
* Name: arm_gic_dump
|
||||
*
|
||||
|
@ -230,8 +230,6 @@ int up_cpu_paused_restore(void)
|
||||
|
||||
int arm_pause_handler(int irq, void *context, void *arg)
|
||||
{
|
||||
int cpu = this_cpu();
|
||||
|
||||
/* Check for false alarms. Such false could occur as a consequence of
|
||||
* some deadlock breaking logic that might have already serviced the SG2
|
||||
* interrupt by calling up_cpu_paused(). If the pause event has already
|
||||
@ -256,8 +254,34 @@ int arm_pause_handler(int irq, void *context, void *arg)
|
||||
leave_critical_section(flags);
|
||||
}
|
||||
|
||||
nxsched_process_delivered(cpu);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: arm_pause_async_handler
|
||||
*
|
||||
* Description:
|
||||
* This is the handler for async pause.
|
||||
*
|
||||
* 1. It saves the current task state at the head of the current assigned
|
||||
* task list.
|
||||
* 2. It porcess g_delivertasks
|
||||
* 3. Returns from interrupt, restoring the state of the new task at the
|
||||
* head of the ready to run list.
|
||||
*
|
||||
* Input Parameters:
|
||||
* Standard interrupt handling
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero on success; a negated errno value on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int arm_pause_async_handler(int irq, void *context, void *arg)
|
||||
{
|
||||
int cpu = this_cpu();
|
||||
|
||||
nxsched_process_delivered(cpu);
|
||||
return OK;
|
||||
}
|
||||
|
||||
@ -282,7 +306,7 @@ int arm_pause_handler(int irq, void *context, void *arg)
|
||||
|
||||
inline_function int up_cpu_pause_async(int cpu)
|
||||
{
|
||||
arm_cpu_sgi(GIC_SMP_CPUPAUSE, (1 << cpu));
|
||||
arm_cpu_sgi(GIC_SMP_CPUPAUSE_ASYNC, (1 << cpu));
|
||||
|
||||
return OK;
|
||||
}
|
||||
@ -331,7 +355,7 @@ int up_cpu_pause(int cpu)
|
||||
spin_lock(&g_cpu_wait[cpu]);
|
||||
spin_lock(&g_cpu_paused[cpu]);
|
||||
|
||||
up_cpu_pause_async(cpu);
|
||||
arm_cpu_sgi(GIC_SMP_CPUPAUSE, (1 << cpu));
|
||||
|
||||
/* Wait for the other CPU to unlock g_cpu_paused meaning that
|
||||
* it is fully paused and ready for up_cpu_resume();
|
||||
|
@ -161,6 +161,8 @@ void arm_gic0_initialize(void)
|
||||
|
||||
DEBUGVERIFY(irq_attach(GIC_SMP_CPUSTART, arm_start_handler, NULL));
|
||||
DEBUGVERIFY(irq_attach(GIC_SMP_CPUPAUSE, arm_pause_handler, NULL));
|
||||
DEBUGVERIFY(irq_attach(GIC_SMP_CPUPAUSE_ASYNC,
|
||||
arm_pause_async_handler, NULL));
|
||||
DEBUGVERIFY(irq_attach(GIC_SMP_CPUCALL,
|
||||
nxsched_smp_call_handler, NULL));
|
||||
#endif
|
||||
|
@ -610,10 +610,12 @@
|
||||
# define GIC_SMP_CPUSTART GIC_IRQ_SGI9
|
||||
# define GIC_SMP_CPUPAUSE GIC_IRQ_SGI10
|
||||
# define GIC_SMP_CPUCALL GIC_IRQ_SGI11
|
||||
# define GIC_SMP_CPUPAUSE_ASYNC GIC_IRQ_SGI12
|
||||
#else
|
||||
# define GIC_SMP_CPUSTART GIC_IRQ_SGI1
|
||||
# define GIC_SMP_CPUPAUSE GIC_IRQ_SGI2
|
||||
# define GIC_SMP_CPUCALL GIC_IRQ_SGI3
|
||||
# define GIC_SMP_CPUPAUSE_ASYNC GIC_IRQ_SGI4
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
@ -827,6 +829,30 @@ int arm_start_handler(int irq, void *context, void *arg);
|
||||
int arm_pause_handler(int irq, void *context, void *arg);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: arm_pause_async_handler
|
||||
*
|
||||
* Description:
|
||||
* This is the handler for async pause.
|
||||
*
|
||||
* 1. It saves the current task state at the head of the current assigned
|
||||
* task list.
|
||||
* 2. It porcess g_delivertasks
|
||||
* 3. Returns from interrupt, restoring the state of the new task at the
|
||||
* head of the ready to run list.
|
||||
*
|
||||
* Input Parameters:
|
||||
* Standard interrupt handling
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero on success; a negated errno value on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
int arm_pause_async_handler(int irq, void *context, void *arg);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: arm_gic_dump
|
||||
*
|
||||
|
@ -313,10 +313,12 @@
|
||||
# define GIC_SMP_CPUSTART GIC_IRQ_SGI9
|
||||
# define GIC_SMP_CPUPAUSE GIC_IRQ_SGI10
|
||||
# define GIC_SMP_CPUCALL GIC_IRQ_SGI11
|
||||
# define GIC_SMP_CPUPAUSE_ASYNC GIC_IRQ_SGI12
|
||||
#else
|
||||
# define GIC_SMP_CPUSTART GIC_IRQ_SGI1
|
||||
# define GIC_SMP_CPUPAUSE GIC_IRQ_SGI2
|
||||
# define GIC_SMP_CPUCALL GIC_IRQ_SGI3
|
||||
# define GIC_SMP_CPUPAUSE_ASYNC GIC_IRQ_SGI4
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
@ -355,6 +357,10 @@ int arm_gic_raise_sgi(unsigned int sgi_id, uint16_t target_list);
|
||||
|
||||
int arm_pause_handler(int irq, void *context, void *arg);
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
int arm_pause_async_handler(int irq, void *context, void *arg);
|
||||
#endif
|
||||
|
||||
void arm_gic_secondary_init(void);
|
||||
|
||||
#endif
|
||||
|
@ -568,6 +568,8 @@ static void gicv3_dist_init(void)
|
||||
/* Attach SGI interrupt handlers. This attaches the handler to all CPUs. */
|
||||
|
||||
DEBUGVERIFY(irq_attach(GIC_SMP_CPUPAUSE, arm64_pause_handler, NULL));
|
||||
DEBUGVERIFY(irq_attach(GIC_SMP_CPUPAUSE_ASYNC,
|
||||
arm64_pause_async_handler, NULL));
|
||||
DEBUGVERIFY(irq_attach(GIC_SMP_CPUCALL,
|
||||
nxsched_smp_call_handler, NULL));
|
||||
#endif
|
||||
@ -814,6 +816,7 @@ static void arm_gic_init(void)
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
up_enable_irq(GIC_SMP_CPUPAUSE);
|
||||
up_enable_irq(GIC_SMP_CPUPAUSE_ASYNC);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -211,6 +211,35 @@ int up_cpu_paused_restore(void)
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: arm64_pause_async_handler
|
||||
*
|
||||
* Description:
|
||||
* This is the handler for async pause.
|
||||
*
|
||||
* 1. It saves the current task state at the head of the current assigned
|
||||
* task list.
|
||||
* 2. It porcess g_delivertasks
|
||||
* 3. Returns from interrupt, restoring the state of the new task at the
|
||||
* head of the ready to run list.
|
||||
*
|
||||
* Input Parameters:
|
||||
* Standard interrupt handling
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero on success; a negated errno value on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int arm64_pause_async_handler(int irq, void *context, void *arg)
|
||||
{
|
||||
int cpu = this_cpu();
|
||||
|
||||
nxsched_process_delivered(cpu);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: arm64_pause_handler
|
||||
*
|
||||
@ -259,8 +288,6 @@ int arm64_pause_handler(int irq, void *context, void *arg)
|
||||
leave_critical_section(flags);
|
||||
}
|
||||
|
||||
nxsched_process_delivered(cpu);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
@ -287,7 +314,7 @@ inline_function int up_cpu_pause_async(int cpu)
|
||||
{
|
||||
/* Execute SGI2 */
|
||||
|
||||
arm64_gic_raise_sgi(GIC_SMP_CPUPAUSE, (1 << cpu));
|
||||
arm64_gic_raise_sgi(GIC_SMP_CPUPAUSE_ASYNC, (1 << cpu));
|
||||
|
||||
return OK;
|
||||
}
|
||||
@ -336,7 +363,7 @@ int up_cpu_pause(int cpu)
|
||||
spin_lock(&g_cpu_wait[cpu]);
|
||||
spin_lock(&g_cpu_paused[cpu]);
|
||||
|
||||
up_cpu_pause_async(cpu);
|
||||
arm64_gic_raise_sgi(GIC_SMP_CPUPAUSE, (1 << cpu));
|
||||
|
||||
/* Wait for the other CPU to unlock g_cpu_paused meaning that
|
||||
* it is fully paused and ready for up_cpu_resume();
|
||||
|
@ -281,10 +281,12 @@
|
||||
#define GIC_IRQ_SGI15 15
|
||||
|
||||
#ifdef CONFIG_ARCH_TRUSTZONE_SECURE
|
||||
# define GIC_SMP_CPUPAUSE_ASYNC GIC_IRQ_SGI8
|
||||
# define GIC_SMP_CPUSTART GIC_IRQ_SGI9
|
||||
# define GIC_SMP_CPUPAUSE GIC_IRQ_SGI10
|
||||
# define GIC_SMP_CPUCALL GIC_IRQ_SGI11
|
||||
#else
|
||||
# define GIC_SMP_CPUPAUSE_ASYNC GIC_IRQ_SGI0
|
||||
# define GIC_SMP_CPUSTART GIC_IRQ_SGI1
|
||||
# define GIC_SMP_CPUPAUSE GIC_IRQ_SGI2
|
||||
# define GIC_SMP_CPUCALL GIC_IRQ_SGI3
|
||||
@ -343,6 +345,28 @@ void arm64_gic_raise_sgi(unsigned int sgi_id, uint16_t target_list);
|
||||
|
||||
int arm64_pause_handler(int irq, void *context, void *arg);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: arm64_pause_async_handler
|
||||
*
|
||||
* Description:
|
||||
* This is the handler for async pause.
|
||||
*
|
||||
* 1. It saves the current task state at the head of the current assigned
|
||||
* task list.
|
||||
* 2. It porcess g_delivertasks
|
||||
* 3. Returns from interrupt, restoring the state of the new task at the
|
||||
* head of the ready to run list.
|
||||
*
|
||||
* Input Parameters:
|
||||
* Standard interrupt handling
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero on success; a negated errno value on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int arm64_pause_async_handler(int irq, void *context, void *arg);
|
||||
|
||||
void arm64_gic_secondary_init(void);
|
||||
|
||||
#endif
|
||||
|
@ -911,6 +911,8 @@ static void arm_gic0_initialize(void)
|
||||
/* Attach SGI interrupt handlers. This attaches the handler to all CPUs. */
|
||||
|
||||
DEBUGVERIFY(irq_attach(GIC_SMP_CPUPAUSE, arm64_pause_handler, NULL));
|
||||
DEBUGVERIFY(irq_attach(GIC_SMP_CPUPAUSE_ASYNC,
|
||||
arm64_pause_async_handler, NULL));
|
||||
DEBUGVERIFY(irq_attach(GIC_SMP_CPUCALL,
|
||||
nxsched_smp_call_handler, NULL));
|
||||
#endif
|
||||
|
@ -654,6 +654,8 @@ static void gicv3_dist_init(void)
|
||||
/* Attach SGI interrupt handlers. This attaches the handler to all CPUs. */
|
||||
|
||||
DEBUGVERIFY(irq_attach(GIC_SMP_CPUPAUSE, arm64_pause_handler, NULL));
|
||||
DEBUGVERIFY(irq_attach(GIC_SMP_CPUPAUSE_ASYNC,
|
||||
arm64_pause_async_handler, NULL));
|
||||
DEBUGVERIFY(irq_attach(GIC_SMP_CPUCALL,
|
||||
nxsched_smp_call_handler, NULL));
|
||||
#endif
|
||||
@ -952,6 +954,7 @@ static void arm64_gic_init(void)
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
up_enable_irq(GIC_SMP_CPUPAUSE);
|
||||
up_enable_irq(GIC_SMP_CPUPAUSE_ASYNC);
|
||||
up_enable_irq(GIC_SMP_CPUCALL);
|
||||
#endif
|
||||
}
|
||||
|
@ -346,9 +346,10 @@
|
||||
#define HPET0_IRQ IRQ2
|
||||
#define HPET1_IRQ IRQ8
|
||||
|
||||
/* Use IRQ15 for SMP */
|
||||
/* Use IRQ15 IRQ16 for SMP */
|
||||
|
||||
#define SMP_IPI_IRQ IRQ15
|
||||
#define SMP_IPI_ASYNC_IRQ IRQ16
|
||||
|
||||
/* Common register save structure created by up_saveusercontext() and by
|
||||
* ISR/IRQ interrupt processing.
|
||||
|
@ -264,6 +264,35 @@ int up_pause_handler(int irq, void *c, void *arg)
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_pause_async_handler
|
||||
*
|
||||
* Description:
|
||||
* This is the handler for async pause.
|
||||
*
|
||||
* 1. It saves the current task state at the head of the current assigned
|
||||
* task list.
|
||||
* 2. It porcess g_delivertasks
|
||||
* 3. Returns from interrupt, restoring the state of the new task at the
|
||||
* head of the ready to run list.
|
||||
*
|
||||
* Input Parameters:
|
||||
* Standard interrupt handling
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero on success; a negated errno value on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int up_pause_async_handler(int irq, void *c, void *arg)
|
||||
{
|
||||
int cpu = this_cpu();
|
||||
|
||||
nxsched_process_delivered(cpu);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_cpu_pause_async
|
||||
*
|
||||
@ -290,7 +319,7 @@ inline_function int up_cpu_pause_async(int cpu)
|
||||
CPU_ZERO(&cpuset);
|
||||
CPU_SET(cpu, &cpuset);
|
||||
|
||||
up_trigger_irq(SMP_IPI_IRQ, cpuset);
|
||||
up_trigger_irq(SMP_IPI_ASYNC_IRQ, cpuset);
|
||||
|
||||
return OK;
|
||||
}
|
||||
@ -336,6 +365,7 @@ void up_send_smp_call(cpu_set_t cpuset)
|
||||
|
||||
int up_cpu_pause(int cpu)
|
||||
{
|
||||
cpu_set_t cpuset;
|
||||
sinfo("cpu=%d\n", cpu);
|
||||
|
||||
#ifdef CONFIG_SCHED_INSTRUMENTATION
|
||||
@ -362,7 +392,10 @@ int up_cpu_pause(int cpu)
|
||||
|
||||
/* Execute Pause IRQ to CPU(cpu) */
|
||||
|
||||
up_cpu_pause_async(cpu);
|
||||
CPU_ZERO(&cpuset);
|
||||
CPU_SET(cpu, &cpuset);
|
||||
|
||||
up_trigger_irq(SMP_IPI_IRQ, cpuset);
|
||||
|
||||
/* Wait for the other CPU to unlock g_cpu_paused meaning that
|
||||
* it is fully paused and ready for up_cpu_resume();
|
||||
|
@ -47,6 +47,7 @@
|
||||
|
||||
extern void __ap_entry(void);
|
||||
extern int up_pause_handler(int irq, void *c, void *arg);
|
||||
extern int up_pause_async_handler(int irq, void *c, void *arg);
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
@ -160,7 +161,9 @@ void x86_64_ap_boot(void)
|
||||
/* Connect Pause IRQ to CPU */
|
||||
|
||||
irq_attach(SMP_IPI_IRQ, up_pause_handler, NULL);
|
||||
irq_attach(SMP_IPI_ASYNC_IRQ, up_pause_async_handler, NULL);
|
||||
up_enable_irq(SMP_IPI_IRQ);
|
||||
up_enable_irq(SMP_IPI_ASYNC_IRQ);
|
||||
|
||||
/* CPU ready */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user