From: Peter Zijlstra <a.p.zijlstra@chello.nl>
To: Ingo Molnar <mingo@elte.hu>
Cc: Thomas Gleixner <tglx@linutronix.de>,
Oleg Nesterov <oleg@tv-sign.ru>,
Steven Rostedt <rostedt@goodmis.org>, Paul Jackson <pj@sgi.com>,
Max Krasnyanskiy <maxk@qualcomm.com>,
linux-kernel@vger.kernel.org,
David Rientjes <rientjes@google.com>
Subject: [RFC/PATCH] cpuset: cpuset irq affinities
Date: Fri, 29 Feb 2008 19:55:51 +0100 [thread overview]
Message-ID: <1204311351.6243.130.camel@lappy> (raw)
In-Reply-To: <20080227222103.673194000@chello.nl>
Hi Paul,
How about something like this; along with the in-kernel version
of /cgroup/boot this could also provide the desired semantics.
Another benefit of this approach would be that it no longer requires
PF_THREAD_BIND, as we'd only stick unbounded kthreads into that cgroup.
(compile tested only)
---
Subject: cpuset: cpuset irq affinities
Allow for an association between cpusets and irqs.
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
---
include/linux/irq.h | 9 ++
kernel/cpuset.c | 160 ++++++++++++++++++++++++++++++++++++++++++++++++++++
kernel/irq/manage.c | 19 ++++++
3 files changed, 188 insertions(+)
Index: linux-2.6-2/include/linux/irq.h
===================================================================
--- linux-2.6-2.orig/include/linux/irq.h
+++ linux-2.6-2/include/linux/irq.h
@@ -174,11 +174,20 @@ struct irq_desc {
#ifdef CONFIG_PROC_FS
struct proc_dir_entry *dir;
#endif
+#ifdef CONFIG_CPUSETS
+ struct cpuset *cs;
+#endif
const char *name;
} ____cacheline_internodealigned_in_smp;
extern struct irq_desc irq_desc[NR_IRQS];
+struct irq_iterator {
+ int (*function)(struct irq_iterator *, int, struct irq_desc *);
+};
+
+extern int irq_iterator(struct irq_iterator *);
+
/*
* Migration helpers for obsolete names, they will go away:
*/
Index: linux-2.6-2/kernel/cpuset.c
===================================================================
--- linux-2.6-2.orig/kernel/cpuset.c
+++ linux-2.6-2/kernel/cpuset.c
@@ -50,6 +50,9 @@
#include <linux/time.h>
#include <linux/backing-dev.h>
#include <linux/sort.h>
+#ifdef CONFIG_GENERIC_HARDIRQS
+#include <linux/irq.h>
+#endif
#include <asm/uaccess.h>
#include <asm/atomic.h>
@@ -732,6 +735,44 @@ void cpuset_change_cpumask(struct task_s
set_cpus_allowed(tsk, (cgroup_cs(scan->cg))->cpus_allowed);
}
+#ifdef CONFIG_GENERIC_HARDIRQS
+struct cpuset_irq_cpumask {
+ struct irq_iterator v;
+ struct cpuset *cs;
+ cpumask_t mask;
+};
+
+static int
+update_irq_cpumask(struct irq_iterator *v, int irq, struct irq_desc *desc)
+{
+ struct cpuset_irq_cpumask *s =
+ container_of(v, struct cpuset_irq_cpumask, v);
+
+ if (desc->cs != s->cs)
+ return 0;
+
+ irq_set_affinity(irq, s->mask);
+
+ return 0;
+}
+
+static void update_irqs_cpumask(struct cpuset *cs)
+{
+ struct cpuset_irq_cpumask s = {
+ .v = { .function = update_irq_cpumask },
+ .cs = cs,
+ };
+
+ cpus_and(s.mask, cpu_online_map, cs->cpus_allowed);
+
+ irq_iterator(&s.v);
+}
+#else
+static void update_irqs_cpumask(struct cpuset *cs)
+{
+}
+#endif
+
/**
* update_cpumask - update the cpus_allowed mask of a cpuset and all tasks in it
* @cs: the cpuset to consider
@@ -795,6 +836,8 @@ static int update_cpumask(struct cpuset
cgroup_scan_tasks(&scan);
heap_free(&heap);
+ update_irqs_cpumask(cs);
+
if (is_load_balanced)
rebuild_sched_domains();
return 0;
@@ -1056,6 +1099,52 @@ static int update_flag(cpuset_flagbits_t
return 0;
}
+#ifdef CONFIG_GENERIC_HARDIRQS
+struct cpuset_irq_update {
+ struct irq_iterator v;
+ struct cpuset *cs;
+ int irq;
+};
+
+static int
+cpuset_update_irq(struct irq_iterator *v, int irq, struct irq_desc *desc)
+{
+ struct cpuset_irq_update *s =
+ container_of(v, struct cpuset_irq_update, v);
+ cpumask_t online_set;
+ int ret;
+
+ if (irq != s->irq)
+ return 0;
+
+ cpus_and(online_set, cpu_online_map, s->cs->cpus_allowed);
+
+ ret = irq_set_affinity(irq, online_set);
+ if (!ret)
+ desc->cs = s->cs;
+
+ return ret;
+}
+
+static int update_irqs(struct cpuset *cs, char *buf)
+{
+ struct cpuset_irq_update s = {
+ .v = { .function = cpuset_update_irq },
+ .cs = cs,
+ };
+
+ if (sscanf(buf, "%d", &s.irq) != 1)
+ return -EIO;
+
+ return irq_iterator(&s.v);
+}
+#else
+static int update_irqs(struct cpuset *cs, char *buf)
+{
+ return 0;
+}
+#endif
+
/*
* Frequency meter - How fast is some event occurring?
*
@@ -1206,6 +1295,7 @@ typedef enum {
FILE_MEMORY_PRESSURE,
FILE_SPREAD_PAGE,
FILE_SPREAD_SLAB,
+ FILE_IRQS,
} cpuset_filetype_t;
static ssize_t cpuset_common_file_write(struct cgroup *cont,
@@ -1273,6 +1363,9 @@ static ssize_t cpuset_common_file_write(
retval = update_flag(CS_SPREAD_SLAB, cs, buffer);
cs->mems_generation = cpuset_mems_generation++;
break;
+ case FILE_IRQS:
+ retval = update_irqs(cs, buffer);
+ break;
default:
retval = -EINVAL;
goto out2;
@@ -1321,6 +1414,59 @@ static int cpuset_sprintf_memlist(char *
return nodelist_scnprintf(page, PAGE_SIZE, mask);
}
+#ifdef CONFIG_GENERIC_HARDIRQS
+struct cpuset_irq_print {
+ struct irq_iterator v;
+ struct cpuset *cs;
+ char *buf;
+ int len;
+ int buflen;
+};
+
+static int
+cpuset_sprintf_irq(struct irq_iterator *v, int irq, struct irq_desc *desc)
+{
+ struct cpuset_irq_print *s =
+ container_of(v, struct cpuset_irq_print, v);
+
+ if (desc->cs != s->cs)
+ return 0;
+
+ if (s->len > 0)
+ s->len += scnprintf(s->buf + s->len, s->buflen - s->len, " ");
+ s->len += scnprintf(s->buf + s->len, s->buflen - s->len, "%d", irq);
+
+ return 0;
+}
+
+static int cpuset_sprintf_irqlist(char *page, struct cpuset *cs)
+{
+ int ret;
+
+ struct cpuset_irq_print s = {
+ .v = { .function = cpuset_sprintf_irq },
+ .cs = cs,
+ .buf = page,
+ .len = 0,
+ .buflen = PAGE_SIZE,
+ };
+
+ mutex_lock(&callback_mutex);
+ ret = irq_iterator(&s.v);
+ mutex_unlock(&callback_mutex);
+
+ if (!ret)
+ ret = s.len;
+
+ return ret;
+}
+#else
+static int cpuset_sprintf_irqlist(char *page, struct cpuset *cs)
+{
+ return 0;
+}
+#endif
+
static ssize_t cpuset_common_file_read(struct cgroup *cont,
struct cftype *cft,
struct file *file,
@@ -1369,6 +1515,9 @@ static ssize_t cpuset_common_file_read(s
case FILE_SPREAD_SLAB:
*s++ = is_spread_slab(cs) ? '1' : '0';
break;
+ case FILE_IRQS:
+ s += cpuset_sprintf_irqlist(s, cs);
+ break;
default:
retval = -EINVAL;
goto out;
@@ -1459,6 +1608,13 @@ static struct cftype cft_spread_slab = {
.private = FILE_SPREAD_SLAB,
};
+static struct cftype cft_irqs = {
+ .name = "irqs",
+ .read = cpuset_common_file_read,
+ .write = cpuset_common_file_write,
+ .private = FILE_IRQS,
+};
+
static int cpuset_populate(struct cgroup_subsys *ss, struct cgroup *cont)
{
int err;
@@ -1481,6 +1637,10 @@ static int cpuset_populate(struct cgroup
return err;
if ((err = cgroup_add_file(cont, ss, &cft_spread_slab)) < 0)
return err;
+#ifdef CONFIG_GENERIC_HARDIRQS
+ if ((err = cgroup_add_file(cont, ss, &cft_irqs)) < 0)
+ return err;
+#endif
/* memory_pressure_enabled is in root cpuset only */
if (err == 0 && !cont->parent)
err = cgroup_add_file(cont, ss,
Index: linux-2.6-2/kernel/irq/manage.c
===================================================================
--- linux-2.6-2.orig/kernel/irq/manage.c
+++ linux-2.6-2/kernel/irq/manage.c
@@ -96,6 +96,25 @@ int irq_set_affinity(unsigned int irq, c
#endif
+int irq_iterator(struct irq_iterator *v)
+{
+ int ret = 0;
+ int irq;
+
+ for (irq = 0; irq < NR_IRQS; irq++) {
+ struct irq_desc *desc = &irq_desc[irq];
+
+ if (desc->chip == &no_irq_chip)
+ continue;
+
+ ret = v->function(v, irq, desc);
+ if (ret)
+ return ret;
+ }
+
+ return ret;
+}
+
/**
* disable_irq_nosync - disable an irq without waiting
* @irq: Interrupt to disable
next prev parent reply other threads:[~2008-02-29 18:56 UTC|newest]
Thread overview: 94+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-02-27 22:21 [RFC/PATCH 0/4] CPUSET driven CPU isolation Peter Zijlstra
2008-02-27 22:21 ` [RFC/PATCH 1/4] sched: remove isolcpus Peter Zijlstra
2008-02-27 23:57 ` Max Krasnyanskiy
2008-02-28 10:19 ` Peter Zijlstra
2008-02-28 19:36 ` Max Krasnyansky
2008-02-27 22:21 ` [RFC/PATCH 2/4] cpuset: system sets Peter Zijlstra
2008-02-27 23:39 ` Paul Jackson
2008-02-28 1:53 ` Max Krasnyanskiy
2008-02-27 23:52 ` Max Krasnyanskiy
2008-02-28 0:11 ` Paul Jackson
2008-02-28 0:29 ` Steven Rostedt
2008-02-28 1:45 ` Max Krasnyanskiy
2008-02-28 3:41 ` Steven Rostedt
2008-02-28 4:58 ` Max Krasnyansky
2008-02-27 22:21 ` [RFC/PATCH 3/4] genirq: system set irq affinities Peter Zijlstra
2008-02-28 0:10 ` Max Krasnyanskiy
2008-02-28 10:19 ` Peter Zijlstra
2008-02-27 22:21 ` [RFC/PATCH 4/4] kthread: system set kthread affinities Peter Zijlstra
2008-02-27 23:38 ` [RFC/PATCH 0/4] CPUSET driven CPU isolation Max Krasnyanskiy
2008-02-28 10:19 ` Peter Zijlstra
2008-02-28 17:33 ` Max Krasnyanskiy
2008-02-28 7:50 ` Ingo Molnar
2008-02-28 8:08 ` Paul Jackson
2008-02-28 9:08 ` Ingo Molnar
2008-02-28 9:17 ` Paul Jackson
2008-02-28 9:32 ` David Rientjes
2008-02-28 10:12 ` David Rientjes
2008-02-28 10:26 ` Peter Zijlstra
2008-02-28 17:37 ` Paul Jackson
2008-02-28 21:24 ` David Rientjes
2008-02-28 22:46 ` Paul Jackson
2008-02-28 23:00 ` David Rientjes
2008-02-29 0:16 ` Paul Jackson
2008-02-29 1:05 ` David Rientjes
2008-02-29 3:34 ` Paul Jackson
2008-02-29 4:00 ` David Rientjes
2008-02-29 6:53 ` Paul Jackson
2008-02-28 10:46 ` Ingo Molnar
2008-02-28 17:47 ` Paul Jackson
2008-02-28 20:11 ` Max Krasnyansky
2008-02-28 20:13 ` Paul Jackson
2008-02-28 20:26 ` Max Krasnyansky
2008-02-28 20:27 ` Paul Jackson
2008-02-28 20:45 ` Max Krasnyansky
2008-02-28 20:23 ` Max Krasnyansky
2008-02-28 17:48 ` Max Krasnyanskiy
2008-02-29 8:31 ` Andrew Morton
2008-02-29 8:36 ` Andrew Morton
2008-02-29 9:10 ` Ingo Molnar
2008-02-29 18:06 ` Max Krasnyanskiy
2008-02-28 12:12 ` Mark Hounschell
2008-02-28 19:57 ` Max Krasnyansky
2008-02-29 18:55 ` Peter Zijlstra [this message]
2008-02-29 19:02 ` [RFC/PATCH] cpuset: cpuset irq affinities Ingo Molnar
2008-02-29 20:52 ` Max Krasnyanskiy
2008-02-29 21:03 ` Peter Zijlstra
2008-02-29 21:20 ` Max Krasnyanskiy
2008-03-03 11:57 ` Peter Zijlstra
2008-03-03 17:36 ` Paul Jackson
2008-03-03 17:57 ` Peter Zijlstra
2008-03-03 18:10 ` Paul Jackson
2008-03-03 18:18 ` Peter Zijlstra
2008-03-04 7:35 ` Paul Jackson
2008-03-04 11:06 ` Peter Zijlstra
2008-03-04 19:52 ` Max Krasnyanskiy
2008-03-05 1:11 ` Paul Jackson
2008-03-05 8:37 ` Peter Zijlstra
2008-03-05 8:50 ` Ingo Molnar
2008-03-05 12:35 ` Paul Jackson
2008-03-05 12:43 ` Ingo Molnar
2008-03-05 17:44 ` Paul Jackson
2008-03-05 19:17 ` Max Krasnyansky
2008-03-06 13:47 ` Paul Jackson
2008-03-06 15:21 ` Peter Zijlstra
2008-03-07 3:40 ` Paul Jackson
2008-03-07 6:39 ` Paul Jackson
2008-03-07 8:47 ` Paul Menage
2008-03-07 14:57 ` Paul Jackson
2008-03-03 18:41 ` Paul Menage
2008-03-03 18:52 ` Paul Jackson
2008-03-04 5:26 ` Paul Menage
2008-03-04 6:15 ` Paul Jackson
2008-03-04 6:21 ` Paul Menage
2008-03-04 6:26 ` Paul Jackson
2008-03-04 6:34 ` Paul Menage
2008-03-04 6:51 ` Paul Jackson
2008-02-29 20:55 ` Paul Jackson
2008-02-29 21:14 ` Peter Zijlstra
2008-02-29 21:29 ` Ingo Molnar
2008-02-29 21:32 ` Ingo Molnar
2008-02-29 21:42 ` Max Krasnyanskiy
2008-02-29 22:00 ` Paul Jackson
2008-02-29 21:53 ` Paul Jackson
2008-03-02 5:18 ` Christoph Hellwig
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=1204311351.6243.130.camel@lappy \
--to=a.p.zijlstra@chello.nl \
--cc=linux-kernel@vger.kernel.org \
--cc=maxk@qualcomm.com \
--cc=mingo@elte.hu \
--cc=oleg@tv-sign.ru \
--cc=pj@sgi.com \
--cc=rientjes@google.com \
--cc=rostedt@goodmis.org \
--cc=tglx@linutronix.de \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox