All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jan Kiszka <jan.kiszka@domain.hid>
To: Philippe Gerum <rpm@xenomai.org>
Cc: "M. Koehrer" <mathias_koehrer@domain.hid>,
	xenomai-core <xenomai@xenomai.org>
Subject: Re: [Xenomai-core] Limiting Xenomai tasks to one certain core in a dual core system
Date: Sat, 25 Nov 2006 12:00:32 +0100	[thread overview]
Message-ID: <45682250.7070403@domain.hid> (raw)
In-Reply-To: <456426A7.3030305@domain.hid>


[-- 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 --]

  reply	other threads:[~2006-11-25 11:00 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
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     ` Jan Kiszka [this message]
2006-11-25 15:12       ` [Xenomai-core] " Jan Kiszka
2006-11-25 18:13         ` Philippe Gerum

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=45682250.7070403@domain.hid \
    --to=jan.kiszka@domain.hid \
    --cc=mathias_koehrer@domain.hid \
    --cc=rpm@xenomai.org \
    --cc=xenomai@xenomai.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.