lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20100903210554.GO2464@sgi.com>
Date:	Fri, 3 Sep 2010 14:05:54 -0700
From:	Arthur Kepner <akepner@....com>
To:	linux-kernel@...r.kernel.org
Cc:	David Miller <davem@...emloft.net>
Subject: [RFC/PATCH] notify user-level IRQ balancer when kernel assigns IRQ
	affinity


We've run into situations where a CPU runs out of interrupt 
vectors, because all the interrupts are getting the default 
affinity (and the interrupt balancer hasn't yet run).

The following emits a netlink message whenever an interrupt 
is given a default CPU affinity. A user-level IRQ balancer 
can use those messages to decide if, and how to reassign 
affinities. This should allow us to avoid running out of 
vectors on any particular CPU (or at least make it far less 
likely).

I know this needs work, but would like to get comments on 
the idea before doing more coding and testing.


Signed-off-by: Arthur Kepner <akepner@....com>

---

diff --git a/arch/Kconfig b/arch/Kconfig
index 4877a8c..65c79c7 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -158,4 +158,15 @@ config HAVE_PERF_EVENTS_NMI
 	  subsystem.  Also has support for calculating CPU cycle events
 	  to determine how many clock cycles in a given period.
 
+config NOTIFY_USER_IRQ_BALANCER
+	bool "Notify user-level IRQ balancer (EXPERIMENTAL)"
+	default n
+	depends on NET && X86
+	help
+	  When the kernel sets a default CPU affinity for an interrupt, 
+          emit a notification message over a netlink socket so that a 
+          user-level IRQ balancer may re-balance IRQs the way it prefers.
+
+	  If unsure, say N.
+
 source "kernel/gcov/Kconfig"
diff --git a/include/linux/irq_notify.h b/include/linux/irq_notify.h
new file mode 100644
index 0000000..b1bbdee
--- /dev/null
+++ b/include/linux/irq_notify.h
@@ -0,0 +1,33 @@
+#ifndef __IRQ_NOTIFY_H
+#define __IRQ_NOTIFY_H
+
+enum {
+	IRQ_NOTIFY_TYPE_UNSPEC,
+	IRQ_NOTIFY_TYPE_NOTICE,
+	__IRQ_NOTIFY_TYPE_MAX,
+};
+
+#define IRQ_NOTIFY_TYPE_MAX (__IRQ_NOTIFY_TYPE_MAX - 1)
+
+enum {
+	IRQ_NOTIFY_CMD_ATTR_UNSPEC,
+	IRQ_NOTIFY_CMD_ATTR_IRQ,
+	__IRQ_NOTIFY_CMD_ATTR_MAX,
+};
+
+#define IRQ_NOTIFY_CMD_ATTR_MAX (__IRQ_NOTIFY_CMD_ATTR_MAX - 1)
+
+#define IRQ_NOTIFY_GNL_NAME "IRQ_NOTIFY"
+#define IRQ_NOTIFY_GNL_VERSION 1
+
+#define IRQ_NOTIFY_GRP_ID 1
+
+#ifdef CONFIG_NOTIFY_USER_IRQ_BALANCER
+extern int irq_notify(int);
+#else
+static inline int irq_notify(int)
+{
+}
+#endif /* CONFIG_NOTIFY_USER_IRQ_BALANCER */
+
+#endif /* __IRQ_NOTIFY_H */
diff --git a/kernel/irq/Makefile b/kernel/irq/Makefile
index 7d04780..b74c75e 100644
--- a/kernel/irq/Makefile
+++ b/kernel/irq/Makefile
@@ -5,3 +5,4 @@ obj-$(CONFIG_PROC_FS) += proc.o
 obj-$(CONFIG_GENERIC_PENDING_IRQ) += migration.o
 obj-$(CONFIG_NUMA_IRQ_DESC) += numa_migrate.o
 obj-$(CONFIG_PM_SLEEP) += pm.o
+obj-$(CONFIG_NOTIFY_USER_IRQ_BALANCER) += irq_notify.o
diff --git a/kernel/irq/irq_notify.c b/kernel/irq/irq_notify.c
new file mode 100644
index 0000000..35c7627
--- /dev/null
+++ b/kernel/irq/irq_notify.c
@@ -0,0 +1,103 @@
+/* 
+ * irq_notify.c - send notification via netlink when the kernel sets
+ *                the default affinity of an IRQ
+ * 
+ * Copyright (C) Arthur Kepner, SGI 2010
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <net/netlink.h>
+#include <net/genetlink.h>
+#include <linux/irq_notify.h>
+
+MODULE_AUTHOR("Arthur Kepner <akepner@....com>");
+MODULE_DESCRIPTION("notify userland when default irq affinity is assigned");
+MODULE_LICENSE("GPL");
+MODULE_VERSION("0.1");
+
+static int irq_notify_family_registered;
+
+static struct genl_family irq_notify_family = {
+	.id		= GENL_ID_GENERATE,
+	.name		= IRQ_NOTIFY_GNL_NAME,
+	.version	= IRQ_NOTIFY_GNL_VERSION,
+	.maxattr	= IRQ_NOTIFY_CMD_ATTR_MAX,
+};
+
+static const struct nla_policy irq_notify_policy[IRQ_NOTIFY_CMD_ATTR_MAX+1] = {
+        [IRQ_NOTIFY_CMD_ATTR_IRQ]  = { .type = NLA_U32 },
+};
+
+int irq_notify(int irq)
+{
+	struct sk_buff *skb;
+	void *hdr;
+	int ret;
+
+	if (!irq_notify_family_registered)
+		return -EINVAL;
+
+	skb = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
+
+	if (skb == NULL)
+		return -ENOMEM;
+
+	hdr = genlmsg_put(skb, 0, 0, &irq_notify_family, 0, 
+			  IRQ_NOTIFY_TYPE_NOTICE);
+
+	if (hdr == NULL) {
+		ret = -ENOMEM;
+		goto fail;
+	}
+
+	ret = nla_put(skb, IRQ_NOTIFY_CMD_ATTR_IRQ, sizeof(u32), &irq);
+	if (ret < 0)
+		goto fail;
+
+	genlmsg_end(skb, hdr);
+
+	return genlmsg_multicast(skb, 0, IRQ_NOTIFY_GRP_ID, GFP_KERNEL);
+
+fail:
+	nlmsg_free(skb);
+	return ret;
+}
+EXPORT_SYMBOL(irq_notify);
+
+static __init int irq_notify_init(void)
+{
+	int ret = 0;
+
+	ret = genl_register_family(&irq_notify_family);
+	if (ret)
+		goto out;
+
+	printk(KERN_CRIT "%s: family registered\n", IRQ_NOTIFY_GNL_NAME);
+
+	irq_notify_family_registered = 1;
+out:
+	return ret;
+}
+module_init(irq_notify_init);
+
+
+static __exit void irq_notify_exit(void)
+{
+	genl_unregister_family(&irq_notify_family);
+	printk(KERN_CRIT "%s: family unregistered\n", IRQ_NOTIFY_GNL_NAME);
+}
+module_exit(irq_notify_exit);
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index c3003e9..2fa65e2 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -14,6 +14,7 @@
 #include <linux/interrupt.h>
 #include <linux/slab.h>
 #include <linux/sched.h>
+#include <linux/irq_notify.h>
 
 #include "internals.h"
 
@@ -178,6 +179,7 @@ static int setup_affinity(unsigned int irq, struct irq_desc *desc)
 	cpumask_and(desc->affinity, cpu_online_mask, irq_default_affinity);
 set_affinity:
 	desc->chip->set_affinity(irq, desc->affinity);
+	irq_notify(irq);
 
 	return 0;
 }
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ