Index: include/asm-i386/hal.h =================================================================== --- include/asm-i386/hal.h (Revision 304) +++ include/asm-i386/hal.h (Arbeitskopie) @@ -266,6 +266,13 @@ void rthal_nmi_arm(unsigned long delay); void rthal_nmi_disarm(void); + +void rthal_nmi_proc_register(void); + +void rthal_nmi_proc_unregister(void); +#else /* !CONFIG_XENO_HW_NMI_DEBUG_LATENCY */ +# define rthal_nmi_proc_register() +# define rthal_nmi_proc_unregister() #endif /* CONFIG_XENO_HW_NMI_DEBUG_LATENCY */ static inline void rthal_timer_program_shot (unsigned long delay) @@ -325,6 +332,18 @@ const char __user *src, long count); +#ifdef CONFIG_PROC_FS +#include + +extern struct proc_dir_entry *rthal_proc_root; + +struct proc_dir_entry *__rthal_add_proc_leaf (const char *name, + read_proc_t rdproc, + write_proc_t wrproc, + void *data, + struct proc_dir_entry *parent); +#endif /* CONFIG_PROC_FS */ + #endif /* !__cplusplus */ #endif /* !_XENO_ASM_I386_HAL_H */ Index: ksrc/arch/i386/hal.c =================================================================== --- ksrc/arch/i386/hal.c (Revision 304) +++ ksrc/arch/i386/hal.c (Arbeitskopie) @@ -216,15 +216,88 @@ static void rthal_latency_above_max(struct pt_regs *regs) { +#ifdef CONFIG_IPIPE_TRACE + ipipe_trace_freeze(rthal_maxlat_us); +#else /* !CONFIG_IPIPE_TRACE */ char buf[128]; snprintf(buf, sizeof(buf), "NMI watchdog detected timer latency above %u us\n", rthal_maxlat_us); die_nmi(regs, buf); +#endif /* CONFIG_IPIPE_TRACE */ } -#endif +#ifdef CONFIG_PROC_FS +#include + +static int maxlat_read_proc (char *page, + char **start, + off_t off, + int count, + int *eof, + void *data) +{ + int len; + + len = sprintf(page, "%u\n", rthal_maxlat_us); + len -= off; + if (len <= off + count) + *eof = 1; + *start = page + off; + if (len > count) + len = count; + if (len < 0) + len = 0; + + return len; +} + +static int maxlat_write_proc (struct file *file, + const char __user *buffer, + unsigned long count, + void *data) +{ + char *end, buf[16]; + int val; + int n; + + n = (count > sizeof(buf) - 1) ? sizeof(buf) - 1 : count; + + if (copy_from_user(buf, buffer, n)) + return -EFAULT; + + buf[n] = '\0'; + val = simple_strtol(buf, &end, 0); + + if (((*end != '\0') && !isspace(*end)) || (val < 0)) + return -EINVAL; + + rthal_maxlat_us = val; + rthal_maxlat_tsc = rthal_llimd(rthal_maxlat_us * 1000ULL, + RTHAL_CPU_FREQ, + 1000000000); + + return count; +} + +void rthal_nmi_proc_register(void) +{ + __rthal_add_proc_leaf("nmi_maxlat", + &maxlat_read_proc, + &maxlat_write_proc, + NULL, + rthal_proc_root); +} + +void rthal_nmi_proc_unregister(void) +{ + remove_proc_entry("nmi_maxlat", rthal_proc_root); +} +#endif /* CONFIG_PROC_FS */ + +#endif /* CONFIG_XENO_HW_NMI_DEBUG_LATENCY */ + int rthal_timer_request (void (*handler)(void), unsigned long nstick) { Index: ksrc/arch/generic/hal.c =================================================================== --- ksrc/arch/generic/hal.c (Revision 304) +++ ksrc/arch/generic/hal.c (Arbeitskopie) @@ -279,7 +279,7 @@ * * @return 0 is returned upon success. Otherwise: * - * - -EINVAL is returned if @a irq is invalid or @æ handler is NULL. + * - -EINVAL is returned if @a irq is invalid or @a handler is NULL. * * Environments: * @@ -841,11 +841,11 @@ return len; } -static struct proc_dir_entry *add_proc_leaf (const char *name, - read_proc_t rdproc, - write_proc_t wrproc, - void *data, - struct proc_dir_entry *parent) +struct proc_dir_entry *__rthal_add_proc_leaf (const char *name, + read_proc_t rdproc, + write_proc_t wrproc, + void *data, + struct proc_dir_entry *parent) { int mode = wrproc ? 0644 : 0444; struct proc_dir_entry *entry; @@ -877,35 +877,39 @@ rthal_proc_root->owner = THIS_MODULE; - add_proc_leaf("hal", + __rthal_add_proc_leaf("hal", &hal_read_proc, NULL, NULL, rthal_proc_root); - add_proc_leaf("irq", + __rthal_add_proc_leaf("irq", &irq_read_proc, NULL, NULL, rthal_proc_root); - add_proc_leaf("faults", + __rthal_add_proc_leaf("faults", &faults_read_proc, NULL, NULL, rthal_proc_root); - add_proc_leaf("apc", + __rthal_add_proc_leaf("apc", &apc_read_proc, NULL, NULL, rthal_proc_root); + + rthal_nmi_proc_register(); + return 0; } static void rthal_proc_unregister (void) { + rthal_nmi_proc_unregister(); remove_proc_entry("hal",rthal_proc_root); remove_proc_entry("irq",rthal_proc_root); remove_proc_entry("faults",rthal_proc_root);