From patchwork Tue May 26 06:25:49 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Blanchard X-Patchwork-Id: 27631 X-Patchwork-Delegate: benh@kernel.crashing.org Return-Path: X-Original-To: patchwork-incoming@bilbo.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from ozlabs.org (ozlabs.org [203.10.76.45]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "mx.ozlabs.org", Issuer "CA Cert Signing Authority" (verified OK)) by bilbo.ozlabs.org (Postfix) with ESMTPS id 2E641B6F44 for ; Tue, 26 May 2009 16:29:54 +1000 (EST) Received: by ozlabs.org (Postfix) id 08D2EDE42D; Tue, 26 May 2009 16:29:28 +1000 (EST) Delivered-To: patchwork-incoming@ozlabs.org Received: from ozlabs.org (localhost [127.0.0.1]) by ozlabs.org (Postfix) with ESMTP id 06BC5DE42C for ; Tue, 26 May 2009 16:29:28 +1000 (EST) X-Original-To: linuxppc-dev@ozlabs.org Delivered-To: linuxppc-dev@ozlabs.org Received: by ozlabs.org (Postfix, from userid 1010) id DD35EDE0E3; Tue, 26 May 2009 16:29:07 +1000 (EST) Date: Tue, 26 May 2009 16:25:49 +1000 From: Anton Blanchard To: linuxppc-dev@ozlabs.org Subject: [PATCH] powerpc: Convert RTAS event scan from kernel thread to workqueue Message-ID: <20090526062549.GH19728@kryten> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.18 (2008-05-17) 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: , Sender: linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@ozlabs.org Errors-To: linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@ozlabs.org RTAS event scan has to run across all cpus. Right now we use a kernel thread and set_cpus_allowed but in doing so we wake up the previous cpu unnecessarily. Some ftrace output shows this: previous cpu (2): [002] 7.022331: sched_switch: task swapper:0 [140] ==> rtasd:194 [120] [002] 7.022338: sched_switch: task rtasd:194 [120] ==> migration/2:9 [0] [002] 7.022344: sched_switch: task migration/2:9 [0] ==> swapper:0 [140] next cpu (3): [003] 7.022345: sched_switch: task swapper:0 [140] ==> rtasd:194 [120] [003] 7.022371: sched_switch: task rtasd:194 [120] ==> swapper:0 [140] We can use schedule_delayed_work_on and avoid the unnecessary wakeup. Signed-off-by: Anton Blanchard Index: linux-2.6/arch/powerpc/platforms/pseries/rtasd.c =================================================================== --- linux-2.6.orig/arch/powerpc/platforms/pseries/rtasd.c 2009-03-15 17:03:45.000000000 +1100 +++ linux-2.6/arch/powerpc/platforms/pseries/rtasd.c 2009-05-26 16:02:39.000000000 +1000 @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include #include @@ -387,36 +387,51 @@ } while(error == 0); } -static void do_event_scan_all_cpus(long delay) +static void rtas_event_scan(struct work_struct *w); +DECLARE_DELAYED_WORK(event_scan_work, rtas_event_scan); + +/* + * Delay should be at least one second since some machines have problems if + * we call event-scan too quickly. + */ +static unsigned long event_scan_delay = 1*HZ; +static int first_pass = 1; + +static void rtas_event_scan(struct work_struct *w) { - int cpu; + unsigned int cpu; + + do_event_scan(); get_online_cpus(); - cpu = first_cpu(cpu_online_map); - for (;;) { - set_cpus_allowed(current, cpumask_of_cpu(cpu)); - do_event_scan(); - set_cpus_allowed(current, CPU_MASK_ALL); - - /* Drop hotplug lock, and sleep for the specified delay */ - put_online_cpus(); - msleep_interruptible(delay); - get_online_cpus(); - cpu = next_cpu(cpu, cpu_online_map); - if (cpu == NR_CPUS) - break; + cpu = next_cpu(smp_processor_id(), cpu_online_map); + if (cpu == NR_CPUS) { + cpu = first_cpu(cpu_online_map); + + if (first_pass) { + first_pass = 0; + event_scan_delay = 30*HZ/rtas_event_scan_rate; + + if (surveillance_timeout != -1) { + pr_debug("rtasd: enabling surveillance\n"); + enable_surveillance(surveillance_timeout); + pr_debug("rtasd: surveillance enabled\n"); + } + } } + + schedule_delayed_work_on(cpu, &event_scan_work, + __round_jiffies_relative(event_scan_delay, cpu)); + put_online_cpus(); } -static int rtasd(void *unused) +static void start_event_scan(void) { unsigned int err_type; int rc; - daemonize("rtasd"); - printk(KERN_DEBUG "RTAS daemon started\n"); pr_debug("rtasd: will sleep for %d milliseconds\n", (30000 / rtas_event_scan_rate)); @@ -434,22 +449,8 @@ } } - /* First pass. */ - do_event_scan_all_cpus(1000); - - if (surveillance_timeout != -1) { - pr_debug("rtasd: enabling surveillance\n"); - enable_surveillance(surveillance_timeout); - pr_debug("rtasd: surveillance enabled\n"); - } - - /* Delay should be at least one second since some - * machines have problems if we call event-scan too - * quickly. */ - for (;;) - do_event_scan_all_cpus(30000/rtas_event_scan_rate); - - return -EINVAL; + schedule_delayed_work_on(first_cpu(cpu_online_map), &event_scan_work, + event_scan_delay); } static int __init rtas_init(void) @@ -487,8 +488,7 @@ if (!entry) printk(KERN_ERR "Failed to create error_log proc entry\n"); - if (kernel_thread(rtasd, NULL, CLONE_FS) < 0) - printk(KERN_ERR "Failed to start RTAS daemon\n"); + start_event_scan(); return 0; }