From ad24f0544af47d2d396e929fd8052bf0b0f674fa Mon Sep 17 00:00:00 2001 From: David Gwynne Date: Wed, 18 Mar 2015 12:23:16 +0000 Subject: remove the congestion handling from struct ifqueue. its only used for the ip and ip6 network stack input queues, so it seems unfair that every instance of ifqueue has to carry a pointer around for this specific use case. this moves the congestion marker to a kernel global. if we detect that we're congested, we assume the whole system is busy and punish all input queues. marking a system as congested is done by setting the global to the current value of ticks. as the system moves away from that value, it moves away from being congested until the comparison fails. written at s2k15 ok henning@ beck@ bluhm@ claudio@ --- sys/net/if.c | 31 ++++++++++--------------------- sys/net/if.h | 4 +++- sys/net/if_ppp.c | 5 ++--- sys/net/if_spppsubr.c | 5 ++--- sys/net/if_tun.c | 5 ++--- sys/net/if_var.h | 7 ++----- sys/net/pf.c | 20 ++------------------ sys/net/pipex.c | 8 +++----- 8 files changed, 26 insertions(+), 59 deletions(-) diff --git a/sys/net/if.c b/sys/net/if.c index ca33d741862..67ff20834f8 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if.c,v 1.321 2015/03/14 03:38:51 jsg Exp $ */ +/* $OpenBSD: if.c,v 1.322 2015/03/18 12:23:15 dlg Exp $ */ /* $NetBSD: if.c,v 1.35 1996/05/07 05:26:04 thorpej Exp $ */ /* @@ -138,7 +138,6 @@ int if_setgroupattribs(caddr_t); int if_clone_list(struct if_clonereq *); struct if_clone *if_clone_lookup(const char *, int *); -void if_congestion_clear(void *); int if_group_egress_build(void); void if_link_state_change_task(void *); @@ -154,6 +153,7 @@ int if_cloners_count; struct timeout net_tick_to; void net_tick(void *); int net_livelocked(void); +int ifq_congestion; /* * Network interface utility routines. @@ -786,33 +786,22 @@ if_clone_list(struct if_clonereq *ifcr) } /* - * set queue congestion marker and register timeout to clear it + * set queue congestion marker */ void -if_congestion(struct ifqueue *ifq) +if_congestion(void) { - /* Not currently needed, all callers check this */ - if (ifq->ifq_congestion) - return; + extern int ticks; - ifq->ifq_congestion = malloc(sizeof(struct timeout), M_TEMP, M_NOWAIT); - if (ifq->ifq_congestion == NULL) - return; - timeout_set(ifq->ifq_congestion, if_congestion_clear, ifq); - timeout_add(ifq->ifq_congestion, hz / 100); + ifq_congestion = ticks; } -/* - * clear the congestion flag - */ -void -if_congestion_clear(void *arg) +int +if_congested(void) { - struct ifqueue *ifq = arg; - struct timeout *to = ifq->ifq_congestion; + extern int ticks; - ifq->ifq_congestion = NULL; - free(to, M_TEMP, sizeof(*to)); + return (ticks - ifq_congestion <= (hz / 100)); } #define equal(a1, a2) \ diff --git a/sys/net/if.h b/sys/net/if.h index b80e4c30b04..70e574b2089 100644 --- a/sys/net/if.h +++ b/sys/net/if.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if.h,v 1.160 2015/02/08 06:00:52 mpi Exp $ */ +/* $OpenBSD: if.h,v 1.161 2015/03/18 12:23:15 dlg Exp $ */ /* $NetBSD: if.h,v 1.23 1996/05/07 02:40:27 thorpej Exp $ */ /* @@ -463,6 +463,8 @@ void if_group_routechange(struct sockaddr *, struct sockaddr *); struct ifnet *ifunit(const char *); struct ifnet *if_get(unsigned int); void ifnewlladdr(struct ifnet *); +void if_congestion(void); +int if_congested(void); #endif /* _KERNEL */ diff --git a/sys/net/if_ppp.c b/sys/net/if_ppp.c index 5169800b4f3..0e5e67c278f 100644 --- a/sys/net/if_ppp.c +++ b/sys/net/if_ppp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_ppp.c,v 1.80 2014/12/19 17:14:39 tedu Exp $ */ +/* $OpenBSD: if_ppp.c,v 1.81 2015/03/18 12:23:15 dlg Exp $ */ /* $NetBSD: if_ppp.c,v 1.39 1997/05/17 21:11:59 christos Exp $ */ /* @@ -1485,8 +1485,7 @@ ppp_inproc(struct ppp_softc *sc, struct mbuf *m) if (sc->sc_flags & SC_DEBUG) printf("%s: input queue full\n", ifp->if_xname); ifp->if_iqdrops++; - if (!inq->ifq_congestion) - if_congestion(inq); + if_congestion(); goto bad; } IF_ENQUEUE(inq, m); diff --git a/sys/net/if_spppsubr.c b/sys/net/if_spppsubr.c index e75fb72f5c4..30bc0aa994f 100644 --- a/sys/net/if_spppsubr.c +++ b/sys/net/if_spppsubr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_spppsubr.c,v 1.130 2015/01/27 03:17:36 dlg Exp $ */ +/* $OpenBSD: if_spppsubr.c,v 1.131 2015/03/18 12:23:15 dlg Exp $ */ /* * Synchronous PPP/Cisco link level subroutines. * Keepalive protocol implemented in both Cisco and PPP modes. @@ -614,8 +614,7 @@ sppp_input(struct ifnet *ifp, struct mbuf *m) if (debug) log(LOG_DEBUG, SPP_FMT "protocol queue overflow\n", SPP_ARGS(ifp)); - if (!inq->ifq_congestion) - if_congestion(inq); + if_congestion(); goto drop; } IF_ENQUEUE(inq, m); diff --git a/sys/net/if_tun.c b/sys/net/if_tun.c index 1fba8ca2c1f..db5b8335734 100644 --- a/sys/net/if_tun.c +++ b/sys/net/if_tun.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_tun.c,v 1.133 2015/03/14 03:38:51 jsg Exp $ */ +/* $OpenBSD: if_tun.c,v 1.134 2015/03/18 12:23:15 dlg Exp $ */ /* $NetBSD: if_tun.c,v 1.24 1996/05/07 02:40:48 thorpej Exp $ */ /* @@ -906,8 +906,7 @@ tunwrite(dev_t dev, struct uio *uio, int ioflag) splx(s); ifp->if_collisions++; m_freem(top); - if (!ifq->ifq_congestion) - if_congestion(ifq); + if_congestion(); return (ENOBUFS); } IF_ENQUEUE(ifq, top); diff --git a/sys/net/if_var.h b/sys/net/if_var.h index 92308d05023..00ffcedfec5 100644 --- a/sys/net/if_var.h +++ b/sys/net/if_var.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if_var.h,v 1.20 2015/02/09 03:09:57 dlg Exp $ */ +/* $OpenBSD: if_var.h,v 1.21 2015/03/18 12:23:15 dlg Exp $ */ /* $NetBSD: if.h,v 1.23 1996/05/07 02:40:27 thorpej Exp $ */ /* @@ -108,7 +108,6 @@ struct ifqueue { int ifq_maxlen; int ifq_drops; struct hfsc_if *ifq_hfsc; - struct timeout *ifq_congestion; }; /* @@ -320,8 +319,7 @@ do { \ if (IF_QFULL(ifq)) { \ IF_DROP(ifq); \ m_freem(m); \ - if (!(ifq)->ifq_congestion) \ - if_congestion(ifq); \ + if_congestion(); \ } else \ IF_ENQUEUE(ifq, m); \ } while (/* CONSTCOND */0) @@ -423,7 +421,6 @@ void if_clone_detach(struct if_clone *); int if_clone_create(const char *); int if_clone_destroy(const char *); -void if_congestion(struct ifqueue *); int sysctl_ifq(int *, u_int, void *, size_t *, void *, size_t, struct ifqueue *); diff --git a/sys/net/pf.c b/sys/net/pf.c index fe7341d94bc..8e180b0f0e8 100644 --- a/sys/net/pf.c +++ b/sys/net/pf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pf.c,v 1.908 2015/03/16 02:40:55 yasuoka Exp $ */ +/* $OpenBSD: pf.c,v 1.909 2015/03/18 12:23:15 dlg Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -221,7 +221,6 @@ int pf_compare_state_keys(struct pf_state_key *, struct pf_state *pf_find_state(struct pfi_kif *, struct pf_state_key_cmp *, u_int, struct mbuf *); int pf_src_connlimit(struct pf_state **); -int pf_check_congestion(struct ifqueue *); int pf_match_rcvif(struct mbuf *, struct pf_rule *); void pf_step_into_anchor(int *, struct pf_ruleset **, struct pf_rule **, struct pf_rule **); @@ -3076,7 +3075,6 @@ pf_test_rule(struct pf_pdesc *pd, struct pf_rule **rm, struct pf_state **sm, struct tcphdr *th = pd->hdr.tcp; struct pf_state_key *skw = NULL, *sks = NULL; struct pf_rule_actions act; - struct ifqueue *ifq = &ipintrq; u_short reason; int rewrite = 0; int tag = -1; @@ -3091,12 +3089,7 @@ pf_test_rule(struct pf_pdesc *pd, struct pf_rule **rm, struct pf_state **sm, act.rtableid = pd->rdomain; SLIST_INIT(&rules); -#ifdef INET6 - if (pd->af == AF_INET6) - ifq = &ip6intrq; -#endif - - if (pd->dir == PF_IN && pf_check_congestion(ifq)) { + if (pd->dir == PF_IN && if_congested()) { REASON_SET(&reason, PFRES_CONGEST); return (PF_DROP); } @@ -6642,15 +6635,6 @@ done: return (action); } -int -pf_check_congestion(struct ifqueue *ifq) -{ - if (ifq->ifq_congestion) - return (1); - else - return (0); -} - void pf_cksum(struct pf_pdesc *pd, struct mbuf *m) { diff --git a/sys/net/pipex.c b/sys/net/pipex.c index c1de0ef540e..f1d4c36f8f4 100644 --- a/sys/net/pipex.c +++ b/sys/net/pipex.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pipex.c,v 1.65 2014/12/19 17:14:40 tedu Exp $ */ +/* $OpenBSD: pipex.c,v 1.66 2015/03/18 12:23:15 dlg Exp $ */ /*- * Copyright (c) 2009 Internet Initiative Japan Inc. @@ -1227,8 +1227,7 @@ pipex_ip_input(struct mbuf *m0, struct pipex_session *session) if (IF_QFULL(&ipintrq)) { IF_DROP(&ipintrq); ifp->if_collisions++; - if (!ipintrq.ifq_congestion) - if_congestion(&ipintrq); + if_congestion(); splx(s); goto drop; } @@ -1302,8 +1301,7 @@ pipex_ip6_input(struct mbuf *m0, struct pipex_session *session) if (IF_QFULL(&ip6intrq)) { IF_DROP(&ip6intrq); ifp->if_collisions++; - if (!ip6intrq.ifq_congestion) - if_congestion(&ip6intrq); + if_congestion(); splx(s); goto drop; } -- cgit v1.2.3