From e7d68516df704885cd43eeb98295502dccf0c435 Mon Sep 17 00:00:00 2001 From: Sepherosa Ziehau Date: Thu, 29 Dec 2016 20:47:10 +0800 Subject: [PATCH] ifq: Factor out if_classq from altq_classq and use it for default ifq. This reduces memory foot print for default ifq and could be used by the upcoming "flow" of FQ-CoDel. --- sys/net/altq/altq_classq.h | 32 +++++++------------ sys/net/altq/if_altq.h | 10 +++--- sys/net/altq/if_classq.h | 79 ++++++++++++++++++++++++++++++++++++++++++++++ sys/net/if.c | 37 +++++++--------------- 4 files changed, 105 insertions(+), 53 deletions(-) create mode 100644 sys/net/altq/if_classq.h diff --git a/sys/net/altq/altq_classq.h b/sys/net/altq/altq_classq.h index fb396342b0..706ca85fd4 100644 --- a/sys/net/altq/altq_classq.h +++ b/sys/net/altq/altq_classq.h @@ -39,6 +39,8 @@ #ifndef _ALTQ_ALTQ_CLASSQ_H_ #define _ALTQ_ALTQ_CLASSQ_H_ +#include + /* * Packet Queue types: RED or DROPHEAD. */ @@ -53,7 +55,7 @@ * Packet Queue structures and macros to manipulate them. */ struct _class_queue_ { - struct mbuf *tail_; /* Tail of packet queue */ + struct if_classq que_; int qlen_; /* Queue length (in number of packets) */ int qlim_; /* Queue limit (in number of packets*) */ int qtype_; /* Queue type */ @@ -64,8 +66,8 @@ typedef struct _class_queue_ class_queue_t; #define qtype(q) (q)->qtype_ /* Get queue type */ #define qlimit(q) (q)->qlim_ /* Max packets to be queued */ #define qlen(q) (q)->qlen_ /* Current queue length. */ -#define qtail(q) (q)->tail_ /* Tail of the queue */ -#define qhead(q) ((q)->tail_ ? (q)->tail_->m_nextpkt : NULL) +#define qtail(q) classq_tail(&(q)->que_) /* Tail of the queue */ +#define qhead(q) classq_head(&(q)->que_) #define qempty(q) ((q)->qlen_ == 0) /* Is the queue empty?? */ #define q_is_red(q) ((q)->qtype_ == Q_RED) /* Is the queue a red queue */ @@ -75,31 +77,19 @@ typedef struct _class_queue_ class_queue_t; static __inline void _addq(class_queue_t *q, struct mbuf *m) { - struct mbuf *m0; - - if ((m0 = qtail(q)) != NULL) - m->m_nextpkt = m0->m_nextpkt; - else - m0 = m; - m0->m_nextpkt = m; - qtail(q) = m; + classq_add(&q->que_, m); qlen(q)++; } static __inline struct mbuf * _getq(class_queue_t *q) { - struct mbuf *m, *m0; + struct mbuf *m; - if ((m = qtail(q)) == NULL) - return (NULL); - if ((m0 = m->m_nextpkt) != m) - m->m_nextpkt = m0->m_nextpkt; - else - qtail(q) = NULL; - qlen(q)--; - m0->m_nextpkt = NULL; - return (m0); + m = classq_get(&q->que_); + if (m != NULL) + qlen(q)--; + return (m); } /* drop a packet at the tail of the queue */ diff --git a/sys/net/altq/if_altq.h b/sys/net/altq/if_altq.h index 671608cbd5..1f9f364ee0 100644 --- a/sys/net/altq/if_altq.h +++ b/sys/net/altq/if_altq.h @@ -28,9 +28,9 @@ #ifndef _NET_ALTQ_IF_ALTQ_H_ #define _NET_ALTQ_IF_ALTQ_H_ -#ifndef _SYS_SERIALIZE_H_ +#include #include -#endif +#include /* Default subqueue */ #define ALTQ_SUBQ_INDEX_DEFAULT 0 @@ -67,10 +67,8 @@ struct ifaltq_subque { struct ifnet *ifsq_ifp; void *ifsq_hw_priv; /* hw private data */ - struct mbuf *ifsq_prio_head; - struct mbuf *ifsq_prio_tail; - struct mbuf *ifsq_norm_head; - struct mbuf *ifsq_norm_tail; + struct if_classq ifsq_norm; + struct if_classq ifsq_prio; int ifsq_prio_len; int ifsq_prio_bcnt; int ifsq_len; /* packet counter */ diff --git a/sys/net/altq/if_classq.h b/sys/net/altq/if_classq.h new file mode 100644 index 0000000000..4db5d87a6d --- /dev/null +++ b/sys/net/altq/if_classq.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 1991-1997 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Network Research + * Group at Lawrence Berkeley Laboratory. + * 4. Neither the name of the University nor of the Laboratory may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +/* + * class queue definitions extracted from altq_classq.h. + */ + +#ifndef _NET_IF_CLASSQ_H_ +#define _NET_IF_CLASSQ_H_ + +struct if_classq { + struct mbuf *clq_tail; /* Tail of packet queue */ +}; + +#ifdef _KERNEL + +#define classq_tail(q) (q)->clq_tail +#define classq_head(q) ((q)->clq_tail ? (q)->clq_tail->m_nextpkt : NULL) + +static __inline void +classq_add(struct if_classq *q, struct mbuf *m) +{ + struct mbuf *m0; + + if ((m0 = classq_tail(q)) != NULL) + m->m_nextpkt = m0->m_nextpkt; + else + m0 = m; + m0->m_nextpkt = m; + classq_tail(q) = m; +} + +static __inline struct mbuf * +classq_get(struct if_classq *q) +{ + struct mbuf *m, *m0; + + if ((m = classq_tail(q)) == NULL) + return (NULL); + if ((m0 = m->m_nextpkt) != m) + m->m_nextpkt = m0->m_nextpkt; + else + classq_tail(q) = NULL; + m0->m_nextpkt = NULL; + return (m0); +} + +#endif /* _KERNEL */ + +#endif /* !_NET_IF_CLASSQ_H_ */ diff --git a/sys/net/if.c b/sys/net/if.c index e02626dd2e..db24f7bcb4 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -2765,24 +2765,16 @@ ifq_set_methods(struct ifaltq *ifq, altq_mapsubq_t mapsubq, static void ifsq_norm_enqueue(struct ifaltq_subque *ifsq, struct mbuf *m) { - m->m_nextpkt = NULL; - if (ifsq->ifsq_norm_tail == NULL) - ifsq->ifsq_norm_head = m; - else - ifsq->ifsq_norm_tail->m_nextpkt = m; - ifsq->ifsq_norm_tail = m; + + classq_add(&ifsq->ifsq_norm, m); ALTQ_SQ_CNTR_INC(ifsq, m->m_pkthdr.len); } static void ifsq_prio_enqueue(struct ifaltq_subque *ifsq, struct mbuf *m) { - m->m_nextpkt = NULL; - if (ifsq->ifsq_prio_tail == NULL) - ifsq->ifsq_prio_head = m; - else - ifsq->ifsq_prio_tail->m_nextpkt = m; - ifsq->ifsq_prio_tail = m; + + classq_add(&ifsq->ifsq_prio, m); ALTQ_SQ_CNTR_INC(ifsq, m->m_pkthdr.len); ALTQ_SQ_PRIO_CNTR_INC(ifsq, m->m_pkthdr.len); } @@ -2792,14 +2784,10 @@ ifsq_norm_dequeue(struct ifaltq_subque *ifsq) { struct mbuf *m; - m = ifsq->ifsq_norm_head; - if (m != NULL) { - if ((ifsq->ifsq_norm_head = m->m_nextpkt) == NULL) - ifsq->ifsq_norm_tail = NULL; - m->m_nextpkt = NULL; + m = classq_get(&ifsq->ifsq_norm); + if (m != NULL) ALTQ_SQ_CNTR_DEC(ifsq, m->m_pkthdr.len); - } - return m; + return (m); } static struct mbuf * @@ -2807,15 +2795,12 @@ ifsq_prio_dequeue(struct ifaltq_subque *ifsq) { struct mbuf *m; - m = ifsq->ifsq_prio_head; + m = classq_get(&ifsq->ifsq_prio); if (m != NULL) { - if ((ifsq->ifsq_prio_head = m->m_nextpkt) == NULL) - ifsq->ifsq_prio_tail = NULL; - m->m_nextpkt = NULL; ALTQ_SQ_CNTR_DEC(ifsq, m->m_pkthdr.len); ALTQ_SQ_PRIO_CNTR_DEC(ifsq, m->m_pkthdr.len); } - return m; + return (m); } int @@ -2868,9 +2853,9 @@ ifsq_classic_dequeue(struct ifaltq_subque *ifsq, int op) switch (op) { case ALTDQ_POLL: - m = ifsq->ifsq_prio_head; + m = classq_head(&ifsq->ifsq_prio); if (m == NULL) - m = ifsq->ifsq_norm_head; + m = classq_head(&ifsq->ifsq_norm); break; case ALTDQ_REMOVE: -- 2.11.4.GIT