]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/net/classq/classq_subr.c
xnu-3248.50.21.tar.gz
[apple/xnu.git] / bsd / net / classq / classq_subr.c
index 738c86e2371e2d96ed258c9699b1561ec61f385e..98c007bd9da8a11296e3d20333561a4eec3505c8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2011-2015 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  *
@@ -95,6 +95,7 @@ ifclassq_setup(struct ifnet *ifp, u_int32_t sflags, boolean_t reuse)
        VERIFY(IFCQ_IS_EMPTY(ifq));
        ifq->ifcq_ifp = ifp;
        IFCQ_LEN(ifq) = 0;
+       IFCQ_BYTES(ifq) = 0;
        bzero(&ifq->ifcq_xmitcnt, sizeof (ifq->ifcq_xmitcnt));
        bzero(&ifq->ifcq_dropcnt, sizeof (ifq->ifcq_dropcnt));
 
@@ -115,6 +116,14 @@ ifclassq_setup(struct ifnet *ifp, u_int32_t sflags, boolean_t reuse)
                        maxlen = if_sndq_maxlen;
                IFCQ_SET_MAXLEN(ifq, maxlen);
 
+               if (IFCQ_MAXLEN(ifq) != if_sndq_maxlen &&
+                   IFCQ_TARGET_QDELAY(ifq) == 0) {
+                       /*
+                        * Choose static queues because the interface has
+                        * maximum queue size set
+                        */
+                       sflags &= ~PKTSCHEDF_QALG_DELAYBASED;
+               }
                ifq->ifcq_sflags = sflags;
                err = ifclassq_pktsched_setup(ifq);
                if (err == 0)
@@ -189,6 +198,7 @@ ifclassq_teardown(struct ifnet *ifp)
        VERIFY(ifq->ifcq_dequeue_sc == NULL);
        VERIFY(ifq->ifcq_request == NULL);
        IFCQ_LEN(ifq) = 0;
+       IFCQ_BYTES(ifq) = 0;
        IFCQ_MAXLEN(ifq) = 0;
        bzero(&ifq->ifcq_xmitcnt, sizeof (ifq->ifcq_xmitcnt));
        bzero(&ifq->ifcq_dropcnt, sizeof (ifq->ifcq_dropcnt));
@@ -238,10 +248,24 @@ ifclassq_get_maxlen(struct ifclassq *ifq)
        return (IFCQ_MAXLEN(ifq));
 }
 
-u_int32_t
-ifclassq_get_len(struct ifclassq *ifq)
+int
+ifclassq_get_len(struct ifclassq *ifq, mbuf_svc_class_t sc, u_int32_t *packets,
+    u_int32_t *bytes)
 {
-       return (IFCQ_LEN(ifq));
+       int err = 0;
+
+       IFCQ_LOCK(ifq);
+       if (sc == MBUF_SC_UNSPEC) {
+               VERIFY(packets != NULL);
+               *packets = IFCQ_LEN(ifq);
+       } else {
+               VERIFY(MBUF_VALID_SC(sc));
+               VERIFY(packets != NULL && bytes != NULL);
+               IFCQ_LEN_SC(ifq, sc, packets, bytes, err);
+       }
+       IFCQ_UNLOCK(ifq);
+
+       return (err);
 }
 
 errno_t
@@ -309,7 +333,6 @@ ifclassq_dequeue_common(struct ifclassq *ifq, mbuf_svc_class_t sc,
        IFCQ_LOCK_SPIN(ifq);
 
        while (i < limit) {
-               u_int64_t pktlen;
 #if PF_ALTQ
                u_int32_t qlen;
 
@@ -361,11 +384,17 @@ ifclassq_dequeue_common(struct ifclassq *ifq, mbuf_svc_class_t sc,
                last = *head;
 
                l += (*head)->m_pkthdr.len;
-               pktlen = (*head)->m_pkthdr.len;
-
-               (*head)->m_pkthdr.pf_mtag.pftag_pktseq =
-                   atomic_add_64_ov(&(ifp->if_bw.cur_seq), pktlen);
 
+#if MEASURE_BW
+               (*head)->m_pkthdr.pkt_bwseq =
+                   atomic_add_64_ov(&(ifp->if_bw.cur_seq), m_pktlen(*head));
+#endif /* MEASURE_BW */
+               if (IFNET_IS_CELLULAR(ifp)) {
+                       (*head)->m_pkthdr.pkt_flags |= PKTF_VALID_UNSENT_DATA;
+                       (*head)->m_pkthdr.pkt_unsent_databytes =
+                           (total_snd_byte_count << MSIZESHIFT) +
+                           ifq->ifcq_bytes;
+               }
                head = &(*head)->m_nextpkt;
                i++;
        }
@@ -539,8 +568,12 @@ ifclassq_ev2str(cqev_t ev)
        const char *c;
 
        switch (ev) {
-       case CLASSQ_EV_LINK_SPEED:
-               c = "LINK_SPEED";
+       case CLASSQ_EV_LINK_BANDWIDTH:
+               c = "LINK_BANDWIDTH";
+               break;
+
+       case CLASSQ_EV_LINK_LATENCY:
+               c = "LINK_LATENCY";
                break;
 
        case CLASSQ_EV_LINK_MTU:
@@ -704,7 +737,7 @@ ifclassq_tbr_set(struct ifclassq *ifq, struct tb_profile *profile,
                bzero(tbr, sizeof (*tbr));
                ifnet_set_start_cycle(ifp, NULL);
                if (update)
-                       ifclassq_update(ifq, CLASSQ_EV_LINK_SPEED);
+                       ifclassq_update(ifq, CLASSQ_EV_LINK_BANDWIDTH);
                return (0);
        }
 
@@ -788,7 +821,7 @@ ifclassq_tbr_set(struct ifclassq *ifq, struct tb_profile *profile,
                ifnet_set_start_cycle(ifp, NULL);
        }
        if (update && tbr->tbr_rate_raw != old_rate)
-               ifclassq_update(ifq, CLASSQ_EV_LINK_SPEED);
+               ifclassq_update(ifq, CLASSQ_EV_LINK_BANDWIDTH);
 
        return (0);
 }