public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
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



  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