let sysctl tweak interface rx queue backpressure cutoffs

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

let sysctl tweak interface rx queue backpressure cutoffs

David Gwynne-5
this lets read and write the backpressure variables in the interface rx
queue (ifiq) handling:

dlg@ix ~$ sysctl net.link.ifrxq
net.link.ifrxq.pressure_return=6
net.link.ifrxq.pressure_drop=8

ideally this would be temporary, ie, id remove it from the tree once
everyone's happy with these numbers.  6 and 8 are the least worst
values ive come up with so far, but it is handy to move them around
for testing purposes.

Index: sys/net/ifq.c
===================================================================
RCS file: /cvs/src/sys/net/ifq.c,v
retrieving revision 1.32
diff -u -p -r1.32 ifq.c
--- sys/net/ifq.c 1 Jul 2019 00:44:29 -0000 1.32
+++ sys/net/ifq.c 1 Jul 2019 00:48:30 -0000
@@ -23,6 +23,7 @@
 #include <sys/socket.h>
 #include <sys/mbuf.h>
 #include <sys/proc.h>
+#include <sys/sysctl.h>
 
 #include <net/if.h>
 #include <net/if_var.h>
@@ -605,6 +606,43 @@ ifiq_process(void *arg)
  mtx_leave(&ifiq->ifiq_mtx);
 
  if_input_process(ifiq->ifiq_if, &ml);
+}
+
+int
+net_ifiq_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp,
+    void *newp, size_t newlen)
+{
+ int val;
+ int error;
+
+ if (namelen != 1)
+ return (EISDIR);
+
+ switch (name[0]) {
+ case NET_LINK_IFRXQ_PRESSURE_RETURN:
+ val = ifiq_pressure_return;
+ error = sysctl_int(oldp, oldlenp, newp, newlen, &val);
+ if (error != 0)
+ return (error);
+ if (val < 1 || val > ifiq_pressure_drop)
+ return (EINVAL);
+ ifiq_pressure_return = val;
+ break;
+ case NET_LINK_IFRXQ_PRESSURE_DROP:
+ val = ifiq_pressure_drop;
+ error = sysctl_int(oldp, oldlenp, newp, newlen, &val);
+ if (error != 0)
+ return (error);
+ if (ifiq_pressure_return > val)
+ return (EINVAL);
+ ifiq_pressure_drop = val;
+ break;
+ default:
+ error = EOPNOTSUPP;
+ break;
+ }
+
+ return (error);
 }
 
 /*
Index: sbin/sysctl/sysctl.c
===================================================================
RCS file: /cvs/src/sbin/sysctl/sysctl.c,v
retrieving revision 1.241
diff -u -p -r1.241 sysctl.c
--- sbin/sysctl/sysctl.c 21 Feb 2019 16:37:13 -0000 1.241
+++ sbin/sysctl/sysctl.c 1 Jul 2019 00:48:30 -0000
@@ -192,6 +192,7 @@ void usage(void);
 int findname(char *, char *, char **, struct list *);
 int sysctl_inet(char *, char **, int *, int, int *);
 int sysctl_inet6(char *, char **, int *, int, int *);
+int sysctl_link(char *, char **, int *, int, int *);
 int sysctl_bpf(char *, char **, int *, int, int *);
 int sysctl_mpls(char *, char **, int *, int, int *);
 int sysctl_pipex(char *, char **, int *, int, int *);
@@ -647,6 +648,12 @@ parse(char *string, int flags)
  }
  break;
  }
+ if (mib[1] == PF_LINK) {
+ len = sysctl_link(string, &bufp, mib, flags, &type);
+ if (len < 0)
+ return;
+ break;
+ }
  if (mib[1] == PF_BPF) {
  len = sysctl_bpf(string, &bufp, mib, flags, &type);
  if (len < 0)
@@ -2230,6 +2237,46 @@ sysctl_inet6(char *string, char **bufpp,
  *typep = lp->list[tindx].ctl_type;
  return(5);
  }
+ return (4);
+}
+
+/* handle net.link requests */
+struct ctlname netlinkname[] = CTL_NET_LINK_NAMES;
+struct ctlname ifrxqname[] = CTL_NET_LINK_IFRXQ_NAMES;
+struct list netlinklist = { netlinkname, NET_LINK_MAXID };
+struct list netlinkvars[] = {
+ [NET_LINK_IFRXQ] = { ifrxqname, NET_LINK_IFRXQ_MAXID },
+};
+
+int
+sysctl_link(char *string, char **bufpp, int mib[], int flags, int *typep)
+{
+ struct list *lp;
+ int indx;
+
+ if (*bufpp == NULL) {
+ listall(string, &netlinklist);
+ return (-1);
+ }
+ if ((indx = findname(string, "third", bufpp, &netlinklist)) == -1)
+ return (-1);
+ mib[2] = indx;
+ if (indx < NET_LINK_MAXID && netlinkvars[indx].list != NULL)
+ lp = &netlinkvars[indx];
+ else if (!flags)
+ return (-1);
+ else {
+ warnx("%s: no variables defined for this protocol", string);
+ return (-1);
+ }
+ if (*bufpp == NULL) {
+ listall(string, lp);
+ return (-1);
+ }
+ if ((indx = findname(string, "fourth", bufpp, lp)) == -1)
+ return (-1);
+ mib[3] = indx;
+ *typep = lp->list[indx].ctl_type;
  return (4);
 }
 
Index: sys/sys/sysctl.h
===================================================================
RCS file: /cvs/src/sys/sys/sysctl.h,v
retrieving revision 1.188
diff -u -p -r1.188 sysctl.h
--- sys/sys/sysctl.h 1 Jun 2019 14:11:18 -0000 1.188
+++ sys/sys/sysctl.h 1 Jul 2019 00:48:31 -0000
@@ -1012,6 +1012,7 @@ int sysctl_wdog(int *, u_int, void *, si
 extern int (*cpu_cpuspeed)(int *);
 extern void (*cpu_setperf)(int);
 
+int net_ifiq_sysctl(int *, u_int, void *, size_t *, void *, size_t);
 int bpf_sysctl(int *, u_int, void *, size_t *, void *, size_t);
 int pflow_sysctl(int *, u_int, void *, size_t *, void *, size_t);
 int pipex_sysctl(int *, u_int, void *, size_t *, void *, size_t);
Index: sys/sys/socket.h
===================================================================
RCS file: /cvs/src/sys/sys/socket.h,v
retrieving revision 1.96
diff -u -p -r1.96 socket.h
--- sys/sys/socket.h 8 Apr 2018 18:57:39 -0000 1.96
+++ sys/sys/socket.h 1 Jul 2019 00:48:31 -0000
@@ -330,7 +330,7 @@ struct sockpeercred {
  { "hylink", CTLTYPE_NODE }, \
  { "appletalk", CTLTYPE_NODE }, \
  { "route", CTLTYPE_NODE }, \
- { "link_layer", CTLTYPE_NODE }, \
+ { "link", CTLTYPE_NODE }, \
  { "xtp", CTLTYPE_NODE }, \
  { "coip", CTLTYPE_NODE }, \
  { "cnt", CTLTYPE_NODE }, \
@@ -376,6 +376,29 @@ struct sockpeercred {
  { "stats", CTLTYPE_STRUCT }, \
  { "table", CTLTYPE_STRUCT }, \
  { "ifnames", CTLTYPE_STRUCT }, \
+}
+
+/*
+ * PF_LINK - link layer or device tunables
+ */
+#define NET_LINK_IFRXQ 1 /* net.link.ifrxq */
+#define NET_LINK_MAXID 2
+
+#define CTL_NET_LINK_NAMES { \
+ { 0, 0 }, \
+ { "ifrxq", CTLTYPE_NODE }, \
+}
+
+#define NET_LINK_IFRXQ_PRESSURE_RETURN \
+ 1 /* net.link.ifrxq.pressure_return */
+#define NET_LINK_IFRXQ_PRESSURE_DROP \
+ 2 /* net.link.ifrxq.pressure_drop */
+#define NET_LINK_IFRXQ_MAXID 3
+
+#define CTL_NET_LINK_IFRXQ_NAMES { \
+ { 0, 0 }, \
+ { "pressure_return", CTLTYPE_INT }, \
+ { "pressure_drop", CTLTYPE_INT }, \
 }
 
 /*
Index: sys/kern/uipc_domain.c
===================================================================
RCS file: /cvs/src/sys/kern/uipc_domain.c,v
retrieving revision 1.56
diff -u -p -r1.56 uipc_domain.c
--- sys/kern/uipc_domain.c 23 Jun 2018 14:38:59 -0000 1.56
+++ sys/kern/uipc_domain.c 1 Jul 2019 00:48:31 -0000
@@ -159,6 +159,37 @@ pffindproto(int family, int protocol, in
  return (maybe);
 }
 
+static int
+net_link_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp,
+    void *newp, size_t newlen)
+{
+ int node;
+ int error;
+
+ /*
+ * All sysctl names at this level are nonterminal.
+ */
+ if (namelen < 2)
+ return (EISDIR); /* overloaded */
+ node = name[0];
+
+ namelen--;
+ name++;
+
+ switch (node) {
+ case NET_LINK_IFRXQ:
+ error = net_ifiq_sysctl(name, namelen, oldp, oldlenp,
+    newp, newlen);
+ break;
+
+ default:
+ error = ENOPROTOOPT;
+ break;
+ }
+
+ return (error);
+}
+
 int
 net_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
     size_t newlen, struct proc *p)
@@ -178,6 +209,9 @@ net_sysctl(int *name, u_int namelen, voi
 
  if (family == PF_UNSPEC)
  return (0);
+ if (family == PF_LINK)
+ return (net_link_sysctl(name + 1, namelen - 1, oldp, oldlenp,
+    newp, newlen));
 #if NBPFILTER > 0
  if (family == PF_BPF)
  return (bpf_sysctl(name + 1, namelen - 1, oldp, oldlenp,