ARTiS, an asymmetric real-time scheduler
Subsystems (5)
cover ARTiS, an asymmetric real-time scheduler
Hello,
I'd like to present "ARTiS", a research project that we developed at the LIFL, within the HYADES project. The goal was to provide a system which can be hard real-time and in the same time permit high performance computing.
The main idea of our approach is to insert asymmetry into an SMP computer. While the several processors allows us to get HPC, the asymmetry provides real-time capabilities. In order to guarantee that the RT tasks can always be scheduled with a low latency, we forbid _all_ the other tasks to take a lock or disable the preemption on some specified CPUs. Basically, there is a set of "RT CPUs" and a set of "Non-RT CPUs". When a normal task is executed on a RT CPU and happen to call either inc_preempt_count() or __local_irq_save(), then it is automatically migrated to a Non-RT CPU, where the syscall will be continued. Still, the RT CPUs can execute all computation from any task. For more detailed description, please have a look at the research papers available at http://www.lifl.fr/west/artis .
So we currently have an implementation for kernel 2.6.11, available on the x86 and IA-64 architectures. It's a proof of concept with rough edges. Even after the code clean-up, I guess some people will scream when looking at the code, it's not the most beautiful one ever done. Nevertheless, it works. When ARTiS is activated your system shouldn't crash more often than usual and tasks scheduled FIFO with priority 99 will get much better latencies than before.
The modifications are mostly situated in the scheduler. The migration from an RT CPU to a Non-RT CPU is done asynchronously (there is a special queue which can be read/write without lock). There is also a big part which tries to enhance the load-balancer wrt the RT and to the asymmetry. Following to this email, there will be the core patch as well as the patches for architecture dependent parts (which are rather small).
It worth noting that even if ARTiS was designed for SMP systems, it works also on a SMT processor (although it seems that for now it's better not to select the SMT additions to avoid crash). It has been tested on Pentium HyperThreaded. Then ARTiS can be seen more like just a firm (or hard if you have hopes) real-time patch that works with any tasks written for Linux.
The latency measurements which have been conducted on a quadri-processor
IA-64 give results of scheduling always under 105µs instead of 1200µs
for a preemptible kernel. On a Pentium 4 HT, latencies are always under
40µs instead of 14000µs. The measurement tool (realfeel-pfm) that we used is available for both x86 and IA-64 architectures. On the latter one there is an additional measure of the "kernel latency" which is quite interesting too.
In addition, a load-balancer evaluator, lbµ is also available. It's completely architecture independent but don't hope too much from it, it just let you always run the same load on the system and collect some statistic. Apart from this, all needs to be done by the user.
If you want to try it, have a look first at the documentation available in Documentation/artis.txt . There is also information available on the research project webpage http://www.lifl.fr/west/artis while you can follow the development at this page: https://gna.org/projects/artis .
We hope that some people can find interest on this project. Any remark or comment is very welcome,
Eric Piel
PATCH 1/3 ARTiS, an asymmetric real-time scheduler
Here is the core of ARTiS.
Documentation/artis.txt +243 -0
@@ -0,0 +1,243 @@ +ARTiS - an Asymmetric Real-Time Scheduling +http://www.lifl.fr/west/artis/ +https://gna.org/projects/artis/ + +Eric Piel <[email protected]> +Christophe Osuna <[email protected]> +Julien Soula <[email protected]> +Philippe Marquet <[email protected]> + +Université des Sciences et Technologies de Lille +Laboratoire d'Informatique Fondamentale de Lille +Last update: May 02, 2005 +------------------------------------------------------------------------------ + + +Overview +-------- + +ARTiS is a patch to the Linux scheduler directed to real-time SMP +systems. By migrating tasks from real-time CPUs to non-real-time ones +it can achieve very low latencies. On an 4x IA-64 we target user +latencies always under 300µs. + +Detail descriptions of the implementation and measurements are available as +research articles at: http://www.lifl.fr/west/artis . + +Installation +------------ + +ARTiS is provided as a set of Linux kernel patch. They apply against +the vanilla Linux Kernel, available at http://www.kernel.org . Some +versions might need to be applied against the Bull version of the +Linux kernel. Use the command: + % patch -p1 < ../the-name-of-the.patch + +ARTiS was designed to run on IA-64 and x86 SMP systems. You can +compile it into the kernel by selecting: + + [X] File systems -> Pseudo filesystems -> /proc file system support + [X] Processor types and features -> Preemptible Kernel + [X] Processor types and features -> Compile the kernel with ARTiS + support + +Optionally you can select: + + [X] Processor types and features -> Compile the kernel with ARTiS + debugging support + [X] Processor types and features -> Compile the kernel with ARTiS + accounting support + +You also need to disable the energy saving functions that could put the CPUs +into a state with a long transition latency. For example, on IA-64 the +pal_halt optimisation must be disabled, this can be done by appending "nohalt" +to the kernel command line (in elilo.conf). + +System administration +--------------------- + +Before you can benefit from the ARTiS enhancements, you will have to +boot on a Linux kernel including the patches on a SMP computer. + +You need to choose an appropriate CPU for the real-time program and +set affinities accordingly via the /proc file system. + +The ARTiS interface provides three files: +/proc/artis/active : contains 0 or 1 corresponding to the deactivation + or activation of ARTiS. It is writable. +/proc/artis/maskrt : contains a hexadecimal number corresponding to the RT + CPU mask. You can change it only when ARTiS is disabled. +/proc/artis/cpustat : gives various statistics about ARTiS, it is read-only. + +EXAMPLE: + +This is an x86 system with 4 processors. We will use the RTC interrupt +for our real-time program, which will run on the 4th processor. + + % cat /proc/interrupts + CPU0 CPU1 CPU2 CPU3 + 0: 16320035 14 10 11 IO-APIC-edge timer + 1: 8 1 0 0 IO-APIC-edge i8042 + 2: 0 0 0 0 XT-PIC cascade + 8: 2 0 1 2459330 IO-APIC-edge rtc + 19: 9930157 1643458 1603777 0 IO-APIC-level eth0 + 20: 133 0 1 0 IO-APIC-level aic7xxx + 21: 29 0 1 0 IO-APIC-level aic7xxx + 22: 134403 0 1 0 IO-APIC-level aic7xxx + NMI: 0 0 0 0 + LOC: 16318912 16318911 16318910 16318835 + ERR: 0 + MIS: 0 + +We need to redirect all the interrupts except the RTC one to the 3 +first processors (which means 7 as CPU mask): + + % for i in 1 2 19 20 21 22 ; do echo 7 > /proc/irq/$i/smp_affinity ; done + +Alternatively, you can use the change_all_irqs.sh script available on +the ARTiS webpage in the affinity-utils package. Warning, on IA-64, we +have noticed that some IRQ may not be able to change of mask. You need +to select another CPU than the one where the IRQ are as a RT CPU. + +Here we want to keep IRQ 8 (RTC) for the real-time process on the 4th CPU: + + % echo 8 > /proc/irq/8/smp_affinity + +We want the 4th processor to be set as real-time: + + % echo 8 > /proc/artis/maskrt + +And of course we must activate ARTiS :-) + + % echo 1 > /proc/artis/active + +The active state of ARTiS as well as the maskrt properties can also be +set on the command line (in elilo.conf) via respectively +"artis_active" and "artis_maskrt=". + +IMPORTANT NOTE (bug workaround): As of 20050502, there seems to be a +latency problem on SMPs. This bug appears both on x86 and IA-64, even +when the computer is purely idle and without ARTiS. The problem: there +is always one (and only one) CPU where the latencies are much higher +than anywhere else (10x or 100x higher). This CPU seems to be the +same that receive all the IRQs at boot, so you can detect it by having +a look at /proc/interrupts. Set this CPU as an NRT CPU, that's all. + + +ARTiS /proc interface +--------------------- + +The ARTiS activation is now realized after boot-time via the /proc +interface. + +The following enables ARTiS + + % echo 1 > /proc/artis/active + +while the following disable ARTiS + + % echo 0 > /proc/artis/active + + +The file /proc/artis/cpustat contains one line of statistics per CPU +(a maximum of 8 CPUs). Every line contains in turn four columns with +the number of migrations initiated on this CPU and some timings useful +for debugging. + + +The file /proc/artis/maskrt identifies the RT CPUs. + +You can specify which CPUs are real-time by writing into this file +the mask of the CPUs. + +For instance the following will set 4th processor as real-time: + + % echo 8 > /proc/artis/maskrt + +The following will set 2nd, 3rd and 4th CPUs as real-time: + + % echo e > /proc/artis/maskrt + + + + +Real-Time programming with ARTiS +-------------------------------- + +You will need to add some instructions to a program to make it +real-time and to bind it to a CPU. Fortunately this is not a difficult +task and if your application is POSIX compliant, most of them are +probably already done. A function like the next one can be used for +this: + + #include <string.h> + #include <sched.h> + + /* Set the current process to real-time priority. + * Return 0 on success, -1 on failure */ + int set_realtime_priority(void) + { + sched_param schp; + + memset(&schp, 0, sizeof(schp)); + schp.sched_priority = sched_get_priority_max(SCHED_FIFO); + + return sched_setscheduler(0, SCHED_FIFO, &schp); + } + +Setting the affinity of a process might not be correctly handled by +the glibc, so you will have to make a syscall. The following might +help: + + #include <unistd.h> + + #if defined(__ia64__) + #define SYS_sched_setaffinity 1231 + #define SYS_sched_getaffinity 1232 + #elif defined(__i386__) + #define SYS_sched_setaffinity 241 + #define SYS_sched_getaffinity 242 + #else + #error Architecture not supported (only ia64 an i386 are) + #endif + + #define sched_setaffinity(arg1, arg2, arg3) \ + syscall(SYS_sched_setaffinity, arg1, arg2, arg3) + #define sched_getaffinity(arg1, arg2, arg3) \ + syscall(SYS_sched_getaffinity, arg1, arg2, arg3) + + /* Set the affinity of the current process. + * Return 0 on success, -1 on failure */ + int set_affinity(unsigned long mask) + { + return sched_setaffinity(0, sizeof(mask), &mask); + } + +With respect to the example above, our program will need to make the +following calls somewhere: + + { + set_realtime_priority(); + set_affinity(8); + } + +Due to the nature of ARTiS, the only constraint compared to a usual +POSIX RT application is the order of this two function calls. The +priority set up must always be *before* the affinity set up +(otherwise, the affinity cannot be guaranted). + +Always keep in mind that if you want your task to have obtain firm +real-time latencies, they will have to be RT0. Such task have the +maximum RT FIFO priority and are binded to one and only one RT CPU. +Guaranty can be insured only for one RT0 task per CPU. More RT0 per +CPU is possible but it is your job to check that they can all be +executed in the same time and always repect their deadlines. + +In case you don't want (or cannot) recompile your application to fit +those specific requirements for ARTiS, you can still change it to RT0 +from outside. schedtool is probably what you need, cf http://freequaos.host.sk/schedtool/. + +Another way to do this is to use the functions provided by libartis, a +small package available on the ARTiS webpage. If you need a more +elaborate example, you can have a look at realfeel-pfm, also available +at the ARTiS webpage.
Documentation/kernel-parameters.txt +6 -0
@@ -220,6 +220,12 @@ running once the system is up. arcrimi= [HW,NET] ARCnet - "RIM I" (entirely mem-mapped) cards Format: <io>,<irq>,<nodeID> + artis_active [KNL] Activates ARTiS + See also Documentation/artis.txt + + artis_maskrt= [KNL] Set ARTiS real-time CPUs mask + See also Documentation/artis.txt + ataflop= [HW,M68k] atarimouse= [HW,MOUSE] Atari Mouse
fs/proc/artis.c +254 -0
254 lines not on this page · raw message
fs/proc/base.c +20 -0
@@ -32,6 +32,7 @@#include <linux/mount.h> #include <linux/security.h> #include <linux/ptrace.h> +#include <linux/artis.h> #include "internal.h" /*
@@ -74,6 +75,9 @@ enum pid_directory_inos {#ifdef CONFIG_AUDITSYSCALL PROC_TGID_LOGINUID,#endif +#ifdef CONFIG_ARTIS +PROC_TGID_ARTIS , +#endifPROC_TGID_FD_DIR ,PROC_TGID_OOM_SCORE , PROC_TGID_OOM_ADJUST,
@@ -105,6 +109,9 @@ enum pid_directory_inos {#ifdef CONFIG_AUDITSYSCALL PROC_TID_LOGINUID,#endif +#ifdef CONFIG_ARTIS +PROC_TID_ARTIS , +#endifPROC_TID_FD_DIR =0x8000 ,/* 0x8000-0xffff */ PROC_TID_OOM_SCORE , PROC_TID_OOM_ADJUST,
@@ -148,6 +155,9 @@ static struct pid_entry tgid_base_stuff[#ifdef CONFIG_AUDITSYSCALL E(PROC_TGID_LOGINUID, "loginuid", S_IFREG|S_IWUSR|S_IRUGO),#endif +#ifdef CONFIG_ARTIS + E(PROC_TGID_ARTIS, "artis", S_IFREG|S_IRUGO), +#endif {0,0,NULL,0} }; static struct pid_entry tid_base_stuff[] = {
@@ -178,6 +188,9 @@ static struct pid_entry tid_base_stuff[]#ifdef CONFIG_AUDITSYSCALL E(PROC_TID_LOGINUID, "loginuid", S_IFREG|S_IWUSR|S_IRUGO),#endif +#ifdef CONFIG_ARTIS +E (PROC_TID_ARTIS ,"artis" ,S_IFREG |S_IRUGO ), +#endif {0,0,NULL,0} };
@@ -1476,6 +1489,13 @@ static struct dentry *proc_pident_lookup ei->op.proc_read = proc_pid_wchan;break ;#endif +#ifdef CONFIG_ARTIS +case PROC_TID_ARTIS : +case PROC_TGID_ARTIS : + inode->i_fop = &proc_info_file_operations; + ei->op.proc_read = proc_pid_artis; +break ; +#endif #ifdef CONFIG_SCHEDSTATS case PROC_TID_SCHEDSTAT :case PROC_TGID_SCHEDSTAT :
fs/proc/Makefile +1 -1
@@ -8,7 +8,7 @@ proc-y := nommu.o task_nommu.o proc-$(CONFIG_MMU) := mmu.o task_mmu.o proc-y += inode.o root.o base.o generic.o array.o \ - kmsg.o proc_tty.o proc_misc.o + kmsg.o proc_tty.o proc_misc.o artis.o proc-$(CONFIG_PROC_KCORE) += kcore.o proc-$(CONFIG_PROC_DEVICETREE) += proc_devtree.o
include/linux/artis.h +273 -0
273 lines not on this page · raw message
include/linux/artis-macros.h +136 -0
136 lines not on this page · raw message
include/linux/init_task.h +1 -0
@@ -112,6 +112,7 @@ extern struct group_info init_groups; .proc_lock = SPIN_LOCK_UNLOCKED, \ .switch_lock = SPIN_LOCK_UNLOCKED, \ .journal_info = NULL, \ + SET_ARTIS_TASK_STATUS_INIT(.artis_status) \ }
include/linux/kernel_stat.h +4 -0
@@ -7,6 +7,7 @@#include <linux/threads.h> #include <linux/percpu.h> #include <asm/cputime.h> +#include <linux/artis.h> /* * 'kernel_stat.h' contains the definitions needed for doing
@@ -23,6 +24,9 @@ struct cpu_usage_stat {cputime64_t idle;cputime64_t iowait;cputime64_t steal; +#ifdef CONFIG_ARTIS +u64 rt; +#endif };struct kernel_stat {
include/linux/preempt.h +9 -0
@@ -8,6 +8,7 @@#include <linux/config.h> #include <linux/linkage.h> +#include <linux/artis-macros.h> #ifdef CONFIG_DEBUG_PREEMPT extern void fastcall add_preempt_count(int val);
@@ -17,7 +18,15 @@# define sub_preempt_count (val) do { preempt_count() -= (val); } while (0)#endif +#ifdef CONFIG_ARTIS +#define inc_preempt_count () \ +do { \ + add_preempt_count(1); \ + artis_try_to_migrate(); \ +} while (0) +#else #define inc_preempt_count () add_preempt_count(1) +#endif #define dec_preempt_count () sub_preempt_count(1)#define preempt_count () (current_thread_info()->preempt_count)
include/linux/sched.h +7 -0
@@ -33,6 +33,8 @@#include <linux/percpu.h> #include <linux/topology.h> +#include <linux/artis.h> +struct exec_domain ;/*
@@ -685,6 +687,11 @@ struct task_struct {struct mempolicy *mempolicy;short il_next;#endif +#ifdef CONFIG_ARTIS +artis_task_status_t artis_status; +unsigned long nr_rt; +int prev_cpu_load_rt[NR_CPUS ]; +#endif };static inline pid_t process_group (struct task_struct *tsk)
init/main.c +10 -0
@@ -46,6 +46,7 @@#include <linux/rmap.h> #include <linux/mempolicy.h> #include <linux/key.h> +#include <linux/artis.h> #include <asm/io.h> #include <asm/bugs.h>
@@ -106,6 +107,10 @@ extern void tc_init(void);enum system_states system_state;EXPORT_SYMBOL (system_state); +#ifdef CONFIG_ARTIS +extern void artis_init (void ); +#endif +/* * Boot command-line arguments */
@@ -510,6 +515,11 @@ asmlinkage void __init start_kernel(voidacpi_early_init ();/* before LAPIC and SMP init */ +#ifdef CONFIG_ARTIS +artis_init (); +#endif + +/* Do the rest non-__init'ed, we're now alive */ rest_init (); }
kernel/fork.c +32 -2
@@ -40,6 +40,7 @@#include <linux/profile.h> #include <linux/rmap.h> #include <linux/acct.h> +#include <linux/artis.h> #include <asm/pgtable.h> #include <asm/pgalloc.h>
@@ -78,10 +79,16 @@ int nr_processes(void)# define free_task_struct (tsk) kmem_cache_free(task_struct_cachep, (tsk))static kmem_cache_t *task_struct_cachep;#endif +#ifdef CONFIG_ARTIS +kmem_cache_t *artis_fifo_node_cachep =NULL ; +#endif void free_task (struct task_struct *tsk) {free_thread_info (tsk->thread_info); +#ifdef CONFIG_ARTIS +free_artis_fifo_node (tsk->artis_status.fifo_node); +#endif free_task_struct (tsk); }EXPORT_SYMBOL (free_task);
@@ -113,6 +120,14 @@ void __init fork_init(unsigned long mempkmem_cache_create ("task_struct" ,sizeof (struct task_struct ),ARCH_MIN_TASKALIGN ,SLAB_PANIC ,NULL ,NULL );#endif +#ifdef CONFIG_ARTIS + artis_fifo_node_cachep = +kmem_cache_create ("artis_fifo_node" , +sizeof (artis_fifo_node_t),0 , +SLAB_MUST_HWCACHE_ALIGN ,NULL ,NULL ); +if (!artis_fifo_node_cachep) +panic ("fork_init(): cannot create artis_fifo_node_t SLAB cache" ); +#endif /* * The default maximum number of threads is set to a safe
@@ -135,6 +150,9 @@ static struct task_struct *dup_task_stru {struct task_struct *tsk;struct thread_info *ti; +#ifdef CONFIG_ARTIS +artis_fifo_node_t *an, def_an=ARTIS_FIFO_NODE_INIT ; +#endif prepare_to_copy (orig);
@@ -148,11 +166,23 @@ static struct task_struct *dup_task_strureturn NULL ; } - *ti = *orig->thread_info; *tsk = *orig; +#ifdef CONFIG_ARTIS + an =alloc_artis_fifo_node (tsk); +if (!an) { +free_task_struct (tsk); +free_thread_info (ti); +return NULL ; + } + + *an = def_an; + an->task = tsk; + tsk->artis_status.fifo_node = an; +#endif + *ti = *orig->thread_info; tsk->thread_info = ti; ti->task = tsk; - +/* One for us, one for whoever does the "release_task()" (usually parent) */ atomic_set (&tsk->usage,2 );return tsk;
kernel/sched.c +1345 -8
1,627 lines not on this page · raw message
PATCH 2/3 ARTiS, an asymmetric real-time scheduler - x86
In reply to Eric PielHere is the architecture dependant part of ARTiS for x86.
arch/i386/Kconfig +26 -0
@@ -528,6 +528,32 @@ config PREEMPT_BKL Say Y here if you are building a kernel for a desktop system. Say N if you are unsure. +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 a + 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. + config X86_UP_APIC bool "Local APIC support on uniprocessors" if !SMP depends on !(X86_VISWS || X86_VOYAGER)
arch/i386/kernel/entry.S +12 -0
@@ -361,13 +361,25 @@ common_interrupt: call do_IRQ jmp ret_from_intr +#ifdef CONFIG_ARTIS #define BUILD_INTERRUPT(name, nr) \ ENTRY(name) \ pushl $nr-256; \ SAVE_ALL \ + call function_artis_migration_disable; \ movl %esp,%eax; \ call smp_/**/name; \ + call function_artis_migration_enable; \ jmp ret_from_intr; +#else +#define BUILD_INTERRUPT(name, nr) \ +ENTRY(name) \ + pushl $nr-256; \ + SAVE_ALL \ + movl %esp,%eax; \ + call smp_/**/name; \ + jmp ret_from_intr; +#endif /* The include is where all of the SMP etc. interrupts come from */ #include "entry_arch.h"
arch/i386/kernel/traps.c +25 -0
@@ -95,6 +95,31 @@ static int kstack_depth_to_print = 24;struct notifier_block *i386die_chain;static DEFINE_SPINLOCK (die_notifier_lock); +#ifdef CONFIG_ARTIS_DEBUG +void artis_put_trace (void **bt,struct task_struct *task,unsigned long * stack) +{ +int i, artis_skip_bt=0 ; +unsigned long addr; + +if (!stack) + stack = (unsigned long *)&stack; +memset (bt,0 ,ARTIS_BT_SIZE *sizeof (void *)); +for (i=artis_skip_bt; i>0 && !kstack_end (stack); ) { + addr = *stack++; +if (kernel_text_address (addr)) + i--; + } +for (i=ARTIS_BT_SIZE ; i>0 && !kstack_end (stack); ) { + addr = *stack++; +if (kernel_text_address (addr)) { + i--; + bt[i]=(void *)addr; + } + } +} +#endif + +int register_die_notifier (struct notifier_block *nb) {int err =0 ;
include/asm-i386/bug.h +9 -2
@@ -2,6 +2,7 @@#define _I386_BUG_H#include <linux/config.h> +#include <linux/artis-macros.h> /* * Tell the user there is some problem.
@@ -10,13 +11,19 @@*/ #ifdef CONFIG_DEBUG_BUGVERBOSE -#define BUG () \ +#define _old_BUG () \ __asm__ __volatile__( "ud2\n" \ "\t.word %c0\n" \ "\t.long %c1\n" \ : : "i" (__LINE__), "i" (__FILE__))#else -#define BUG () __asm__ __volatile__("ud2\n") +#define _old_BUG () __asm__ __volatile__("ud2\n") +#endif + +#if defined(CONFIG_ARTIS_DEBUG ) +#define BUG () ARTIS_BUG(1,0) +#else +#define BUG () _old_BUG()#endif #define HAVE_ARCH_BUG
include/asm-i386/system.h +49 -4
65 lines not on this page · raw message
PATCH 3/3 ARTiS, an asymmetric real-time scheduler - IA-64
In reply to Eric PielHere is the Here is the architecture dependant part of ARTiS for IA-64.
arch/ia64/Kconfig +26 -0
@@ -46,6 +46,32 @@ config GENERIC_IOMAP 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
arch/ia64/kernel/process.c +37 -0
@@ -229,6 +229,43 @@ static inline void play_dead(void) }#endif /* CONFIG_HOTPLUG_CPU */ +#ifdef CONFIG_ARTIS_DEBUG +#include <linux/artis.h> +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 ) {
include/asm-ia64/bug.h +9 -1
@@ -1,12 +1,20 @@#ifndef _ASM_IA64_BUG_H#define _ASM_IA64_BUG_H +#include <linux/artis-macros.h> +#if (__GNUC__ >3 ) || (__GNUC__ ==3 && __GNUC_MINOR__ >=1 )# define ia64_abort () __builtin_trap()#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 should be made generic? */ #define HAVE_ARCH_BUG
include/asm-ia64/system.h +51 -3
77 lines not on this page · raw message