include/net/codel_impl.h

Source file repositories/reference/linux-study-clean/include/net/codel_impl.h

File Facts

System
Linux kernel
Corpus path
include/net/codel_impl.h
Extension
.h
Size
8799 bytes
Lines
274
Domain
Networking Core
Bucket
Sockets, Protocols, Packet Path, And Network Policy
Inferred role
Networking Core: implementation source
Status
source implementation candidate

Why This File Exists

Networking stack implementation surface: socket APIs, protocol dispatch, packet flow, routing, filtering, and network namespaces.

Dependency Surface

Detected Declarations

Annotated Snippet

if (!drop) {
			/* sojourn time below target - leave dropping state */
			WRITE_ONCE(vars->dropping, false);
		} else if (codel_time_after_eq(now, vars->drop_next)) {
			/* It's time for the next drop. Drop the current
			 * packet and dequeue the next. The dequeue might
			 * take us out of dropping state.
			 * If not, schedule the next drop.
			 * A large backlog might result in drop rates so high
			 * that the next drop should happen now,
			 * hence the while loop.
			 */
			while (vars->dropping &&
			       codel_time_after_eq(now, vars->drop_next)) {
				/* dont care of possible wrap
				 * since there is no more divide.
				 */
				WRITE_ONCE(vars->count, vars->count + 1);
				codel_Newton_step(vars);
				if (params->ecn && INET_ECN_set_ce(skb)) {
					WRITE_ONCE(stats->ecn_mark,
						   stats->ecn_mark + 1);
					WRITE_ONCE(vars->drop_next,
						codel_control_law(vars->drop_next,
								  params->interval,
								  vars->rec_inv_sqrt));
					goto end;
				}
				stats->drop_len += skb_len_func(skb);
				drop_func(skb, ctx);
				stats->drop_count++;
				skb = dequeue_func(vars, ctx);
				if (!codel_should_drop(skb, ctx,
						       vars, params, stats,
						       skb_len_func,
						       skb_time_func,
						       backlog, now)) {
					/* leave dropping state */
					WRITE_ONCE(vars->dropping, false);
				} else {
					/* and schedule the next drop */
					WRITE_ONCE(vars->drop_next,
						codel_control_law(vars->drop_next,
								  params->interval,
								  vars->rec_inv_sqrt));
				}
			}
		}
	} else if (drop) {
		u32 delta;

		if (params->ecn && INET_ECN_set_ce(skb)) {
			WRITE_ONCE(stats->ecn_mark, stats->ecn_mark + 1);
		} else {
			stats->drop_len += skb_len_func(skb);
			drop_func(skb, ctx);
			stats->drop_count++;

			skb = dequeue_func(vars, ctx);
			drop = codel_should_drop(skb, ctx, vars, params,
						 stats, skb_len_func,
						 skb_time_func, backlog, now);
		}
		WRITE_ONCE(vars->dropping, true);
		/* if min went above target close to when we last went below it
		 * assume that the drop rate that controlled the queue on the
		 * last cycle is a good starting point to control it now.
		 */
		delta = vars->count - vars->lastcount;
		if (delta > 1 &&
		    codel_time_before(now - vars->drop_next,
				      16 * params->interval)) {
			WRITE_ONCE(vars->count, delta);
			/* we dont care if rec_inv_sqrt approximation
			 * is not very precise :
			 * Next Newton steps will correct it quadratically.
			 */
			codel_Newton_step(vars);
		} else {
			WRITE_ONCE(vars->count, 1);
			vars->rec_inv_sqrt = ~0U >> REC_INV_SQRT_SHIFT;
		}
		WRITE_ONCE(vars->lastcount, vars->count);
		WRITE_ONCE(vars->drop_next,
			   codel_control_law(now, params->interval,
					     vars->rec_inv_sqrt));
	}
end:
	if (skb && codel_time_after(vars->ldelay, params->ce_threshold)) {
		bool set_ce = true;

Annotation

Implementation Notes