diff options
author | Felix Fietkau <nbd@openwrt.org> | 2015-03-22 17:41:26 +0100 |
---|---|---|
committer | Felix Fietkau <nbd@openwrt.org> | 2015-03-22 17:41:26 +0100 |
commit | 1268b8222a3613c2ee36cc7d3006e1989f068a52 (patch) | |
tree | 46c7a02fb14432a27b4b0304c09cf143f85e3f49 | |
parent | 1bba3f853bf5b2974b32303c55dfbc0e78d01965 (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.c | 12 | ||||
-rw-r--r-- | device.h | 4 | ||||
-rw-r--r-- | system-linux.c | 35 |
3 files changed, 51 insertions, 0 deletions
@@ -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); } @@ -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) |