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