Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) #ifndef __NET_SCHED_CODEL_IMPL_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) #define __NET_SCHED_CODEL_IMPL_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Codel - The Controlled-Delay Active Queue Management algorithm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  *  Copyright (C) 2011-2012 Kathleen Nichols <nichols@pollere.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  *  Copyright (C) 2011-2012 Van Jacobson <van@pollere.net>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  *  Copyright (C) 2012 Michael D. Taht <dave.taht@bufferbloat.net>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  *  Copyright (C) 2012,2015 Eric Dumazet <edumazet@google.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  * Redistribution and use in source and binary forms, with or without
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13)  * modification, are permitted provided that the following conditions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)  * are met:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15)  * 1. Redistributions of source code must retain the above copyright
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16)  *    notice, this list of conditions, and the following disclaimer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17)  *    without modification.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18)  * 2. Redistributions in binary form must reproduce the above copyright
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19)  *    notice, this list of conditions and the following disclaimer in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20)  *    documentation and/or other materials provided with the distribution.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21)  * 3. The names of the authors may not be used to endorse or promote products
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22)  *    derived from this software without specific prior written permission.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24)  * Alternatively, provided that this notice is retained in full, this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25)  * software may be distributed under the terms of the GNU General
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26)  * Public License ("GPL") version 2, in which case the provisions of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27)  * GPL apply INSTEAD OF those given above.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29)  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30)  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31)  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32)  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33)  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34)  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35)  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36)  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37)  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38)  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39)  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40)  * DAMAGE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) /* Controlling Queue Delay (CoDel) algorithm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45)  * =========================================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46)  * Source : Kathleen Nichols and Van Jacobson
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47)  * http://queue.acm.org/detail.cfm?id=2209336
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49)  * Implemented on linux by Dave Taht and Eric Dumazet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) static void codel_params_init(struct codel_params *params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	params->interval = MS2TIME(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	params->target = MS2TIME(5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	params->ce_threshold = CODEL_DISABLED_THRESHOLD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	params->ecn = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) static void codel_vars_init(struct codel_vars *vars)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	memset(vars, 0, sizeof(*vars));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) static void codel_stats_init(struct codel_stats *stats)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	stats->maxpacket = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71)  * http://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Iterative_methods_for_reciprocal_square_roots
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72)  * new_invsqrt = (invsqrt / 2) * (3 - count * invsqrt^2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74)  * Here, invsqrt is a fixed point number (< 1.0), 32bit mantissa, aka Q0.32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) static void codel_Newton_step(struct codel_vars *vars)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	u32 invsqrt = ((u32)vars->rec_inv_sqrt) << REC_INV_SQRT_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	u32 invsqrt2 = ((u64)invsqrt * invsqrt) >> 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	u64 val = (3LL << 32) - ((u64)vars->count * invsqrt2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	val >>= 2; /* avoid overflow in following multiply */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	val = (val * invsqrt) >> (32 - 2 + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	vars->rec_inv_sqrt = val >> REC_INV_SQRT_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89)  * CoDel control_law is t + interval/sqrt(count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90)  * We maintain in rec_inv_sqrt the reciprocal value of sqrt(count) to avoid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91)  * both sqrt() and divide operation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) static codel_time_t codel_control_law(codel_time_t t,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 				      codel_time_t interval,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 				      u32 rec_inv_sqrt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	return t + reciprocal_scale(interval, rec_inv_sqrt << REC_INV_SQRT_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) static bool codel_should_drop(const struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 			      void *ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 			      struct codel_vars *vars,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 			      struct codel_params *params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 			      struct codel_stats *stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 			      codel_skb_len_t skb_len_func,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 			      codel_skb_time_t skb_time_func,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 			      u32 *backlog,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 			      codel_time_t now)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	bool ok_to_drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	u32 skb_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	if (!skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 		vars->first_above_time = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	skb_len = skb_len_func(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	vars->ldelay = now - skb_time_func(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	if (unlikely(skb_len > stats->maxpacket))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 		stats->maxpacket = skb_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	if (codel_time_before(vars->ldelay, params->target) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	    *backlog <= params->mtu) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 		/* went below - stay below for at least interval */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 		vars->first_above_time = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	ok_to_drop = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	if (vars->first_above_time == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 		/* just went above from below. If we stay above
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 		 * for at least interval we'll say it's ok to drop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 		vars->first_above_time = now + params->interval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	} else if (codel_time_after(now, vars->first_above_time)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 		ok_to_drop = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	return ok_to_drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) static struct sk_buff *codel_dequeue(void *ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 				     u32 *backlog,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 				     struct codel_params *params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 				     struct codel_vars *vars,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 				     struct codel_stats *stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 				     codel_skb_len_t skb_len_func,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 				     codel_skb_time_t skb_time_func,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 				     codel_skb_drop_t drop_func,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 				     codel_skb_dequeue_t dequeue_func)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	struct sk_buff *skb = dequeue_func(vars, ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	codel_time_t now;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	bool drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	if (!skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 		vars->dropping = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 		return skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	now = codel_get_time();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	drop = codel_should_drop(skb, ctx, vars, params, stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 				 skb_len_func, skb_time_func, backlog, now);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	if (vars->dropping) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 		if (!drop) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 			/* sojourn time below target - leave dropping state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 			vars->dropping = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 		} else if (codel_time_after_eq(now, vars->drop_next)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 			/* It's time for the next drop. Drop the current
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 			 * packet and dequeue the next. The dequeue might
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 			 * take us out of dropping state.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 			 * If not, schedule the next drop.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 			 * A large backlog might result in drop rates so high
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 			 * that the next drop should happen now,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 			 * hence the while loop.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 			while (vars->dropping &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 			       codel_time_after_eq(now, vars->drop_next)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 				vars->count++; /* dont care of possible wrap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 						* since there is no more divide
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 						*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 				codel_Newton_step(vars);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 				if (params->ecn && INET_ECN_set_ce(skb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 					stats->ecn_mark++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 					vars->drop_next =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 						codel_control_law(vars->drop_next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 								  params->interval,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 								  vars->rec_inv_sqrt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 					goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 				stats->drop_len += skb_len_func(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 				drop_func(skb, ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 				stats->drop_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 				skb = dequeue_func(vars, ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 				if (!codel_should_drop(skb, ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 						       vars, params, stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 						       skb_len_func,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 						       skb_time_func,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 						       backlog, now)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 					/* leave dropping state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 					vars->dropping = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 				} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 					/* and schedule the next drop */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 					vars->drop_next =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 						codel_control_law(vars->drop_next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 								  params->interval,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 								  vars->rec_inv_sqrt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	} else if (drop) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 		u32 delta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 		if (params->ecn && INET_ECN_set_ce(skb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 			stats->ecn_mark++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 			stats->drop_len += skb_len_func(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 			drop_func(skb, ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 			stats->drop_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 			skb = dequeue_func(vars, ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 			drop = codel_should_drop(skb, ctx, vars, params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 						 stats, skb_len_func,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 						 skb_time_func, backlog, now);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 		vars->dropping = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 		/* if min went above target close to when we last went below it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 		 * assume that the drop rate that controlled the queue on the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 		 * last cycle is a good starting point to control it now.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 		delta = vars->count - vars->lastcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 		if (delta > 1 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 		    codel_time_before(now - vars->drop_next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 				      16 * params->interval)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 			vars->count = delta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 			/* we dont care if rec_inv_sqrt approximation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 			 * is not very precise :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 			 * Next Newton steps will correct it quadratically.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 			codel_Newton_step(vars);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 			vars->count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 			vars->rec_inv_sqrt = ~0U >> REC_INV_SQRT_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 		vars->lastcount = vars->count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 		vars->drop_next = codel_control_law(now, params->interval,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 						    vars->rec_inv_sqrt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) end:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	if (skb && codel_time_after(vars->ldelay, params->ce_threshold) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	    INET_ECN_set_ce(skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 		stats->ce_mark++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	return skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) #endif