forked from luck/tmp_suning_uos_patched
powerpc: Provide a separate handler for each IPI action
With the new generic smp call function helpers, I noticed the code in smp_message_recv was a single function call in many cases. While getting the message number from the ipi data is easy, we can reduce the path length by a function and data-dependent switch by registering seperate IPI actions for these simple calls. Originally I left the ipi action array exposed, but then I realized the registration code should be common too. The three users each had their own name array, so I made a fourth to convert all users to use a common one. Signed-off-by: Milton Miller <miltonm@bga.com> Signed-off-by: Paul Mackerras <paulus@samba.org>
This commit is contained in:
parent
a6326e98a2
commit
25ddd738c2
|
@ -81,6 +81,13 @@ extern int cpu_to_core_id(int cpu);
|
|||
#define PPC_MSG_CALL_FUNC_SINGLE 2
|
||||
#define PPC_MSG_DEBUGGER_BREAK 3
|
||||
|
||||
/*
|
||||
* irq controllers that have dedicated ipis per message and don't
|
||||
* need additional code in the action handler may use this
|
||||
*/
|
||||
extern int smp_request_message_ipi(int virq, int message);
|
||||
extern const char *smp_ipi_name[];
|
||||
|
||||
void smp_init_iSeries(void);
|
||||
void smp_init_pSeries(void);
|
||||
void smp_init_cell(void);
|
||||
|
|
|
@ -123,6 +123,65 @@ void smp_message_recv(int msg)
|
|||
}
|
||||
}
|
||||
|
||||
static irqreturn_t call_function_action(int irq, void *data)
|
||||
{
|
||||
generic_smp_call_function_interrupt();
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static irqreturn_t reschedule_action(int irq, void *data)
|
||||
{
|
||||
/* we just need the return path side effect of checking need_resched */
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static irqreturn_t call_function_single_action(int irq, void *data)
|
||||
{
|
||||
generic_smp_call_function_single_interrupt();
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static irqreturn_t debug_ipi_action(int irq, void *data)
|
||||
{
|
||||
smp_message_recv(PPC_MSG_DEBUGGER_BREAK);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static irq_handler_t smp_ipi_action[] = {
|
||||
[PPC_MSG_CALL_FUNCTION] = call_function_action,
|
||||
[PPC_MSG_RESCHEDULE] = reschedule_action,
|
||||
[PPC_MSG_CALL_FUNC_SINGLE] = call_function_single_action,
|
||||
[PPC_MSG_DEBUGGER_BREAK] = debug_ipi_action,
|
||||
};
|
||||
|
||||
const char *smp_ipi_name[] = {
|
||||
[PPC_MSG_CALL_FUNCTION] = "ipi call function",
|
||||
[PPC_MSG_RESCHEDULE] = "ipi reschedule",
|
||||
[PPC_MSG_CALL_FUNC_SINGLE] = "ipi call function single",
|
||||
[PPC_MSG_DEBUGGER_BREAK] = "ipi debugger",
|
||||
};
|
||||
|
||||
/* optional function to request ipi, for controllers with >= 4 ipis */
|
||||
int smp_request_message_ipi(int virq, int msg)
|
||||
{
|
||||
int err;
|
||||
|
||||
if (msg < 0 || msg > PPC_MSG_DEBUGGER_BREAK) {
|
||||
return -EINVAL;
|
||||
}
|
||||
#if !defined(CONFIG_DEBUGGER) && !defined(CONFIG_KEXEC)
|
||||
if (msg == PPC_MSG_DEBUGGER_BREAK) {
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
err = request_irq(virq, smp_ipi_action[msg], IRQF_DISABLED|IRQF_PERCPU,
|
||||
smp_ipi_name[msg], 0);
|
||||
WARN(err < 0, "unable to request_irq %d for %s (rc %d)\n",
|
||||
virq, smp_ipi_name[msg], err);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
void smp_send_reschedule(int cpu)
|
||||
{
|
||||
if (likely(smp_ops))
|
||||
|
|
Loading…
Reference in New Issue
Block a user