|
@@ -19,7 +19,7 @@
|
|
#include <linux/vmalloc.h>
|
|
#include <linux/vmalloc.h>
|
|
#include <linux/spinlock.h>
|
|
#include <linux/spinlock.h>
|
|
#include <linux/cpu.h>
|
|
#include <linux/cpu.h>
|
|
-#include <linux/delay.h>
|
|
|
|
|
|
+#include <linux/workqueue.h>
|
|
|
|
|
|
#include <asm/uaccess.h>
|
|
#include <asm/uaccess.h>
|
|
#include <asm/io.h>
|
|
#include <asm/io.h>
|
|
@@ -387,36 +387,51 @@ static void do_event_scan(void)
|
|
} while(error == 0);
|
|
} 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();
|
|
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();
|
|
put_online_cpus();
|
|
}
|
|
}
|
|
|
|
|
|
-static int rtasd(void *unused)
|
|
|
|
|
|
+static void start_event_scan(void)
|
|
{
|
|
{
|
|
unsigned int err_type;
|
|
unsigned int err_type;
|
|
int rc;
|
|
int rc;
|
|
|
|
|
|
- daemonize("rtasd");
|
|
|
|
-
|
|
|
|
printk(KERN_DEBUG "RTAS daemon started\n");
|
|
printk(KERN_DEBUG "RTAS daemon started\n");
|
|
pr_debug("rtasd: will sleep for %d milliseconds\n",
|
|
pr_debug("rtasd: will sleep for %d milliseconds\n",
|
|
(30000 / rtas_event_scan_rate));
|
|
(30000 / rtas_event_scan_rate));
|
|
@@ -434,22 +449,8 @@ static int rtasd(void *unused)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- /* 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)
|
|
static int __init rtas_init(void)
|
|
@@ -487,8 +488,7 @@ static int __init rtas_init(void)
|
|
if (!entry)
|
|
if (!entry)
|
|
printk(KERN_ERR "Failed to create error_log proc entry\n");
|
|
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;
|
|
return 0;
|
|
}
|
|
}
|