From b3d47573801bae4659f3ee3a3c0c10dbb7773029 Mon Sep 17 00:00:00 2001 From: dlg Date: Thu, 23 Apr 2015 09:45:24 +0000 Subject: [PATCH] replace the use of struct ifqueue in pipex with mbuf_queues. this has a slight semantic change. previously pipex would only process up to 128 packets on the input and output queues at a time and would reschedule the softint if there were any left. now it mq_delists the current set of pending packets and only processes them. if anything is added to the queues later they'll cause the softint to run again. this in turn lets us deprecate sysctl_ifq since nothing uses it anymore. because niqueues are mostly wrappers around mbuf_queues, we can provide sysctl_mq and just #define sysctl_niq to it. pipex bits are ok yasuoka@ --- sys/net/if.c | 34 ++++--------------- sys/net/if_var.h | 10 +++--- sys/net/pipex.c | 79 +++++++++++++------------------------------ sys/net/pipex_local.h | 5 ++- 4 files changed, 36 insertions(+), 92 deletions(-) diff --git a/sys/net/if.c b/sys/net/if.c index 18bdf90b486..28e2596ca37 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if.c,v 1.329 2015/04/10 13:58:20 dlg Exp $ */ +/* $OpenBSD: if.c,v 1.330 2015/04/23 09:45:24 dlg Exp $ */ /* $NetBSD: if.c,v 1.35 1996/05/07 05:26:04 thorpej Exp $ */ /* @@ -2162,8 +2162,8 @@ ifpromisc(struct ifnet *ifp, int pswitch) } int -sysctl_ifq(int *name, u_int namelen, void *oldp, size_t *oldlenp, - void *newp, size_t newlen, struct ifqueue *ifq) +sysctl_mq(int *name, u_int namelen, void *oldp, size_t *oldlenp, + void *newp, size_t newlen, struct mbuf_queue *mq) { /* All sysctl names at this level are terminal. */ if (namelen != 1) @@ -2171,34 +2171,12 @@ sysctl_ifq(int *name, u_int namelen, void *oldp, size_t *oldlenp, switch (name[0]) { case IFQCTL_LEN: - return (sysctl_rdint(oldp, oldlenp, newp, ifq->ifq_len)); + return (sysctl_rdint(oldp, oldlenp, newp, mq_len(mq))); case IFQCTL_MAXLEN: return (sysctl_int(oldp, oldlenp, newp, newlen, - &ifq->ifq_maxlen)); + &mq->mq_maxlen)); /* XXX directly accessing maxlen */ case IFQCTL_DROPS: - return (sysctl_rdint(oldp, oldlenp, newp, ifq->ifq_drops)); - default: - return (EOPNOTSUPP); - } - /* NOTREACHED */ -} - -int -sysctl_niq(int *name, u_int namelen, void *oldp, size_t *oldlenp, - void *newp, size_t newlen, struct niqueue *niq) -{ - /* All sysctl names at this level are terminal. */ - if (namelen != 1) - return (ENOTDIR); - - switch (name[0]) { - case IFQCTL_LEN: - return (sysctl_rdint(oldp, oldlenp, newp, niq_len(niq))); - case IFQCTL_MAXLEN: - return (sysctl_int(oldp, oldlenp, newp, newlen, - &niq->ni_q.mq_maxlen)); /* XXX */ - case IFQCTL_DROPS: - return (sysctl_rdint(oldp, oldlenp, newp, niq_drops(niq))); + return (sysctl_rdint(oldp, oldlenp, newp, mq_drops(mq))); default: return (EOPNOTSUPP); } diff --git a/sys/net/if_var.h b/sys/net/if_var.h index 9ecd7d0bf9c..6c84dd2e183 100644 --- a/sys/net/if_var.h +++ b/sys/net/if_var.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if_var.h,v 1.24 2015/04/07 10:46:20 mpi Exp $ */ +/* $OpenBSD: if_var.h,v 1.25 2015/04/23 09:45:24 dlg Exp $ */ /* $NetBSD: if.h,v 1.23 1996/05/07 02:40:27 thorpej Exp $ */ /* @@ -411,6 +411,8 @@ int niq_enlist(struct niqueue *, struct mbuf_list *); #define niq_filter(_q, _f, _c) mq_filter(&(_q)->ni_q, (_f), (_c)) #define niq_len(_q) mq_len(&(_q)->ni_q) #define niq_drops(_q) mq_drops(&(_q)->ni_q) +#define sysctl_niq(_n, _l, _op, _olp, _np, _nl, _niq) \ + sysctl_mq((_n), (_l), (_op), (_olp), (_np), (_nl), &(_niq)->ni_q) extern struct ifnet_head ifnet; extern struct ifnet *lo0ifp; @@ -441,10 +443,8 @@ void if_clone_detach(struct if_clone *); int if_clone_create(const char *); int if_clone_destroy(const char *); -int sysctl_ifq(int *, u_int, void *, size_t *, void *, size_t, - struct ifqueue *); -int sysctl_niq(int *, u_int, void *, size_t *, void *, size_t, - struct niqueue *); +int sysctl_mq(int *, u_int, void *, size_t *, void *, size_t, + struct mbuf_queue *); int loioctl(struct ifnet *, u_long, caddr_t); void loopattach(int); diff --git a/sys/net/pipex.c b/sys/net/pipex.c index 51fc8c3b2f2..7c93ab6fbdc 100644 --- a/sys/net/pipex.c +++ b/sys/net/pipex.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pipex.c,v 1.68 2015/04/10 13:58:20 dlg Exp $ */ +/* $OpenBSD: pipex.c,v 1.69 2015/04/23 09:45:24 dlg Exp $ */ /*- * Copyright (c) 2009 Internet Initiative Japan Inc. @@ -100,8 +100,8 @@ struct timeout pipex_timer_ch; /* callout timer context */ int pipex_prune = 1; /* walk list every seconds */ /* pipex traffic queue */ -struct ifqueue pipexinq; -struct ifqueue pipexoutq; +struct mbuf_queue pipexinq = MBUF_QUEUE_INITIALIZER(IFQ_MAXLEN, IPL_NET); +struct mbuf_queue pipexoutq = MBUF_QUEUE_INITIALIZER(IFQ_MAXLEN, IPL_NET); void *pipex_softintr = NULL; Static void pipex_softintr_handler(void *); @@ -144,9 +144,7 @@ pipex_init(void) LIST_INIT(&pipex_id_hashtable[i]); for (i = 0; i < nitems(pipex_peer_addr_hashtable); i++) LIST_INIT(&pipex_peer_addr_hashtable[i]); - /* queue and softintr init */ - IFQ_SET_MAXLEN(&pipexinq, IFQ_MAXLEN); - IFQ_SET_MAXLEN(&pipexoutq, IFQ_MAXLEN); + /* softintr init */ pipex_softintr = softintr_establish(IPL_SOFTNET, pipex_softintr_handler, NULL); } @@ -718,18 +716,11 @@ pipex_ppp_dequeue(void) struct pipex_session *pkt_session; u_int16_t proto; struct mbuf *m; - int c, s; + struct mbuf_list ml; /* ppp output */ - for (c = 0; c < PIPEX_DEQUEUE_LIMIT; c++) { - s = splnet(); - IF_DEQUEUE(&pipexoutq, m); - if (m == NULL) { - splx(s); - break; - } - splx(s); - + mq_delist(&pipexoutq, &ml); + while ((m = ml_dequeue(&ml)) != NULL) { pkt_session = m->m_pkthdr.ph_cookie; if (pkt_session == NULL) { m_freem(m); @@ -765,15 +756,8 @@ pipex_ppp_dequeue(void) } /* ppp input */ - for (c = 0; c < PIPEX_DEQUEUE_LIMIT; c++) { - s = splnet(); - IF_DEQUEUE(&pipexinq, m); - if (m == NULL) { - splx(s); - break; - } - splx(s); - + mq_delist(&pipexinq, &ml); + while ((m = ml_dequeue(&ml)) != NULL) { pkt_session = m->m_pkthdr.ph_cookie; if (pkt_session == NULL) { m_freem(m); @@ -781,42 +765,21 @@ pipex_ppp_dequeue(void) } pipex_ppp_input(m, pkt_session, 0); } - - /* - * When packet remains in queue, it is necessary - * to re-schedule software interrupt. - */ - s = splnet(); - if (!IF_IS_EMPTY(&pipexinq) || !IF_IS_EMPTY(&pipexoutq)) - softintr_schedule(pipex_softintr); - splx(s); } Static int pipex_ppp_enqueue(struct mbuf *m0, struct pipex_session *session, - struct ifqueue *queue) + struct mbuf_queue *mq) { - int s; - m0->m_pkthdr.ph_cookie = session; /* XXX need to support other protocols */ m0->m_pkthdr.ph_ppp_proto = PPP_IP; - s = splnet(); - if (IF_QFULL(queue)) { - IF_DROP(queue); - splx(s); - goto fail; - } - IF_ENQUEUE(queue, m0); - splx(s); + if (mq_enqueue(mq, m0) != 0) + return (1); softintr_schedule(pipex_softintr); return (0); - -fail: - /* caller is responsible for freeing m0 */ - return (1); } /*********************************************************************** @@ -878,7 +841,7 @@ pipex_timer(void *ignored_arg) * mbuf queued in pipexinq or pipexoutq may have a * refererce to this session. */ - if (!IF_IS_EMPTY(&pipexinq) || !IF_IS_EMPTY(&pipexoutq)) + if (!mq_empty(&pipexinq) || !mq_empty(&pipexoutq)) continue; pipex_destroy_session(session); @@ -966,7 +929,7 @@ pipex_ip_output(struct mbuf *m0, struct pipex_session *session) is_idle = 0; m0 = ip_is_idle_packet(m0, &is_idle); if (m0 == NULL) - goto drop; + goto dropped; if (is_idle == 0) /* update expire time */ session->stat.idle_time = 0; @@ -976,19 +939,20 @@ pipex_ip_output(struct mbuf *m0, struct pipex_session *session) if ((session->ppp_flags & PIPEX_PPP_ADJUST_TCPMSS) != 0) { m0 = adjust_tcp_mss(m0, session->peer_mru); if (m0 == NULL) - goto drop; + goto dropped; } } else m0->m_flags &= ~(M_BCAST|M_MCAST); /* output ip packets to the session tunnel */ if (pipex_ppp_enqueue(m0, session, &pipexoutq)) - goto drop; + goto dropped; return; drop: if (m0 != NULL) m_freem(m0); +dropped: session->stat.oerrors++; } @@ -1323,10 +1287,13 @@ pipex_common_input(struct pipex_session *session, struct mbuf *m0, int hlen, } /* input ppp packets to kernel session */ - if (pipex_ppp_enqueue(m0, session, &pipexinq) == 0) + if (pipex_ppp_enqueue(m0, session, &pipexinq) != 0) + goto dropped; + else return (NULL); drop: m_freem(m0); +dropped: session->stat.ierrors++; return (NULL); @@ -3071,10 +3038,10 @@ pipex_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, return (sysctl_int(oldp, oldlenp, newp, newlen, &pipex_enable)); case PIPEXCTL_INQ: - return (sysctl_ifq(name + 1, namelen - 1, + return (sysctl_mq(name + 1, namelen - 1, oldp, oldlenp, newp, newlen, &pipexinq)); case PIPEXCTL_OUTQ: - return (sysctl_ifq(name + 1, namelen - 1, + return (sysctl_mq(name + 1, namelen - 1, oldp, oldlenp, newp, newlen, &pipexoutq)); default: return (ENOPROTOOPT); diff --git a/sys/net/pipex_local.h b/sys/net/pipex_local.h index 7e3287d285d..86685532ea1 100644 --- a/sys/net/pipex_local.h +++ b/sys/net/pipex_local.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pipex_local.h,v 1.21 2014/12/01 06:55:05 yasuoka Exp $ */ +/* $OpenBSD: pipex_local.h,v 1.22 2015/04/23 09:45:24 dlg Exp $ */ /* * Copyright (c) 2009 Internet Initiative Japan Inc. @@ -49,7 +49,6 @@ #define PIPEX_HASH_SIZE (PIPEX_MAX_SESSION/PIPEX_HASH_DIV) #define PIPEX_HASH_MASK (PIPEX_HASH_SIZE-1) #define PIPEX_CLOSE_TIMEOUT 30 -#define PIPEX_DEQUEUE_LIMIT (IFQ_MAXLEN >> 1) #define PIPEX_PPPMINLEN 5 /* minimum PPP header length is 1 and minimum ppp payload length is 4 */ @@ -427,7 +426,7 @@ Static struct mbuf *ip_is_idle_packet (struct mbuf *, int *); Static void pipex_session_log (struct pipex_session *, int, const char *, ...) __attribute__((__format__(__printf__,3,4))); Static uint32_t pipex_sockaddr_hash_key(struct sockaddr *); Static int pipex_sockaddr_compar_addr(struct sockaddr *, struct sockaddr *); -Static int pipex_ppp_enqueue (struct mbuf *, struct pipex_session *, struct ifqueue *); +Static int pipex_ppp_enqueue (struct mbuf *, struct pipex_session *, struct mbuf_queue *); Static void pipex_ppp_dequeue (void); Static void pipex_timer_start (void); Static void pipex_timer_stop (void); -- 2.20.1