[PATCH] rtasd shouldn't hold cpucontrol while sleeping

Nathan Lynch ntl at pobox.com
Sun Feb 20 14:04:25 EST 2005


On Sun, Feb 20, 2005 at 07:43:00AM +1100, Anton Blanchard wrote:
> 
> We used to migrate to random cpus each iteration but we got watchdog
> timeouts on a 16 way nighthawk. The theory was that the worst case touch
> of the watchdog on a cpu could be 2x the scan rate.
> 
> I didnt confirm this with the firmware guys but changing it to the
> current method where we always iterate in the same order made the
> watchdogs go away.

OK, here's a more conservative patch which preserves that behavior.
My primary goal is to get rid of that delay during boot.

The rtasd thread should not hold the cpucontrol semaphore while
sleeping between event scans in its first pass; it needlessly delays
boot by one second per cpu when CONFIG_HOTPLUG_CPU=y.

Signed-off-by: Nathan Lynch <ntl at pobox.com>

Index: linux-2.6.11-rc4-bk4/arch/ppc64/kernel/rtasd.c
===================================================================
--- linux-2.6.11-rc4-bk4.orig/arch/ppc64/kernel/rtasd.c	2005-02-20 02:08:49.000000000 +0000
+++ linux-2.6.11-rc4-bk4/arch/ppc64/kernel/rtasd.c	2005-02-20 02:28:07.000000000 +0000
@@ -400,10 +400,33 @@
 	} while(error == 0);
 }
 
+static void do_event_scan_all_cpus(long delay)
+{
+	int cpu;
+
+	lock_cpu_hotplug();
+	cpu = first_cpu(cpu_online_map);
+	for (;;) {
+		set_cpus_allowed(current, cpumask_of_cpu(cpu));
+		do_event_scan(rtas_token("event-scan"));
+		set_cpus_allowed(current, CPU_MASK_ALL);
+
+		/* Drop hotplug lock, and sleep for the specified delay */
+		unlock_cpu_hotplug();
+		set_current_state(TASK_INTERRUPTIBLE);
+		schedule_timeout(delay);
+		lock_cpu_hotplug();
+
+		cpu = next_cpu(cpu, cpu_online_map);
+		if (cpu == NR_CPUS)
+			break;
+	}
+	unlock_cpu_hotplug();
+}
+
 static int rtasd(void *unused)
 {
 	unsigned int err_type;
-	int cpu = 0;
 	int event_scan = rtas_token("event-scan");
 	int rc;
 
@@ -437,17 +460,7 @@
 	}
 
 	/* First pass. */
-	lock_cpu_hotplug();
-	for_each_online_cpu(cpu) {
-		DEBUG("scheduling on %d\n", cpu);
-		set_cpus_allowed(current, cpumask_of_cpu(cpu));
-		DEBUG("watchdog scheduled on cpu %d\n", smp_processor_id());
-
-		do_event_scan(event_scan);
-		set_current_state(TASK_INTERRUPTIBLE);
-		schedule_timeout(HZ);
-	}
-	unlock_cpu_hotplug();
+	do_event_scan_all_cpus(HZ);
 
 	if (surveillance_timeout != -1) {
 		DEBUG("enabling surveillance\n");
@@ -455,25 +468,10 @@
 		DEBUG("surveillance enabled\n");
 	}
 
-	lock_cpu_hotplug();
-	cpu = first_cpu(cpu_online_map);
-	for (;;) {
-		set_cpus_allowed(current, cpumask_of_cpu(cpu));
-		do_event_scan(event_scan);
-		set_cpus_allowed(current, CPU_MASK_ALL);
-
-		/* Drop hotplug lock, and sleep for a bit (at least
-		 * one second since some machines have problems if we
-		 * call event-scan too quickly). */
-		unlock_cpu_hotplug();
-		set_current_state(TASK_INTERRUPTIBLE);
-		schedule_timeout((HZ*60/rtas_event_scan_rate) / 2);
-		lock_cpu_hotplug();
-
-		cpu = next_cpu(cpu, cpu_online_map);
-		if (cpu == NR_CPUS)
-			cpu = first_cpu(cpu_online_map);
-	}
+	/* Delay should be at least one second since some
+	 * machines have problems if we call event-scan too
+	 * quickly. */
+	do_event_scan_all_cpus((HZ*60/rtas_event_scan_rate) / 2);
 
 error:
 	/* Should delete proc entries */



More information about the Linuxppc64-dev mailing list