From dc5f7a04f2b446b5224be356c2fc79e88a5d3e8f Mon Sep 17 00:00:00 2001 From: Daniel Borkmann Date: Mon, 3 Jun 2013 22:49:19 +0200 Subject: irq: break out from xutils and save + restore Break out IRQ functionality from xutils, simplify it, and save + restore IRQ affinity list. Signed-off-by: Daniel Borkmann --- irq.c | 129 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100644 irq.c (limited to 'irq.c') diff --git a/irq.c b/irq.c new file mode 100644 index 0000000..fbd1cbc --- /dev/null +++ b/irq.c @@ -0,0 +1,129 @@ +/* + * netsniff-ng - the packet sniffing beast + * Copyright 2009 - 2013 Daniel Borkmann. + * Copyright 2009, 2010 Emmanuel Roullit. + * Subject to the GPL, version 2. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "irq.h" +#include "die.h" +#include "xutils.h" + +int device_irq_number(const char *ifname) +{ + int irq = 0; + char buff[128], sysname[128]; + FILE *fp; + + if (!strncmp("lo", ifname, strlen("lo"))) + return 0; + + slprintf(sysname, sizeof(sysname), + "/sys/class/net/%s/device/irq", + ifname); + + fp = fopen(sysname, "r"); + if (!fp) + return -ENOENT; + + memset(buff, 0, sizeof(buff)); + + if (fgets(buff, sizeof(buff), fp) != NULL) { + buff[sizeof(buff) - 1] = 0; + irq = atoi(buff); + } + + fclose(fp); + return irq; +} + +static char nic_irq_affinity_list[128]; +static bool nic_irq_stored = false; +static int nic_irq = -1; + +static void device_save_irq_affinity_list(void) +{ + int ret, fd; + char file[128]; + + bug_on(nic_irq_stored); + + slprintf(file, sizeof(file), + "/proc/irq/%d/smp_affinity_list", nic_irq); + + fd = open(file, O_RDONLY); + if (fd < 0) + return; + + memset(nic_irq_affinity_list, 0, sizeof(nic_irq_affinity_list)); + + ret = read(fd, nic_irq_affinity_list, + sizeof(nic_irq_affinity_list)); + if (ret < 0) + panic("Cannot store NIC IRQ affinity!\n"); + + close(fd); + + nic_irq_stored = true; +} + +void device_restore_irq_affinity_list(void) +{ + int ret, fd; + char file[128]; + + if (!nic_irq_stored) + return; + + bug_on(nic_irq == -1); + + slprintf(file, sizeof(file), + "/proc/irq/%d/smp_affinity_list", nic_irq); + + fd = open(file, O_WRONLY); + if (fd < 0) + return; + + ret = write(fd, nic_irq_affinity_list, + sizeof(nic_irq_affinity_list)); + if (ret < 0) + panic("Cannot restore NIC IRQ affinity!\n"); + + close(fd); +} + +int device_set_irq_affinity_list(int irq, unsigned long from, unsigned long to) +{ + int ret, fd; + char file[128], list[64]; + + if (!nic_irq_stored) { + nic_irq = irq; + device_save_irq_affinity_list(); + } + + slprintf(file, sizeof(file), "/proc/irq/%d/smp_affinity_list", irq); + slprintf(list, sizeof(list), "%lu-%lu\n", from, to); + + fd = open(file, O_WRONLY); + if (fd < 0) + return -ENOENT; + + ret = write(fd, list, strlen(list)); + + close(fd); + return ret; +} + +int device_bind_irq_to_cpu(int irq, int cpu) +{ + return device_set_irq_affinity_list(irq, cpu, cpu); +} -- cgit v1.2.3-54-g00ecf