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 2454e9b9a5976f182fe1fec52a39176cbe454bb5..a7112f042a677426ab27baff8b8131e0bb4e3d40 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 306496c11b8be8b095b92919d8d9969c5f172e65..0424658a21bfdd1c63dab33b674684078883f55f 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 7ad733eaf5cd1a64d10de5631d5ac9804023d0f3..f398dbc5c5ad2251b9328357611fae725171bf44 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 02faa328262faf94ed09d93c4ae68c8ada1fa71b..0bf071e70d9095360bd27510cabca5067cf7f3a1 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