if_rxr_livelocked

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

if_rxr_livelocked

David Gwynne-5
if a driver determines that an rx ring is generating too much load,
it can notify the rxr ring accounting stuff of this. the effect is
that it may lower the current watermark on the ring, therefore
restricting the number of packets that will enter the system in the
future.

this also adds if_rxr_cwm, so a driver can access the current
watermark.

right now nothing uses this, but it is the building blocks for
allowing rx ring moderation to be useful again in the mp network
stack we're building. the current determination of "is the system
too busy?" depends on all network stack work in the system being
done in a softint context above softclock, and on a single cpu.
that is no longer true, so this is an attempt to modernise rx
ring moderation.

ok?

Index: share/man/man9/if_rxr_init.9
===================================================================
RCS file: /cvs/src/share/man/man9/if_rxr_init.9,v
retrieving revision 1.6
diff -u -p -r1.6 if_rxr_init.9
--- share/man/man9/if_rxr_init.9 15 Nov 2017 01:41:20 -0000 1.6
+++ share/man/man9/if_rxr_init.9 15 Nov 2017 01:50:33 -0000
@@ -33,8 +33,12 @@
 .Fn if_rxr_get "struct if_rxring *rxr" "unsigned int max"
 .Ft void
 .Fn if_rxr_put "struct if_rxring *rxr" "unsigned int n"
+.Ft void
+.Fn if_rxr_livelocked "struct if_rxring *rxr"
 .Ft unsigned int
 .Fn if_rxr_inuse "struct if_rxring *rxr"
+.Ft unsigned int
+.Fn if_rxr_cwm "struct if_rxring *rxr"
 .Ft int
 .Fo if_rxr_ioctl
 .Fa "struct if_rxrinfo *ifri"
@@ -81,10 +85,17 @@ returns
 .Fa n
 receive descriptor slots to the ring.
 .Pp
+.Fn if_rxr_livelocked
+can signal that that receive ring is generating too much load.
+.Pp
 .Fn if_rxr_inuse
 can be used to determine how many descriptor slots have been allocated
 on the ring.
 .Pp
+.Fn if_rxr_cwm
+can be used to determine what the current watermark is for the ring.
+on the ring.
+.Pp
 The
 .Fn if_rxr_ioctl
 and
@@ -128,8 +139,10 @@ to fill them again.
 .Fn if_rxr_init ,
 .Fn if_rxr_get ,
 .Fn if_rxr_put ,
+.Fn if_rxr_livelocked ,
+.Fn if_rxr_inuse ,
 and
-.Fn if_rxr_inuse
+.Fn if_rxr_cwm
 can be called during autoconf, from process context, or from interrupt context.
 .Pp
 .Fn if_rxr_ioctl
@@ -150,6 +163,9 @@ requested.
 .Pp
 .Fn if_rxr_inuse
 returns the number of receive descriptor slots currently in use on the ring.
+.Pp
+.Fn if_rxr_cwm
+returns the currently allowed allocation watermark.
 .Sh SEE ALSO
 .Xr autoconf 9
 .Sh HISTORY
Index: sys/net/if_var.h
===================================================================
RCS file: /cvs/src/sys/net/if_var.h,v
retrieving revision 1.83
diff -u -p -r1.83 if_var.h
--- sys/net/if_var.h 31 Oct 2017 22:05:12 -0000 1.83
+++ sys/net/if_var.h 15 Nov 2017 01:50:33 -0000
@@ -333,11 +337,13 @@ void if_ih_insert(struct ifnet *, int (*
 void if_ih_remove(struct ifnet *, int (*)(struct ifnet *, struct mbuf *,
     void *), void *);
 
+void if_rxr_livelocked(struct if_rxring *);
 void if_rxr_init(struct if_rxring *, u_int, u_int);
 u_int if_rxr_get(struct if_rxring *, u_int);
 
 #define if_rxr_put(_r, _c) do { (_r)->rxr_alive -= (_c); } while (0)
 #define if_rxr_inuse(_r) ((_r)->rxr_alive)
+#define if_rxr_cwm(_r) ((_r)->rxr_cwm)
 
 int if_rxr_info_ioctl(struct if_rxrinfo *, u_int, struct if_rxring_info *);
 int if_rxr_ioctl(struct if_rxrinfo *, const char *, u_int,
Index: sys/net/if.c
===================================================================
RCS file: /cvs/src/sys/net/if.c,v
retrieving revision 1.523
diff -u -p -r1.523 if.c
--- sys/net/if.c 4 Nov 2017 16:58:46 -0000 1.523
+++ sys/net/if.c 15 Nov 2017 01:50:34 -0000
@@ -2817,6 +2778,19 @@ if_rxr_adjust_cwm(struct if_rxring *rxr)
  rxr->rxr_cwm++;
 
  rxr->rxr_adjusted = ticks;
+}
+
+void
+if_rxr_livelocked(struct if_rxring *rxr)
+{
+ extern int ticks;
+
+ if (ticks - rxr->rxr_adjusted >= 1) {
+ if (rxr->rxr_cwm > rxr->rxr_lwm)
+ rxr->rxr_cwm--;
+
+ rxr->rxr_adjusted = ticks;
+ }
 }
 
 u_int