allow setting rps/xps defualt values via uci
authorJohn Crispin <john@phrozen.org>
Tue, 22 Aug 2017 07:10:58 +0000 (09:10 +0200)
committerJohn Crispin <john@phrozen.org>
Tue, 22 Aug 2017 07:10:58 +0000 (09:10 +0200)
Signed-off-by: John Crispin <john@phrozen.org>
config.c
device.c
device.h
system-linux.c

index 2454e9b..a7112f0 100644 (file)
--- a/config.c
+++ b/config.c
@@ -289,6 +289,18 @@ config_init_rules(void)
 
        iprule_update_complete();
 }
+static int
+config_parse_global_ps_val(struct uci_section *globals, const char *option)
+{
+       const char *val = uci_lookup_option_string(
+                       uci_ctx, globals, option);
+       int ret = 0;
+
+       if (val)
+               ret = strtol(val, 0, 10);
+
+       return ret;
+}
 
 static void
 config_init_globals(void)
@@ -306,7 +318,10 @@ config_init_globals(void)
                        uci_ctx, globals, "default_ps");
 
        if (default_ps)
-               device_set_default_ps(strcmp(default_ps, "1") ? false : true);
+               device_set_default_ps(strcmp(default_ps, "1") ? false : true,
+                       config_parse_global_ps_val(globals, "default_xps_val"),
+                       config_parse_global_ps_val(globals, "default_rps_val"),
+                       config_parse_global_ps_val(globals, "default_rps_flow_cnt"));
 }
 
 static void
index 306496c..0424658 100644 (file)
--- a/device.c
+++ b/device.c
@@ -33,6 +33,9 @@
 static struct list_head devtypes = LIST_HEAD_INIT(devtypes);
 static struct avl_tree devices;
 static bool default_ps = true;
+static int default_rps_val;
+static int default_rps_flow_cnt;
+static int default_xps_val;
 
 static const struct blobmsg_policy dev_attrs[__DEV_ATTR_MAX] = {
        [DEV_ATTR_TYPE] = { .name = "type", .type = BLOBMSG_TYPE_STRING },
@@ -912,14 +915,18 @@ device_reset_old(void)
 }
 
 void
-device_set_default_ps(bool state)
+device_set_default_ps(bool state, int xps, int rps, int rps_flow_cnt)
 {
        struct device *dev;
 
-       if (state == default_ps)
+       if ((state == default_ps) && (default_rps_val == rps) &&
+           (default_xps_val == xps) && (default_rps_flow_cnt == rps_flow_cnt))
                return;
 
        default_ps = state;
+       default_rps_val = rps;
+       default_rps_flow_cnt = rps_flow_cnt;
+       default_xps_val = xps;
 
        avl_for_each_element(&devices, dev, avl) {
                struct device_settings *s = &dev->settings;
@@ -927,11 +934,14 @@ device_set_default_ps(bool state)
 
                if (!(s->flags & DEV_OPT_RPS)) {
                        s->rps = default_ps;
+                       s->rps_val = default_rps_val;
+                       s->rps_flow_cnt = default_rps_flow_cnt;
                        apply_mask |= DEV_OPT_RPS;
                }
 
                if (!(s->flags & DEV_OPT_XPS)) {
                        s->xps = default_ps;
+                       s->xps_val = default_xps_val;
                        apply_mask |= DEV_OPT_XPS;
                }
 
index 7ad733e..f398dbc 100644 (file)
--- a/device.h
+++ b/device.h
@@ -164,7 +164,10 @@ struct device_settings {
        unsigned int neigh6gcstaletime;
        int neigh4locktime;
        bool rps;
+       int rps_val;
+       int rps_flow_cnt;
        bool xps;
+       int xps_val;
        unsigned int dadtransmits;
        bool multicast_to_unicast;
        unsigned int multicast_router;
@@ -250,7 +253,7 @@ device_apply_config(struct device *dev, struct device_type *type,
 
 void device_reset_config(void);
 void device_reset_old(void);
-void device_set_default_ps(bool state);
+void device_set_default_ps(bool state, int xps, int rps, int rps_flow_cnt);
 
 void device_init_virtual(struct device *dev, struct device_type *type, const char *name);
 int device_init(struct device *dev, struct device_type *type, const char *ifname);
index 02faa32..0bf071e 100644 (file)
@@ -1388,7 +1388,7 @@ system_if_get_settings(struct device *dev, struct device_settings *s)
 }
 
 static void
-system_if_set_rps_xps_val(const char *path, int val)
+system_if_set_rps_xps_val(const char *path, char *fmt, int val)
 {
        char val_buf[8];
        glob_t gl;
@@ -1397,7 +1397,7 @@ system_if_set_rps_xps_val(const char *path, int val)
        if (glob(path, 0, NULL, &gl))
                return;
 
-       snprintf(val_buf, sizeof(val_buf), "%x", val);
+       snprintf(val_buf, sizeof(val_buf), fmt, val);
        for (i = 0; i < gl.gl_pathc; i++)
                system_set_sysctl(gl.gl_pathv[i], val_buf);
 
@@ -1408,17 +1408,23 @@ static void
 system_if_apply_rps_xps(struct device *dev, struct device_settings *s)
 {
        long n_cpus = sysconf(_SC_NPROCESSORS_ONLN);
-       int val;
+       int val, rps_val, rps_flow_cnt, xps_val;
 
        if (n_cpus < 2)
                return;
 
        val = (1 << n_cpus) - 1;
+       rps_val = s->rps_val ? s->rps_val : val;
        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);
+       system_if_set_rps_xps_val(dev_buf, "%x", s->rps ? rps_val : 0);
+
+       rps_flow_cnt = s->rps_flow_cnt ? s->rps_flow_cnt : 0;
+       snprintf(dev_buf, sizeof(dev_buf), "/sys/class/net/%s/queues/*/rps_flow_cnt", dev->ifname);
+       system_if_set_rps_xps_val(dev_buf, "%d", s->rps ? rps_flow_cnt : 0);
 
+       xps_val = s->xps_val ? s->xps_val : val;
        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);
+       system_if_set_rps_xps_val(dev_buf, "%x", s->xps ? xps_val : 0);
 }
 
 void