diff -urp --unidirectional-new-file -X /home/piel/west/artis/utils/dontdiff -X /home/piel/west/artis/utils/dontdiff2 2.6.12.2.orig/arch/ia64/Kconfig 2.6.12-artis-cvs-only/arch/ia64/Kconfig --- 2.6.12.2.orig/arch/ia64/Kconfig 2005-06-30 01:00:53.000000000 +0200 +++ 2.6.12-artis-cvs-only/arch/ia64/Kconfig 2005-07-11 21:07:12.000000000 +0200 @@ -50,6 +50,32 @@ config SCHED_NO_NO_OMIT_FRAME_POINTER bool default y +config ARTIS + bool "Compile the kernel with ARTiS support (EXPERIMENTAL)" + depends on PREEMPT && SMP + help + ARTiS is an "Asymmetric Real-Time Scheduling". When activated, + the real-time tasks will be insured of low latencies. It works + by automatically migrating the normal tasks out from CPUs running + real-time tasks when they would trigger a preemption disable or an + IRQ disable. Obviously, a SMP system is required (SMT works too). + Note that it will not be activated by default, you need to select + it at boot time. For more information, see Documentation/artis.txt. + +config ARTIS_DEBUG + bool "Compile the kernel with ARTiS debugging support (EXPERIMENTAL)" + depends on ARTIS + help + Activate debuging code in ARTiS, you probably don't want this, excepted + if you want to hack on ARTiS. + +config ARTIS_STAT + bool "Compile the kernel with ARTiS accounting support (EXPERIMENTAL)" + depends on ARTIS + help + Activate statistics about ARTiS, available in /proc. There is no (or + very little) performance penalty, so you can safely say "yes" here. + choice prompt "System type" default IA64_GENERIC diff -urp --unidirectional-new-file -X /home/piel/west/artis/utils/dontdiff -X /home/piel/west/artis/utils/dontdiff2 2.6.12.2.orig/arch/ia64/kernel/process.c 2.6.12-artis-cvs-only/arch/ia64/kernel/process.c --- 2.6.12.2.orig/arch/ia64/kernel/process.c 2005-06-30 01:00:53.000000000 +0200 +++ 2.6.12-artis-cvs-only/arch/ia64/kernel/process.c 2005-07-11 21:07:12.000000000 +0200 @@ -229,6 +229,45 @@ static inline void play_dead(void) } #endif /* CONFIG_HOTPLUG_CPU */ +#ifdef CONFIG_ARTIS_DEBUG +#include +void +artis_ia64_put_trace(struct unw_frame_info *info, void *arg) +{ + void **bt = (void **)arg; + int i, artis_skip_bt, r_unw; + unsigned long ip, sp, bsp; + + memset(bt, 0, ARTIS_BT_SIZE*sizeof(void *)); + r_unw=0; + artis_skip_bt=0; + for(i=artis_skip_bt-1; + i>=0 && r_unw>=0; + i--, r_unw=unw_unwind(info)) { + unw_get_ip(info, &ip); + if (ip == 0) + break; + unw_get_sp(info, &sp); + unw_get_bsp(info, &bsp); + } + for(i=ARTIS_BT_SIZE-1; + i>=0 && r_unw>=0; + i--, r_unw=unw_unwind(info)) { + unw_get_ip(info, &ip); + if (ip == 0) + break; + unw_get_sp(info, &sp); + unw_get_bsp(info, &bsp); + bt[i] = (void *)ip; + } +} + +void +artis_put_trace(void **bt, struct task_struct *task, unsigned long *stack) { + unw_init_running(artis_ia64_put_trace, (void *)bt); +} +#endif + void cpu_idle_wait(void) { unsigned int cpu, this_cpu = get_cpu(); diff -urp --unidirectional-new-file -X /home/piel/west/artis/utils/dontdiff -X /home/piel/west/artis/utils/dontdiff2 2.6.12.2.orig/include/asm-ia64/bug.h 2.6.12-artis-cvs-only/include/asm-ia64/bug.h --- 2.6.12.2.orig/include/asm-ia64/bug.h 2005-06-30 01:00:53.000000000 +0200 +++ 2.6.12-artis-cvs-only/include/asm-ia64/bug.h 2005-07-11 21:07:12.000000000 +0200 @@ -1,5 +1,6 @@ #ifndef _ASM_IA64_BUG_H #define _ASM_IA64_BUG_H +#include #ifdef CONFIG_BUG #if (__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1) @@ -7,7 +8,13 @@ #else # define ia64_abort() (*(volatile int *) 0 = 0) #endif -#define BUG() do { printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); ia64_abort(); } while (0) +#define _old_BUG() do { printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); ia64_abort(); } while (0) + +#if defined(CONFIG_ARTIS_DEBUG) +#define BUG() do { ARTIS_BUG(1,0); } while (0) +#else +#define BUG() _old_BUG() +#endif /* should this BUG be made generic? */ #define HAVE_ARCH_BUG diff -urp --unidirectional-new-file -X /home/piel/west/artis/utils/dontdiff -X /home/piel/west/artis/utils/dontdiff2 2.6.12.2.orig/include/asm-ia64/system.h 2.6.12-artis-cvs-only/include/asm-ia64/system.h --- 2.6.12.2.orig/include/asm-ia64/system.h 2005-06-30 01:00:53.000000000 +0200 +++ 2.6.12-artis-cvs-only/include/asm-ia64/system.h 2005-07-11 21:07:12.000000000 +0200 @@ -121,7 +121,7 @@ extern struct ia64_boot_param { * write a floating-point register right before reading the PSR * and that writes to PSR.mfl */ -#define __local_irq_save(x) \ +#define _raw__local_irq_save(x) \ do { \ ia64_stop(); \ (x) = ia64_getreg(_IA64_REG_PSR); \ @@ -129,13 +129,47 @@ do { \ ia64_rsm(IA64_PSR_I); \ } while (0) -#define __local_irq_disable() \ +#define _raw__local_irq_disable() \ do { \ ia64_stop(); \ ia64_rsm(IA64_PSR_I); \ } while (0) -#define __local_irq_restore(x) ia64_intrin_local_irq_restore((x) & IA64_PSR_I) +#define _raw__local_irq_restore(x) ia64_intrin_local_irq_restore((x) & IA64_PSR_I) + +#ifdef CONFIG_ARTIS +#include + +/* Overwrite all functions "dangerous" for real-time: migrate task on + * non real-time CPU */ + +#define __local_irq_save(x) \ +do { \ + artis_force_migration(); \ + _raw__local_irq_save(x); \ +} while (0) + +#define __local_irq_disable() \ +do { \ + artis_force_migration(); \ + _raw__local_irq_disable(); \ +} while (0) + +#define __local_irq_restore(x) \ +do { \ + if (!((x) & IA64_PSR_I)) \ + artis_force_migration(); \ + _raw__local_irq_restore(x); \ +} while (0) + +#else + +#define __local_irq_save(x) _raw__local_irq_save(x) +#define __local_irq_disable() _raw__local_irq_disable() +#define __local_irq_restore(x) _raw__local_irq_restore(x) + +#endif + #ifdef CONFIG_IA64_DEBUG_IRQ @@ -282,6 +316,20 @@ do { \ #define finish_arch_switch(rq, prev) spin_unlock_irq(&(prev)->switch_lock) #define task_running(rq, p) ((rq)->curr == (p) || spin_is_locked(&(p)->switch_lock)) +#ifdef CONFIG_ARTIS +/* On IA64, the end of scheduler releases the runqueue lock, + * so a wake-up has re-activated the task and we must + * deactivate it + * */ +#define artis_complete_arch(rq, task) \ +do { \ + spin_lock(&(rq)->lock); \ + if ((task)->array) \ + deactivate_task((task),(rq)); \ +} while(0) +#define artis_finish_complete_arch(rq, task) spin_unlock(&(rq)->lock) +#endif + #define ia64_platform_is(x) (strcmp(x, platform_name) == 0) void cpu_idle_wait(void);