From patchwork Tue Oct 21 01:37:01 2008 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Milton Miller X-Patchwork-Id: 5174 X-Patchwork-Delegate: paulus@samba.org Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from ozlabs.org (localhost [127.0.0.1]) by ozlabs.org (Postfix) with ESMTP id 1DB28DDE00 for ; Tue, 21 Oct 2008 12:40:38 +1100 (EST) X-Original-To: linuxppc-dev@ozlabs.org Delivered-To: linuxppc-dev@ozlabs.org Received: from sullivan.realtime.net (sullivan.realtime.net [205.238.132.226]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id D6F2BDDE1E for ; Tue, 21 Oct 2008 12:37:24 +1100 (EST) Received: from sullivan.realtime.net (localhost [127.0.0.1]) by sullivan.realtime.net (8.13.1/8.9.3) with ESMTP id m9L1b2L1045435; Mon, 20 Oct 2008 20:37:02 -0500 (CDT) (envelope-from miltonm@sullivan.realtime.net) Received: (from miltonm@localhost) by sullivan.realtime.net (8.13.1/8.12.7/Submit) id m9L1b18n045430; Mon, 20 Oct 2008 20:37:01 -0500 (CDT) Date: Mon, 20 Oct 2008 20:37:01 -0500 (CDT) From: Milton Miller To: linuxppc-dev@ozlabs.org Message-id: In-Reply-To: Subject: [PATCH 14/16 v2] powerpc: expand vs demux ipi actions per message Cc: Arnd Bergmann X-BeenThere: linuxppc-dev@ozlabs.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@ozlabs.org Errors-To: linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@ozlabs.org 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 separate 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 --- v2: fix arg reversal noted by Geert Uytterhoeven. This order is most similar to request_irq and message in data field, but without casting. Perhaps we should make the common code look like an ipi action handler and remove this last call? Currently we still have to allocate a stack frame to load the return value. Index: next.git/arch/powerpc/include/asm/smp.h =================================================================== --- next.git.orig/arch/powerpc/include/asm/smp.h 2008-10-05 00:08:36.000000000 -0500 +++ next.git/arch/powerpc/include/asm/smp.h 2008-10-05 00:16:34.000000000 -0500 @@ -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); Index: next.git/arch/powerpc/kernel/smp.c =================================================================== --- next.git.orig/arch/powerpc/kernel/smp.c 2008-10-05 00:08:38.000000000 -0500 +++ next.git/arch/powerpc/kernel/smp.c 2008-10-05 00:19:12.000000000 -0500 @@ -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, ipi_names[msg], err); + + return err; +} + void smp_send_reschedule(int cpu) { if (likely(smp_ops))