From mboxrd@z Thu Jan 1 00:00:00 1970 Message-ID: <45685D6D.7010802@domain.hid> Date: Sat, 25 Nov 2006 16:12:45 +0100 From: Jan Kiszka MIME-Version: 1.0 Subject: Re: [Xenomai-core] Limiting Xenomai tasks to one certain core in a dual core system References: <13096879.1164184060512.JavaMail.ngmail@domain.hid> <45640F06.5000005@domain.hid> <456426A7.3030305@domain.hid> <45682250.7070403@domain.hid> In-Reply-To: <45682250.7070403@domain.hid> Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="------------enigB9F327D1326092BE249EDE07" Sender: jan.kiszka@domain.hid List-Id: "Xenomai life and development \(bug reports, patches, discussions\)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Philippe Gerum Cc: "M. Koehrer" , xenomai-core This is an OpenPGP/MIME signed message (RFC 2440 and 3156) --------------enigB9F327D1326092BE249EDE07 Content-Type: multipart/mixed; boundary="------------050406040907050107070100" This is a multi-part message in MIME format. --------------050406040907050107070100 Content-Type: text/plain; charset=ISO-8859-15 Content-Transfer-Encoding: quoted-printable 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 quit= e > 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 specifi= c > CPU set. >=20 > 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: >=20 >> root@domain.hid :/root# cat /proc/xenomai/sched=20 >> 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-9= 16 >> 2 0000000c 918 99 5000000 1 D sampling-= 916 >> root@domain.hid :/root# cat /proc/xenomai/affinity=20 >> 0x0000000c >=20 [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 --------------050406040907050107070100 Content-Type: text/plain; name="global-cpu-affinity-v3.patch" Content-Transfer-Encoding: quoted-printable Content-Disposition: inline; filename="global-cpu-affinity-v3.patch" --- 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 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- xenomai.orig/include/nucleus/pod.h +++ xenomai/include/nucleus/pod.h @@ -253,6 +253,8 @@ extern u_long nktickdef; =20 extern char *nkmsgbuf; =20 +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 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- xenomai.orig/ksrc/nucleus/intr.c +++ xenomai/ksrc/nucleus/intr.c @@ -626,6 +626,9 @@ int xnintr_attach(xnintr_t *intr, void * =20 xnlock_get_irqsave(&intrlock, s); =20 +#ifdef CONFIG_SMP + xnarch_set_irq_affinity(intr->irq, nkaffinity); +#endif /* CONFIG_SMP */ err =3D xnintr_irq_attach(intr); =20 xnlock_put_irqrestore(&intrlock, s); Index: xenomai/ksrc/nucleus/module.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- xenomai.orig/ksrc/nucleus/module.c +++ xenomai/ksrc/nucleus/module.c @@ -688,6 +688,59 @@ static int heap_read_proc(char *page, return len; } =20 +static int affinity_read_proc(char *page, + char **start, + off_t off, int count, int *eof, void *data) +{ + unsigned long val =3D 0; + int len, cpu; + + for (cpu =3D 0; cpu < sizeof(val) * 8; cpu++) + if (xnarch_cpu_isset(cpu, nkaffinity)) + val |=3D (1 << cpu); + + len =3D sprintf(page, "%08lx\n", val); + len -=3D off; + if (len <=3D off + count) + *eof =3D 1; + *start =3D page + off; + if (len > count) + len =3D count; + if (len < 0) + len =3D 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 =3D count > sizeof(buf) - 1 ? sizeof(buf) - 1 : count; + + if (copy_from_user(buf, buffer, n)) + return -EFAULT; + + buf[n] =3D '\0'; + val =3D simple_strtol(buf, &end, 0); + + if (*end !=3D '\0' && !isspace(*end)) + return -EINVAL; + + xnarch_cpus_clear(new_affinity); + for (cpu =3D 0; cpu < sizeof(val) * 8; cpu++, val >>=3D 1) + if (val & 1) + xnarch_cpu_set(cpu, new_affinity); + nkaffinity =3D 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) =20 add_proc_leaf("heap", &heap_read_proc, NULL, NULL, rthal_proc_root); =20 + add_proc_leaf("affinity", &affinity_read_proc, &affinity_write_proc, + NULL, rthal_proc_root); + #ifdef CONFIG_XENO_OPT_PERVASIVE iface_proc_root =3D create_proc_entry("interfaces", S_IFDIR, rthal_proc_root); @@ -778,6 +834,7 @@ void xnpod_delete_proc(void) =20 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 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- xenomai.orig/ksrc/nucleus/pod.c +++ xenomai/ksrc/nucleus/pod.c @@ -70,6 +70,8 @@ MODULE_PARM_DESC(tick_arg, "Fixed clock=20 =20 char *nkmsgbuf =3D NULL; =20 +xnarch_cpumask_t nkaffinity =3D XNPOD_ALL_CPUS; + const char *xnpod_fatal_helper(const char *format, ...) { const unsigned nr_cpus =3D xnarch_num_online_cpus(); @@ -910,7 +912,7 @@ int xnpod_start_thread(xnthread_t *threa return -EBUSY; =20 if (xnarch_cpus_empty(affinity)) - affinity =3D XNARCH_CPU_MASK_ALL; + affinity =3D nkaffinity; =20 xnlock_get_irqsave(&nklock, s); =20 Index: xenomai/ksrc/nucleus/shadow.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- 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) =3D thread; xnpod_suspend_thread(thread, XNRELAX, XN_INFINITE, NULL); =20 + affinity =3D thread->affinity; + if (xnarch_cpus_empty(affinity)) + affinity =3D nkaffinity; + set_cpus_allowed(current, affinity); + if (u_completion) { xnshadow_signal_completion(u_completion, 0); return 0; } =20 - /* 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 =3D xnarch_cpumask_of_cpu(rthal_processor_id()); - set_cpus_allowed(current, affinity); - + /* Nobody waits for us, so we may start the shadow immediately. */ mode =3D thread->rrperiod !=3D XN_INFINITE ? XNRRB : 0; xnpod_start_thread(thread, mode, 0, affinity, NULL, NULL); =20 --------------050406040907050107070100-- --------------enigB9F327D1326092BE249EDE07 Content-Type: application/pgp-signature; name="signature.asc" Content-Description: OpenPGP digital signature Content-Disposition: attachment; filename="signature.asc" -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.5 (MingW32) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQFFaF1tniDOoMHTA+kRAoHbAJ9/kLpQntqROvzdPCvGX7yJndND7wCdHcDo 5/skysgDD50IO6/CRemj/Pc= =aMZl -----END PGP SIGNATURE----- --------------enigB9F327D1326092BE249EDE07--