1*fdd8201dSApple OSS Distributions /* 2*fdd8201dSApple OSS Distributions * Copyright (c) 2016-2021 Apple Inc. All rights reserved. 3*fdd8201dSApple OSS Distributions * 4*fdd8201dSApple OSS Distributions * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5*fdd8201dSApple OSS Distributions * 6*fdd8201dSApple OSS Distributions * This file contains Original Code and/or Modifications of Original Code 7*fdd8201dSApple OSS Distributions * as defined in and that are subject to the Apple Public Source License 8*fdd8201dSApple OSS Distributions * Version 2.0 (the 'License'). You may not use this file except in 9*fdd8201dSApple OSS Distributions * compliance with the License. The rights granted to you under the License 10*fdd8201dSApple OSS Distributions * may not be used to create, or enable the creation or redistribution of, 11*fdd8201dSApple OSS Distributions * unlawful or unlicensed copies of an Apple operating system, or to 12*fdd8201dSApple OSS Distributions * circumvent, violate, or enable the circumvention or violation of, any 13*fdd8201dSApple OSS Distributions * terms of an Apple operating system software license agreement. 14*fdd8201dSApple OSS Distributions * 15*fdd8201dSApple OSS Distributions * Please obtain a copy of the License at 16*fdd8201dSApple OSS Distributions * http://www.opensource.apple.com/apsl/ and read it before using this file. 17*fdd8201dSApple OSS Distributions * 18*fdd8201dSApple OSS Distributions * The Original Code and all software distributed under the License are 19*fdd8201dSApple OSS Distributions * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20*fdd8201dSApple OSS Distributions * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21*fdd8201dSApple OSS Distributions * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22*fdd8201dSApple OSS Distributions * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23*fdd8201dSApple OSS Distributions * Please see the License for the specific language governing rights and 24*fdd8201dSApple OSS Distributions * limitations under the License. 25*fdd8201dSApple OSS Distributions * 26*fdd8201dSApple OSS Distributions * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27*fdd8201dSApple OSS Distributions */ 28*fdd8201dSApple OSS Distributions 29*fdd8201dSApple OSS Distributions #ifndef _NET_CLASSQ_CLASSQ_FQ_CODEL_H 30*fdd8201dSApple OSS Distributions #define _NET_CLASSQ_CLASSQ_FQ_CODEL_H 31*fdd8201dSApple OSS Distributions #ifdef PRIVATE 32*fdd8201dSApple OSS Distributions #ifdef BSD_KERNEL_PRIVATE 33*fdd8201dSApple OSS Distributions #include <stdbool.h> 34*fdd8201dSApple OSS Distributions #include <sys/time.h> 35*fdd8201dSApple OSS Distributions #include <net/flowadv.h> 36*fdd8201dSApple OSS Distributions #include <net/classq/if_classq.h> 37*fdd8201dSApple OSS Distributions #if SKYWALK 38*fdd8201dSApple OSS Distributions #include <skywalk/os_skywalk_private.h> 39*fdd8201dSApple OSS Distributions #endif /* SKYWALK */ 40*fdd8201dSApple OSS Distributions 41*fdd8201dSApple OSS Distributions #ifdef __cplusplus 42*fdd8201dSApple OSS Distributions extern "C" { 43*fdd8201dSApple OSS Distributions #endif 44*fdd8201dSApple OSS Distributions 45*fdd8201dSApple OSS Distributions #define FQ_MIN_FC_THRESHOLD_BYTES 7500 46*fdd8201dSApple OSS Distributions #define FQ_IS_DELAYHIGH(_fq_) ((_fq_)->fq_flags & FQF_DELAY_HIGH) 47*fdd8201dSApple OSS Distributions #define FQ_SET_DELAY_HIGH(_fq_) do { \ 48*fdd8201dSApple OSS Distributions (_fq_)->fq_flags |= FQF_DELAY_HIGH; \ 49*fdd8201dSApple OSS Distributions } while (0) 50*fdd8201dSApple OSS Distributions #define FQ_CLEAR_DELAY_HIGH(_fq_) do { \ 51*fdd8201dSApple OSS Distributions (_fq_)->fq_flags &= ~FQF_DELAY_HIGH; \ 52*fdd8201dSApple OSS Distributions } while (0) 53*fdd8201dSApple OSS Distributions 54*fdd8201dSApple OSS Distributions #define FQ_IS_OVERWHELMING(_fq_) ((_fq_)->fq_flags & FQF_OVERWHELMING) 55*fdd8201dSApple OSS Distributions #define FQ_SET_OVERWHELMING(_fq_) do { \ 56*fdd8201dSApple OSS Distributions (_fq_)->fq_flags |= FQF_OVERWHELMING; \ 57*fdd8201dSApple OSS Distributions } while (0) 58*fdd8201dSApple OSS Distributions #define FQ_CLEAR_OVERWHELMING(_fq_) do { \ 59*fdd8201dSApple OSS Distributions (_fq_)->fq_flags &= ~FQF_OVERWHELMING; \ 60*fdd8201dSApple OSS Distributions } while (0) 61*fdd8201dSApple OSS Distributions 62*fdd8201dSApple OSS Distributions typedef struct flowq { 63*fdd8201dSApple OSS Distributions union { 64*fdd8201dSApple OSS Distributions MBUFQ_HEAD(mbufq_head) __mbufq; /* mbuf packet queue */ 65*fdd8201dSApple OSS Distributions #if SKYWALK 66*fdd8201dSApple OSS Distributions KPKTQ_HEAD(kpktq_head) __kpktq; /* skywalk packet queue */ 67*fdd8201dSApple OSS Distributions #endif /* SKYWALK */ 68*fdd8201dSApple OSS Distributions } __fq_pktq_u; 69*fdd8201dSApple OSS Distributions #define FQF_FLOWCTL_CAPABLE 0x01 /* Use flow control instead of drop */ 70*fdd8201dSApple OSS Distributions #define FQF_DELAY_HIGH 0x02 /* Min delay is greater than target */ 71*fdd8201dSApple OSS Distributions #define FQF_NEW_FLOW 0x04 /* Currently on new flows queue */ 72*fdd8201dSApple OSS Distributions #define FQF_OLD_FLOW 0x08 /* Currently on old flows queue */ 73*fdd8201dSApple OSS Distributions #define FQF_FLOWCTL_ON 0x10 /* Currently flow controlled */ 74*fdd8201dSApple OSS Distributions #define FQF_DESTROYED 0x80 /* flowq destroyed */ 75*fdd8201dSApple OSS Distributions #define FQF_OVERWHELMING 0x40 /* The largest flow when AQM hits queue limit */ 76*fdd8201dSApple OSS Distributions uint8_t fq_flags; /* flags */ 77*fdd8201dSApple OSS Distributions uint8_t fq_sc_index; /* service_class index */ 78*fdd8201dSApple OSS Distributions int32_t fq_deficit; /* Deficit for scheduling */ 79*fdd8201dSApple OSS Distributions uint32_t fq_bytes; /* Number of bytes in the queue */ 80*fdd8201dSApple OSS Distributions uint64_t fq_min_qdelay; /* min queue delay for Codel */ 81*fdd8201dSApple OSS Distributions uint64_t fq_updatetime; /* next update interval */ 82*fdd8201dSApple OSS Distributions uint64_t fq_getqtime; /* last dequeue time */ 83*fdd8201dSApple OSS Distributions SLIST_ENTRY(flowq) fq_hashlink; /* for flow queue hash table */ 84*fdd8201dSApple OSS Distributions STAILQ_ENTRY(flowq) fq_actlink; /* for new/old flow queues */ 85*fdd8201dSApple OSS Distributions uint32_t fq_flowhash; /* Flow hash */ 86*fdd8201dSApple OSS Distributions classq_pkt_type_t fq_ptype; /* Packet type */ 87*fdd8201dSApple OSS Distributions /* temporary packet queue for dequeued packets */ 88*fdd8201dSApple OSS Distributions classq_pkt_t fq_dq_head; 89*fdd8201dSApple OSS Distributions classq_pkt_t fq_dq_tail; 90*fdd8201dSApple OSS Distributions STAILQ_ENTRY(flowq) fq_dqlink; /* entry on dequeue flow list */ 91*fdd8201dSApple OSS Distributions bool fq_in_dqlist; 92*fdd8201dSApple OSS Distributions } fq_t; 93*fdd8201dSApple OSS Distributions 94*fdd8201dSApple OSS Distributions #define fq_mbufq __fq_pktq_u.__mbufq 95*fdd8201dSApple OSS Distributions #if SKYWALK 96*fdd8201dSApple OSS Distributions #define fq_kpktq __fq_pktq_u.__kpktq 97*fdd8201dSApple OSS Distributions #endif /* SKYWALK */ 98*fdd8201dSApple OSS Distributions 99*fdd8201dSApple OSS Distributions #if SKYWALK 100*fdd8201dSApple OSS Distributions #define fq_empty(_q) (((_q)->fq_ptype == QP_MBUF) ? \ 101*fdd8201dSApple OSS Distributions MBUFQ_EMPTY(&(_q)->fq_mbufq) : \ 102*fdd8201dSApple OSS Distributions KPKTQ_EMPTY(&(_q)->fq_kpktq)) 103*fdd8201dSApple OSS Distributions #else /* !SKYWALK */ 104*fdd8201dSApple OSS Distributions #define fq_empty(_q) MBUFQ_EMPTY(&(_q)->fq_mbufq) 105*fdd8201dSApple OSS Distributions #endif /* !SKYWALK */ 106*fdd8201dSApple OSS Distributions 107*fdd8201dSApple OSS Distributions #if SKYWALK 108*fdd8201dSApple OSS Distributions #define fq_enqueue(_q, _h, _t, _c) do { \ 109*fdd8201dSApple OSS Distributions switch ((_q)->fq_ptype) { \ 110*fdd8201dSApple OSS Distributions case QP_MBUF: \ 111*fdd8201dSApple OSS Distributions ASSERT((_h).cp_ptype == QP_MBUF); \ 112*fdd8201dSApple OSS Distributions ASSERT((_t).cp_ptype == QP_MBUF); \ 113*fdd8201dSApple OSS Distributions MBUFQ_ENQUEUE_MULTI(&(_q)->fq_mbufq, (_h).cp_mbuf, \ 114*fdd8201dSApple OSS Distributions (_t).cp_mbuf); \ 115*fdd8201dSApple OSS Distributions MBUFQ_ADD_CRUMB_MULTI(&(_q)->fq_mbufq, (_h).cp_mbuf, \ 116*fdd8201dSApple OSS Distributions (_t).cp_mbuf, PKT_CRUMB_FQ_ENQUEUE); \ 117*fdd8201dSApple OSS Distributions break; \ 118*fdd8201dSApple OSS Distributions case QP_PACKET: \ 119*fdd8201dSApple OSS Distributions ASSERT((_h).cp_ptype == QP_PACKET); \ 120*fdd8201dSApple OSS Distributions ASSERT((_t).cp_ptype == QP_PACKET); \ 121*fdd8201dSApple OSS Distributions KPKTQ_ENQUEUE_MULTI(&(_q)->fq_kpktq, (_h).cp_kpkt, \ 122*fdd8201dSApple OSS Distributions (_t).cp_kpkt, (_c)); \ 123*fdd8201dSApple OSS Distributions break; \ 124*fdd8201dSApple OSS Distributions default: \ 125*fdd8201dSApple OSS Distributions VERIFY(0); \ 126*fdd8201dSApple OSS Distributions __builtin_unreachable(); \ 127*fdd8201dSApple OSS Distributions break; \ 128*fdd8201dSApple OSS Distributions } \ 129*fdd8201dSApple OSS Distributions } while (0) 130*fdd8201dSApple OSS Distributions #else /* !SKYWALK */ 131*fdd8201dSApple OSS Distributions #define fq_enqueue(_q, _h, _t, _c) do { \ 132*fdd8201dSApple OSS Distributions MBUFQ_ENQUEUE_MULTI(&(_q)->fq_mbufq, (_h).cp_mbuf, \ 133*fdd8201dSApple OSS Distributions (_t).cp_mbuf); \ 134*fdd8201dSApple OSS Distributions MBUFQ_ADD_CRUMB_MULTI(&(_q)->fq_mbufq, (_h).cp_mbuf, \ 135*fdd8201dSApple OSS Distributions (_t).cp_mbuf, PKT_CRUMB_FQ_ENQUEUE); \ 136*fdd8201dSApple OSS Distributions } while (0) 137*fdd8201dSApple OSS Distributions #endif /* !SKYWALK */ 138*fdd8201dSApple OSS Distributions 139*fdd8201dSApple OSS Distributions #if SKYWALK 140*fdd8201dSApple OSS Distributions #define fq_dequeue(_q, _p) do { \ 141*fdd8201dSApple OSS Distributions switch ((_q)->fq_ptype) { \ 142*fdd8201dSApple OSS Distributions case QP_MBUF: { \ 143*fdd8201dSApple OSS Distributions MBUFQ_DEQUEUE(&(_q)->fq_mbufq, (_p)->cp_mbuf); \ 144*fdd8201dSApple OSS Distributions if (__probable((_p)->cp_mbuf != NULL)) { \ 145*fdd8201dSApple OSS Distributions CLASSQ_PKT_INIT_MBUF((_p), (_p)->cp_mbuf); \ 146*fdd8201dSApple OSS Distributions m_add_crumb((_p)->cp_mbuf, \ 147*fdd8201dSApple OSS Distributions PKT_CRUMB_FQ_DEQUEUE); \ 148*fdd8201dSApple OSS Distributions } \ 149*fdd8201dSApple OSS Distributions break; \ 150*fdd8201dSApple OSS Distributions } \ 151*fdd8201dSApple OSS Distributions case QP_PACKET: { \ 152*fdd8201dSApple OSS Distributions KPKTQ_DEQUEUE(&(_q)->fq_kpktq, (_p)->cp_kpkt); \ 153*fdd8201dSApple OSS Distributions if (__probable((_p)->cp_kpkt != NULL)) { \ 154*fdd8201dSApple OSS Distributions CLASSQ_PKT_INIT_PACKET((_p), (_p)->cp_kpkt); \ 155*fdd8201dSApple OSS Distributions } \ 156*fdd8201dSApple OSS Distributions break; \ 157*fdd8201dSApple OSS Distributions } \ 158*fdd8201dSApple OSS Distributions default: \ 159*fdd8201dSApple OSS Distributions VERIFY(0); \ 160*fdd8201dSApple OSS Distributions __builtin_unreachable(); \ 161*fdd8201dSApple OSS Distributions break; \ 162*fdd8201dSApple OSS Distributions } \ 163*fdd8201dSApple OSS Distributions } while (0) 164*fdd8201dSApple OSS Distributions #else /* !SKYWALK */ 165*fdd8201dSApple OSS Distributions #define fq_dequeue(_q, _p) do { \ 166*fdd8201dSApple OSS Distributions MBUFQ_DEQUEUE(&(_q)->fq_mbufq, (_p)->cp_mbuf); \ 167*fdd8201dSApple OSS Distributions if (__probable((_p)->cp_mbuf != NULL)) { \ 168*fdd8201dSApple OSS Distributions CLASSQ_PKT_INIT_MBUF((_p), (_p)->cp_mbuf); \ 169*fdd8201dSApple OSS Distributions m_add_crumb((_p)->cp_mbuf, PKT_CRUMB_FQ_DEQUEUE); \ 170*fdd8201dSApple OSS Distributions } \ 171*fdd8201dSApple OSS Distributions } while (0) 172*fdd8201dSApple OSS Distributions #endif /* !SKYWALK */ 173*fdd8201dSApple OSS Distributions 174*fdd8201dSApple OSS Distributions struct fq_codel_sched_data; 175*fdd8201dSApple OSS Distributions struct fq_if_classq; 176*fdd8201dSApple OSS Distributions 177*fdd8201dSApple OSS Distributions /* Function definitions */ 178*fdd8201dSApple OSS Distributions extern void fq_codel_init(void); 179*fdd8201dSApple OSS Distributions extern void fq_codel_reap_caches(boolean_t); 180*fdd8201dSApple OSS Distributions extern fq_t *fq_alloc(classq_pkt_type_t); 181*fdd8201dSApple OSS Distributions extern void fq_destroy(fq_t *); 182*fdd8201dSApple OSS Distributions extern int fq_addq(struct fq_codel_sched_data *, pktsched_pkt_t *, 183*fdd8201dSApple OSS Distributions struct fq_if_classq *); 184*fdd8201dSApple OSS Distributions extern void fq_getq_flow(struct fq_codel_sched_data *, fq_t *, 185*fdd8201dSApple OSS Distributions pktsched_pkt_t *); 186*fdd8201dSApple OSS Distributions extern void fq_getq_flow_internal(struct fq_codel_sched_data *, 187*fdd8201dSApple OSS Distributions fq_t *, pktsched_pkt_t *); 188*fdd8201dSApple OSS Distributions extern void fq_head_drop(struct fq_codel_sched_data *, fq_t *); 189*fdd8201dSApple OSS Distributions 190*fdd8201dSApple OSS Distributions #ifdef __cplusplus 191*fdd8201dSApple OSS Distributions } 192*fdd8201dSApple OSS Distributions #endif 193*fdd8201dSApple OSS Distributions #endif /* BSD_KERNEL_PRIVATE */ 194*fdd8201dSApple OSS Distributions #endif /* PRIVATE */ 195*fdd8201dSApple OSS Distributions #endif /* _NET_CLASSQ_CLASSQ_FQ_CODEL_H */ 196