summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2015-03-22 17:41:26 +0100
committerFelix Fietkau <nbd@openwrt.org>2015-03-22 17:41:26 +0100
commit1268b8222a3613c2ee36cc7d3006e1989f068a52 (patch)
tree46c7a02fb14432a27b4b0304c09cf143f85e3f49
parent1bba3f853bf5b2974b32303c55dfbc0e78d01965 (diff)
device: add support for configuring RPS/XPS (enabled by default if available)
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
-rw-r--r--device.c12
-rw-r--r--device.h4
-rw-r--r--system-linux.c35
3 files changed, 51 insertions, 0 deletions
diff --git a/device.c b/device.c
index 2706473..3ca867c 100644
--- a/device.c
+++ b/device.c
@@ -44,6 +44,8 @@ static const struct blobmsg_policy dev_attrs[__DEV_ATTR_MAX] = {
[DEV_ATTR_IGMPVERSION] = { .name = "igmpversion", .type = BLOBMSG_TYPE_INT32 },
[DEV_ATTR_MLDVERSION] = { .name = "mldversion", .type = BLOBMSG_TYPE_INT32 },
[DEV_ATTR_NEIGHREACHABLETIME] = { .name = "neighreachabletime", .type = BLOBMSG_TYPE_INT32 },
+ [DEV_ATTR_RPS] = { .name = "rps", .type = BLOBMSG_TYPE_BOOL },
+ [DEV_ATTR_XPS] = { .name = "xps", .type = BLOBMSG_TYPE_BOOL },
};
const struct uci_blob_param_list device_attr_list = {
@@ -243,6 +245,16 @@ device_init_settings(struct device *dev, struct blob_attr **tb)
s->flags |= DEV_OPT_NEIGHREACHABLETIME;
}
+ if ((cur = tb[DEV_ATTR_RPS]))
+ s->rps = blobmsg_get_bool(cur);
+ else
+ s->rps = true;
+
+ if ((cur = tb[DEV_ATTR_XPS]))
+ s->xps = blobmsg_get_bool(cur);
+ else
+ s->xps = true;
+
device_set_disabled(dev, disabled);
}
diff --git a/device.h b/device.h
index cddb340..391b8c9 100644
--- a/device.h
+++ b/device.h
@@ -38,6 +38,8 @@ enum {
DEV_ATTR_IGMPVERSION,
DEV_ATTR_MLDVERSION,
DEV_ATTR_NEIGHREACHABLETIME,
+ DEV_ATTR_RPS,
+ DEV_ATTR_XPS,
__DEV_ATTR_MAX,
};
@@ -129,6 +131,8 @@ struct device_settings {
unsigned int mldversion;
unsigned int neigh4reachabletime;
unsigned int neigh6reachabletime;
+ bool rps;
+ bool xps;
};
/*
diff --git a/system-linux.c b/system-linux.c
index 21385fc..9ff1532 100644
--- a/system-linux.c
+++ b/system-linux.c
@@ -51,6 +51,7 @@
#include <fcntl.h>
#include <glob.h>
#include <time.h>
+#include <unistd.h>
#include <netlink/msg.h>
#include <netlink/attr.h>
@@ -1055,6 +1056,38 @@ system_if_get_settings(struct device *dev, struct device_settings *s)
}
}
+static void
+system_if_set_rps_xps_val(const char *path, int val)
+{
+ char val_buf[8];
+ glob_t gl;
+ int i;
+
+ if (glob(path, 0, NULL, &gl))
+ return;
+
+ snprintf(val_buf, sizeof(val_buf), "%x", val);
+ for (i = 0; i < gl.gl_pathc; i++)
+ system_set_sysctl(gl.gl_pathv[i], val_buf);
+}
+
+static void
+system_if_apply_rps_xps(struct device *dev, struct device_settings *s)
+{
+ long n_cpus = sysconf(_SC_NPROCESSORS_ONLN);
+ int val;
+
+ if (n_cpus < 2)
+ return;
+
+ val = (1 << n_cpus) - 1;
+ snprintf(dev_buf, sizeof(dev_buf), "/sys/class/net/%s/queues/*/rps_cpus", dev->ifname);
+ system_if_set_rps_xps_val(dev_buf, s->rps ? val : 0);
+
+ snprintf(dev_buf, sizeof(dev_buf), "/sys/class/net/%s/queues/*/xps_cpus", dev->ifname);
+ system_if_set_rps_xps_val(dev_buf, s->xps ? val : 0);
+}
+
void
system_if_apply_settings(struct device *dev, struct device_settings *s, unsigned int apply_mask)
{
@@ -1116,6 +1149,8 @@ system_if_apply_settings(struct device *dev, struct device_settings *s, unsigned
snprintf(buf, sizeof(buf), "%d", s->neigh6reachabletime);
system_set_neigh6reachabletime(dev, buf);
}
+
+ system_if_apply_rps_xps(dev, s);
}
int system_if_up(struct device *dev)