replace the use of struct ifqueue in pipex with mbuf_queues.
authordlg <dlg@openbsd.org>
Thu, 23 Apr 2015 09:45:24 +0000 (09:45 +0000)
committerdlg <dlg@openbsd.org>
Thu, 23 Apr 2015 09:45:24 +0000 (09:45 +0000)
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
sys/net/if_var.h
sys/net/pipex.c
sys/net/pipex_local.h

index 18bdf90..28e2596 100644 (file)
@@ -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);
        }
index 9ecd7d0..6c84dd2 100644 (file)
@@ -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);
index 51fc8c3..7c93ab6 100644 (file)
@@ -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);
index 7e3287d..8668553 100644 (file)
@@ -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);