* [Xenomai-help] Limiting Xenomai tasks to one certain core in a dual core system @ 2006-11-22 8:27 M. Koehrer 2006-11-22 8:49 ` [Xenomai-core] " Jan Kiszka 0 siblings, 1 reply; 6+ messages in thread From: M. Koehrer @ 2006-11-22 8:27 UTC (permalink / raw) To: xenomai Hi all, I want to run Xenomai and rtnet (using RTDM) on a dual core CPU. Using the kernel parameter isolcpus I can force the standard Linux tasks to run on one of the cores. The other core should be used exclusively by all real time tasks (including rtnet). I can - of course - pass a parameter on each rt_task_create() call. However how can I force rtnet (using RTDM) to run on this CPU core? Is there a possibility to mask the CPUs to be used globally? This could also avoid to pass the CPU number with each rt_task_create() call. Thanks for any feedback on this. Regards Mathias -- Mathias Koehrer mathias_koehrer@domain.hid Viel oder wenig? Schnell oder langsam? Unbegrenzt surfen + telefonieren ohne Zeit- und Volumenbegrenzung? DAS TOP ANGEBOT JETZT bei Arcor: günstig und schnell mit DSL - das All-Inclusive-Paket für clevere Doppel-Sparer, nur 44,85 inkl. DSL- und ISDN-Grundgebühr! http://www.arcor.de/rd/emf-dsl-2 ^ permalink raw reply [flat|nested] 6+ messages in thread
* [Xenomai-core] Re: [Xenomai-help] Limiting Xenomai tasks to one certain core in a dual core system 2006-11-22 8:27 [Xenomai-help] Limiting Xenomai tasks to one certain core in a dual core system M. Koehrer @ 2006-11-22 8:49 ` Jan Kiszka 2006-11-22 10:29 ` Jan Kiszka 0 siblings, 1 reply; 6+ messages in thread From: Jan Kiszka @ 2006-11-22 8:49 UTC (permalink / raw) To: M. Koehrer; +Cc: xenomai, xenomai-core [-- Attachment #1: Type: text/plain, Size: 1301 bytes --] M. Koehrer wrote: > Hi all, > > I want to run Xenomai and rtnet (using RTDM) on a dual core CPU. > Using the kernel parameter isolcpus I can force the standard Linux tasks > to run on one of the cores. > The other core should be used exclusively by all real time tasks (including rtnet). > I can - of course - pass a parameter on each rt_task_create() call. > However how can I force rtnet (using RTDM) to run on this CPU core? You hit a weak point, see the Task Market in the wiki: "CPU affinity for RTDM threads." We both need an API for RTDM and its application on RTnet. Not complex work, just work... > Is there a possibility to mask the CPUs to be used globally? > This could also avoid to pass the CPU number with each rt_task_create() call. Well, that would actually be an additional way. Yeah, maybe some global CPU mask that controls the affinity on future thread creation. We could export it via /proc so that you can set it right before starting a specific group of applications and drivers. On the long term, a control interface to the Xenomai scheduler would be good so that things like policy, priority, time-slice, or CPU affinity could be manipulated with some command line tool or via /proc after thread creation. Further feedback welcome! Jan [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 249 bytes --] ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [Xenomai-core] Re: [Xenomai-help] Limiting Xenomai tasks to one certain core in a dual core system 2006-11-22 8:49 ` [Xenomai-core] " Jan Kiszka @ 2006-11-22 10:29 ` Jan Kiszka 2006-11-25 11:00 ` [Xenomai-core] " Jan Kiszka 0 siblings, 1 reply; 6+ messages in thread From: Jan Kiszka @ 2006-11-22 10:29 UTC (permalink / raw) To: M. Koehrer; +Cc: xenomai-core [-- Attachment #1.1: Type: text/plain, Size: 661 bytes --] Jan Kiszka wrote: > M. Koehrer wrote: >> Is there a possibility to mask the CPUs to be used globally? >> This could also avoid to pass the CPU number with each rt_task_create() call. > > Well, that would actually be an additional way. Yeah, maybe some global > CPU mask that controls the affinity on future thread creation. We could > export it via /proc so that you can set it right before starting a > specific group of applications and drivers. Some food for thoughts: Here is an experimental implementation of such a global mask. Seems to work, at least I was able to prevent any task creation on a UP box by setting the mask to 0. Jan [-- Attachment #1.2: global-cpu-affinity.patch --] [-- Type: text/plain, Size: 3717 bytes --] --- include/nucleus/pod.h | 2 + ksrc/nucleus/module.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++ ksrc/nucleus/pod.c | 3 ++ 3 files changed, 62 insertions(+) Index: xenomai/include/nucleus/pod.h =================================================================== --- xenomai.orig/include/nucleus/pod.h +++ xenomai/include/nucleus/pod.h @@ -253,6 +253,8 @@ extern u_long nktickdef; extern char *nkmsgbuf; +extern xnarch_cpumask_t nkaffinity; + #define xnprintf(fmt,args...) xnarch_printf(fmt , ##args) #define xnloginfo(fmt,args...) xnarch_loginfo(fmt , ##args) #define xnlogwarn(fmt,args...) xnarch_logwarn(fmt , ##args) Index: xenomai/ksrc/nucleus/module.c =================================================================== --- xenomai.orig/ksrc/nucleus/module.c +++ xenomai/ksrc/nucleus/module.c @@ -688,6 +688,59 @@ static int heap_read_proc(char *page, return len; } +static int affinity_read_proc(char *page, + char **start, + off_t off, int count, int *eof, void *data) +{ + unsigned long val = 0; + int len, cpu; + + for (cpu = 0; cpu < sizeof(val) * 8; cpu++) + if (xnarch_cpu_isset(cpu, nkaffinity)) + val |= (1 << cpu); + + len = sprintf(page, "0x%08lx\n", val); + 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 affinity_write_proc(struct file *file, + const char __user * buffer, + unsigned long count, void *data) +{ + char *end, buf[16]; + unsigned long val; + xnarch_cpumask_t new_affinity; + int n, cpu; + + 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)) + return -EINVAL; + + xnarch_cpus_clear(new_affinity); + for (cpu = 0; cpu < sizeof(val) * 8; cpu++, val >>= 1) + if (val & 1) + xnarch_cpu_set(cpu, new_affinity); + nkaffinity = new_affinity; + + return count; +} + static struct proc_dir_entry *add_proc_leaf(const char *name, read_proc_t rdproc, write_proc_t wrproc, @@ -760,6 +813,9 @@ void xnpod_init_proc(void) add_proc_leaf("heap", &heap_read_proc, NULL, NULL, rthal_proc_root); + add_proc_leaf("affinity", &affinity_read_proc, &affinity_write_proc, + NULL, rthal_proc_root); + #ifdef CONFIG_XENO_OPT_PERVASIVE iface_proc_root = create_proc_entry("interfaces", S_IFDIR, rthal_proc_root); @@ -778,6 +834,7 @@ void xnpod_delete_proc(void) remove_proc_entry("interfaces", rthal_proc_root); #endif /* CONFIG_XENO_OPT_PERVASIVE */ + remove_proc_entry("affinity", rthal_proc_root); remove_proc_entry("heap", rthal_proc_root); remove_proc_entry("irq", rthal_proc_root); remove_proc_entry("timer", rthal_proc_root); Index: xenomai/ksrc/nucleus/pod.c =================================================================== --- xenomai.orig/ksrc/nucleus/pod.c +++ xenomai/ksrc/nucleus/pod.c @@ -70,6 +70,8 @@ MODULE_PARM_DESC(tick_arg, "Fixed clock char *nkmsgbuf = NULL; +xnarch_cpumask_t nkaffinity = XNPOD_ALL_CPUS; + const char *xnpod_fatal_helper(const char *format, ...) { const unsigned nr_cpus = xnarch_num_online_cpus(); @@ -915,6 +917,7 @@ int xnpod_start_thread(xnthread_t *threa xnlock_get_irqsave(&nklock, s); thread->affinity = xnarch_cpu_online_map; + xnarch_cpus_and(thread->affinity, nkaffinity, thread->affinity); xnarch_cpus_and(thread->affinity, affinity, thread->affinity); if (xnarch_cpus_empty(thread->affinity)) { [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 250 bytes --] ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [Xenomai-core] Limiting Xenomai tasks to one certain core in a dual core system 2006-11-22 10:29 ` Jan Kiszka @ 2006-11-25 11:00 ` Jan Kiszka 2006-11-25 15:12 ` Jan Kiszka 0 siblings, 1 reply; 6+ messages in thread From: Jan Kiszka @ 2006-11-25 11:00 UTC (permalink / raw) To: Philippe Gerum; +Cc: M. Koehrer, xenomai-core [-- Attachment #1.1: Type: text/plain, Size: 2156 bytes --] Jan Kiszka wrote: > Jan Kiszka wrote: >> M. Koehrer wrote: >>> Is there a possibility to mask the CPUs to be used globally? >>> This could also avoid to pass the CPU number with each rt_task_create() call. >> Well, that would actually be an additional way. Yeah, maybe some global >> CPU mask that controls the affinity on future thread creation. We could >> export it via /proc so that you can set it right before starting a >> specific group of applications and drivers. > > Some food for thoughts: > > Here is an experimental implementation of such a global mask. Seems to > work, at least I was able to prevent any task creation on a UP box by > setting the mask to 0. Even more brain exercises: This is version 2 of my patch, consequently applying the global mask idea also on IRQ affinity. I think this simple mechanism can solve quite a few basic SMP setup issue by forcing all user threads, driver threads, and IRQs that are created/attached during a certain period to a specific CPU set. That's the theory. In practice, things look not that clear ATM. I noticed some oddity on a 4-way qemu box running the latency test and hacked the attached enhancement for /proc/xenomai/sched. This is what I get on that box: > root@domain.hid :/root# cat /proc/xenomai/sched > CPU AFFINITY PID PRI PERIOD TIMEOUT STAT NAME > 0 00000001 0 -1 0 0 R ROOT/0 > 1 00000002 0 -1 0 0 R ROOT/1 > 2 00000004 0 -1 0 0 R ROOT/2 > 3 00000008 0 -1 0 0 R ROOT/3 > 0 0000000c 917 0 0 0 W display-916 > 2 0000000c 918 99 5000000 1 D sampling-916 > root@domain.hid :/root# cat /proc/xenomai/affinity > 0x0000000c Philippe, anyone else: This scheduling of display-916 is not like as it should be, is it? Jan PS: /proc output of IRQ affinities would be nice as well, but we are lacking the require abstraction by ipipe ATM, something to read out the currently set affinity. [-- Attachment #1.2: global-cpu-affinity-v2.patch --] [-- Type: text/plain, Size: 4204 bytes --] --- include/nucleus/pod.h | 2 + ksrc/nucleus/intr.c | 3 ++ ksrc/nucleus/module.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++ ksrc/nucleus/pod.c | 3 ++ 4 files changed, 65 insertions(+) Index: xenomai/include/nucleus/pod.h =================================================================== --- xenomai.orig/include/nucleus/pod.h +++ xenomai/include/nucleus/pod.h @@ -253,6 +253,8 @@ extern u_long nktickdef; extern char *nkmsgbuf; +extern xnarch_cpumask_t nkaffinity; + #define xnprintf(fmt,args...) xnarch_printf(fmt , ##args) #define xnloginfo(fmt,args...) xnarch_loginfo(fmt , ##args) #define xnlogwarn(fmt,args...) xnarch_logwarn(fmt , ##args) Index: xenomai/ksrc/nucleus/intr.c =================================================================== --- xenomai.orig/ksrc/nucleus/intr.c +++ xenomai/ksrc/nucleus/intr.c @@ -626,6 +626,9 @@ int xnintr_attach(xnintr_t *intr, void * xnlock_get_irqsave(&intrlock, s); +#ifdef CONFIG_SMP + xnarch_set_irq_affinity(intr->irq, nkaffinity); +#endif /* CONFIG_SMP */ err = xnintr_irq_attach(intr); xnlock_put_irqrestore(&intrlock, s); Index: xenomai/ksrc/nucleus/module.c =================================================================== --- xenomai.orig/ksrc/nucleus/module.c +++ xenomai/ksrc/nucleus/module.c @@ -688,6 +688,59 @@ static int heap_read_proc(char *page, return len; } +static int affinity_read_proc(char *page, + char **start, + off_t off, int count, int *eof, void *data) +{ + unsigned long val = 0; + int len, cpu; + + for (cpu = 0; cpu < sizeof(val) * 8; cpu++) + if (xnarch_cpu_isset(cpu, nkaffinity)) + val |= (1 << cpu); + + len = sprintf(page, "%08lx\n", val); + 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 affinity_write_proc(struct file *file, + const char __user * buffer, + unsigned long count, void *data) +{ + char *end, buf[16]; + unsigned long val; + xnarch_cpumask_t new_affinity; + int n, cpu; + + 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)) + return -EINVAL; + + xnarch_cpus_clear(new_affinity); + for (cpu = 0; cpu < sizeof(val) * 8; cpu++, val >>= 1) + if (val & 1) + xnarch_cpu_set(cpu, new_affinity); + nkaffinity = new_affinity; + + return count; +} + static struct proc_dir_entry *add_proc_leaf(const char *name, read_proc_t rdproc, write_proc_t wrproc, @@ -760,6 +813,9 @@ void xnpod_init_proc(void) add_proc_leaf("heap", &heap_read_proc, NULL, NULL, rthal_proc_root); + add_proc_leaf("affinity", &affinity_read_proc, &affinity_write_proc, + NULL, rthal_proc_root); + #ifdef CONFIG_XENO_OPT_PERVASIVE iface_proc_root = create_proc_entry("interfaces", S_IFDIR, rthal_proc_root); @@ -778,6 +834,7 @@ void xnpod_delete_proc(void) remove_proc_entry("interfaces", rthal_proc_root); #endif /* CONFIG_XENO_OPT_PERVASIVE */ + remove_proc_entry("affinity", rthal_proc_root); remove_proc_entry("heap", rthal_proc_root); remove_proc_entry("irq", rthal_proc_root); remove_proc_entry("timer", rthal_proc_root); Index: xenomai/ksrc/nucleus/pod.c =================================================================== --- xenomai.orig/ksrc/nucleus/pod.c +++ xenomai/ksrc/nucleus/pod.c @@ -70,6 +70,8 @@ MODULE_PARM_DESC(tick_arg, "Fixed clock char *nkmsgbuf = NULL; +xnarch_cpumask_t nkaffinity = XNPOD_ALL_CPUS; + const char *xnpod_fatal_helper(const char *format, ...) { const unsigned nr_cpus = xnarch_num_online_cpus(); @@ -915,6 +917,7 @@ int xnpod_start_thread(xnthread_t *threa xnlock_get_irqsave(&nklock, s); thread->affinity = xnarch_cpu_online_map; + xnarch_cpus_and(thread->affinity, nkaffinity, thread->affinity); xnarch_cpus_and(thread->affinity, affinity, thread->affinity); if (xnarch_cpus_empty(thread->affinity)) { [-- Attachment #1.3: print-thread-affinity.patch --] [-- Type: text/plain, Size: 1631 bytes --] --- ksrc/nucleus/module.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) Index: xenomai/ksrc/nucleus/module.c =================================================================== --- xenomai.orig/ksrc/nucleus/module.c +++ xenomai/ksrc/nucleus/module.c @@ -103,6 +103,7 @@ struct sched_seq_iterator { xnticks_t period; xnticks_t timeout; xnflags_t status; + xnarch_cpumask_t affinity; } sched_info[1]; }; @@ -145,8 +146,9 @@ static int sched_seq_show(struct seq_fil char sbuf[64], pbuf[16]; if (v == SEQ_START_TOKEN) - seq_printf(seq, "%-3s %-6s %-8s %-8s %-10s %-10s %s\n", - "CPU", "PID", "PRI", "PERIOD", "TIMEOUT", "STAT", "NAME"); + seq_printf(seq, "%-3s %-8s %-6s %-8s %-8s %-10s %-10s %s\n", + "CPU", "AFFINITY", "PID", "PRI", "PERIOD", "TIMEOUT", + "STAT", "NAME"); else { struct sched_seq_info *p = (struct sched_seq_info *)v; @@ -156,8 +158,9 @@ static int sched_seq_show(struct seq_fil else snprintf(pbuf, sizeof(pbuf), "%3d", p->cprio); - seq_printf(seq, "%3u %-6d %-8s %-8Lu %-10Lu %-10s %s\n", + seq_printf(seq, "%3u %08x %-6d %-8s %-8Lu %-10Lu %-10s %s\n", p->cpu, + p->affinity, p->pid, pbuf, p->period, @@ -237,6 +240,7 @@ static int sched_seq_open(struct inode * iter->sched_info[n].period = xnthread_get_period(thread); iter->sched_info[n].timeout = xnthread_get_timeout(thread, iter->start_time); iter->sched_info[n].status = thread->status; + iter->sched_info[n].affinity = thread->affinity; holder = nextq(&nkpod->threadq, holder); [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 250 bytes --] ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [Xenomai-core] Limiting Xenomai tasks to one certain core in a dual core system 2006-11-25 11:00 ` [Xenomai-core] " Jan Kiszka @ 2006-11-25 15:12 ` Jan Kiszka 2006-11-25 18:13 ` Philippe Gerum 0 siblings, 1 reply; 6+ messages in thread From: Jan Kiszka @ 2006-11-25 15:12 UTC (permalink / raw) To: Philippe Gerum; +Cc: M. Koehrer, xenomai-core [-- Attachment #1.1: Type: text/plain, Size: 2015 bytes --] Jan Kiszka wrote: > This is version 2 of my patch, consequently applying the global mask > idea also on IRQ affinity. I think this simple mechanism can solve quite > a few basic SMP setup issue by forcing all user threads, driver threads, > and IRQs that are created/attached during a certain period to a specific > CPU set. > > That's the theory. In practice, things look not that clear ATM. I > noticed some oddity on a 4-way qemu box running the latency test and > hacked the attached enhancement for /proc/xenomai/sched. This is what I > get on that box: > >> root@domain.hid :/root# cat /proc/xenomai/sched >> CPU AFFINITY PID PRI PERIOD TIMEOUT STAT NAME >> 0 00000001 0 -1 0 0 R ROOT/0 >> 1 00000002 0 -1 0 0 R ROOT/1 >> 2 00000004 0 -1 0 0 R ROOT/2 >> 3 00000008 0 -1 0 0 R ROOT/3 >> 0 0000000c 917 0 0 0 W display-916 >> 2 0000000c 918 99 5000000 1 D sampling-916 >> root@domain.hid :/root# cat /proc/xenomai/affinity >> 0x0000000c > [I should really stop believing heavy issues can be solved with light-weight patches...] OK, after reading a bit more in what I was hacking on, I'm starting to understand the CPU selection mechanisms of shadow threads. Here comes version 3 of the patch. Now it actually forces all threads to the desired CPUs. The reason why I failed with previous approaches could even be a SMP bug of the original code. The Linux affinity of a shadow thread was only set if no u_completion has been passed to xnshadow_map - which affected native threads e.g. So I reordered the code, and it works. I also changed the policy of /proc/xenoami/affinity. It will now only override the mapping if the user didn't provide an explicit mask. I think this provides more flexibility. Comment? Jan [-- Attachment #1.2: global-cpu-affinity-v3.patch --] [-- Type: text/plain, Size: 5329 bytes --] --- include/nucleus/pod.h | 2 + ksrc/nucleus/intr.c | 3 ++ ksrc/nucleus/module.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++ ksrc/nucleus/pod.c | 4 ++- ksrc/nucleus/shadow.c | 15 +++++-------- 5 files changed, 71 insertions(+), 10 deletions(-) Index: xenomai/include/nucleus/pod.h =================================================================== --- xenomai.orig/include/nucleus/pod.h +++ xenomai/include/nucleus/pod.h @@ -253,6 +253,8 @@ extern u_long nktickdef; extern char *nkmsgbuf; +extern xnarch_cpumask_t nkaffinity; + #define xnprintf(fmt,args...) xnarch_printf(fmt , ##args) #define xnloginfo(fmt,args...) xnarch_loginfo(fmt , ##args) #define xnlogwarn(fmt,args...) xnarch_logwarn(fmt , ##args) Index: xenomai/ksrc/nucleus/intr.c =================================================================== --- xenomai.orig/ksrc/nucleus/intr.c +++ xenomai/ksrc/nucleus/intr.c @@ -626,6 +626,9 @@ int xnintr_attach(xnintr_t *intr, void * xnlock_get_irqsave(&intrlock, s); +#ifdef CONFIG_SMP + xnarch_set_irq_affinity(intr->irq, nkaffinity); +#endif /* CONFIG_SMP */ err = xnintr_irq_attach(intr); xnlock_put_irqrestore(&intrlock, s); Index: xenomai/ksrc/nucleus/module.c =================================================================== --- xenomai.orig/ksrc/nucleus/module.c +++ xenomai/ksrc/nucleus/module.c @@ -688,6 +688,59 @@ static int heap_read_proc(char *page, return len; } +static int affinity_read_proc(char *page, + char **start, + off_t off, int count, int *eof, void *data) +{ + unsigned long val = 0; + int len, cpu; + + for (cpu = 0; cpu < sizeof(val) * 8; cpu++) + if (xnarch_cpu_isset(cpu, nkaffinity)) + val |= (1 << cpu); + + len = sprintf(page, "%08lx\n", val); + 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 affinity_write_proc(struct file *file, + const char __user * buffer, + unsigned long count, void *data) +{ + char *end, buf[16]; + unsigned long val; + xnarch_cpumask_t new_affinity; + int n, cpu; + + 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)) + return -EINVAL; + + xnarch_cpus_clear(new_affinity); + for (cpu = 0; cpu < sizeof(val) * 8; cpu++, val >>= 1) + if (val & 1) + xnarch_cpu_set(cpu, new_affinity); + nkaffinity = new_affinity; + + return count; +} + static struct proc_dir_entry *add_proc_leaf(const char *name, read_proc_t rdproc, write_proc_t wrproc, @@ -760,6 +813,9 @@ void xnpod_init_proc(void) add_proc_leaf("heap", &heap_read_proc, NULL, NULL, rthal_proc_root); + add_proc_leaf("affinity", &affinity_read_proc, &affinity_write_proc, + NULL, rthal_proc_root); + #ifdef CONFIG_XENO_OPT_PERVASIVE iface_proc_root = create_proc_entry("interfaces", S_IFDIR, rthal_proc_root); @@ -778,6 +834,7 @@ void xnpod_delete_proc(void) remove_proc_entry("interfaces", rthal_proc_root); #endif /* CONFIG_XENO_OPT_PERVASIVE */ + remove_proc_entry("affinity", rthal_proc_root); remove_proc_entry("heap", rthal_proc_root); remove_proc_entry("irq", rthal_proc_root); remove_proc_entry("timer", rthal_proc_root); Index: xenomai/ksrc/nucleus/pod.c =================================================================== --- xenomai.orig/ksrc/nucleus/pod.c +++ xenomai/ksrc/nucleus/pod.c @@ -70,6 +70,8 @@ MODULE_PARM_DESC(tick_arg, "Fixed clock char *nkmsgbuf = NULL; +xnarch_cpumask_t nkaffinity = XNPOD_ALL_CPUS; + const char *xnpod_fatal_helper(const char *format, ...) { const unsigned nr_cpus = xnarch_num_online_cpus(); @@ -910,7 +912,7 @@ int xnpod_start_thread(xnthread_t *threa return -EBUSY; if (xnarch_cpus_empty(affinity)) - affinity = XNARCH_CPU_MASK_ALL; + affinity = nkaffinity; xnlock_get_irqsave(&nklock, s); Index: xenomai/ksrc/nucleus/shadow.c =================================================================== --- xenomai.orig/ksrc/nucleus/shadow.c +++ xenomai/ksrc/nucleus/shadow.c @@ -853,20 +853,17 @@ int xnshadow_map(xnthread_t *thread, xnc xnshadow_thrptd(current) = thread; xnpod_suspend_thread(thread, XNRELAX, XN_INFINITE, NULL); + affinity = thread->affinity; + if (xnarch_cpus_empty(affinity)) + affinity = nkaffinity; + set_cpus_allowed(current, affinity); + if (u_completion) { xnshadow_signal_completion(u_completion, 0); return 0; } - /* Nobody waits for us, so we may start the shadow immediately - after having forced the CPU affinity to the current - processor. Note that we don't use smp_processor_id() to prevent - kernel debug stuff to yell at us for calling it in a preemptible - section of code. */ - - affinity = xnarch_cpumask_of_cpu(rthal_processor_id()); - set_cpus_allowed(current, affinity); - + /* Nobody waits for us, so we may start the shadow immediately. */ mode = thread->rrperiod != XN_INFINITE ? XNRRB : 0; xnpod_start_thread(thread, mode, 0, affinity, NULL, NULL); [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 250 bytes --] ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [Xenomai-core] Limiting Xenomai tasks to one certain core in a dual core system 2006-11-25 15:12 ` Jan Kiszka @ 2006-11-25 18:13 ` Philippe Gerum 0 siblings, 0 replies; 6+ messages in thread From: Philippe Gerum @ 2006-11-25 18:13 UTC (permalink / raw) To: Jan Kiszka; +Cc: M. Koehrer, xenomai-core On Sat, 2006-11-25 at 16:12 +0100, Jan Kiszka wrote: [...] > OK, after reading a bit more in what I was hacking on, I'm starting to > understand the CPU selection mechanisms of shadow threads. Here comes > version 3 of the patch. Now it actually forces all threads to the > desired CPUs. > > The reason why I failed with previous approaches could even be a SMP bug > of the original code. The Linux affinity of a shadow thread was only set > if no u_completion has been passed to xnshadow_map - which affected > native threads e.g. So I reordered the code, and it works. > The root issue is why LO_START_REQ which normally sets the affinity at the end of the create -> start protocol did not get a chance to run. Likely that the newly mapped thread was still in a runnable state when tested from xnshadow_start(), which might be due to a kernel preemption artefact. > I also changed the policy of /proc/xenoami/affinity. It will now only > override the mapping if the user didn't provide an explicit mask. I > think this provides more flexibility. > > Comment? [...] > const unsigned nr_cpus = xnarch_num_online_cpus(); > @@ -910,7 +912,7 @@ int xnpod_start_thread(xnthread_t *threa > return -EBUSY; > > if (xnarch_cpus_empty(affinity)) > - affinity = XNARCH_CPU_MASK_ALL; > + affinity = nkaffinity; This is fairly significant API change that should be loudly documented, especially because its behaviour now depends on a new variable. > > xnlock_get_irqsave(&nklock, s); > > Index: xenomai/ksrc/nucleus/shadow.c > =================================================================== > --- xenomai.orig/ksrc/nucleus/shadow.c > +++ xenomai/ksrc/nucleus/shadow.c > @@ -853,20 +853,17 @@ int xnshadow_map(xnthread_t *thread, xnc > xnshadow_thrptd(current) = thread; > xnpod_suspend_thread(thread, XNRELAX, XN_INFINITE, NULL); > > + affinity = thread->affinity; > + if (xnarch_cpus_empty(affinity)) > + affinity = nkaffinity; This won't work as expected. The thread->affinity info should not be used in the xnshadow_map() context, because it has not been set yet (xnshadow_map() should be seen as the equivalent to xnpod_init_thread() for shadow threads). This information is set by the nucleus by a call to xnpod_start_thread(), so one step later in the task spawn protocol. Luckily, it seems to be zeroed in your test, but it has not been initialized yet. > + set_cpus_allowed(current, affinity); > + This should be ok to pin the newly mapped task to a CPU early on, even in the auto-start configuration, but that case, we should kill the now redundant set_cpus_allowed() from LO_START_REQ. Actually, we would be better of killing LO_START_REQ entirely, since it would not make sense anymore, compared to a regular WAKEUP request. -- Philippe. ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2006-11-25 18:13 UTC | newest] Thread overview: 6+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2006-11-22 8:27 [Xenomai-help] Limiting Xenomai tasks to one certain core in a dual core system M. Koehrer 2006-11-22 8:49 ` [Xenomai-core] " Jan Kiszka 2006-11-22 10:29 ` Jan Kiszka 2006-11-25 11:00 ` [Xenomai-core] " Jan Kiszka 2006-11-25 15:12 ` Jan Kiszka 2006-11-25 18:13 ` Philippe Gerum
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.