184bf557fSMohit P. Tahiliani /* SPDX-License-Identifier: GPL-2.0-only */
284bf557fSMohit P. Tahiliani #ifndef __NET_SCHED_PIE_H
384bf557fSMohit P. Tahiliani #define __NET_SCHED_PIE_H
484bf557fSMohit P. Tahiliani
584bf557fSMohit P. Tahiliani #include <linux/ktime.h>
684bf557fSMohit P. Tahiliani #include <linux/skbuff.h>
784bf557fSMohit P. Tahiliani #include <linux/types.h>
884bf557fSMohit P. Tahiliani #include <net/inet_ecn.h>
984bf557fSMohit P. Tahiliani #include <net/pkt_sched.h>
1084bf557fSMohit P. Tahiliani
11105e808cSLeslie Monis #define MAX_PROB (U64_MAX >> BITS_PER_BYTE)
12cf4eeee5SMohit P. Tahiliani #define DTIME_INVALID U64_MAX
1384bf557fSMohit P. Tahiliani #define QUEUE_THRESHOLD 16384
1484bf557fSMohit P. Tahiliani #define DQCOUNT_INVALID -1
1584bf557fSMohit P. Tahiliani #define PIE_SCALE 8
1684bf557fSMohit P. Tahiliani
17b42a3d7cSMohit P. Tahiliani /**
18b42a3d7cSMohit P. Tahiliani * struct pie_params - contains pie parameters
19b42a3d7cSMohit P. Tahiliani * @target: target delay in pschedtime
20*d1cca974SRandy Dunlap * @tupdate: interval at which drop probability is calculated
21b42a3d7cSMohit P. Tahiliani * @limit: total number of packets that can be in the queue
22b42a3d7cSMohit P. Tahiliani * @alpha: parameter to control drop probability
23b42a3d7cSMohit P. Tahiliani * @beta: parameter to control drop probability
24b42a3d7cSMohit P. Tahiliani * @ecn: is ECN marking of packets enabled
25b42a3d7cSMohit P. Tahiliani * @bytemode: is drop probability scaled based on pkt size
26b42a3d7cSMohit P. Tahiliani * @dq_rate_estimator: is Little's law used for qdelay calculation
27b42a3d7cSMohit P. Tahiliani */
2884bf557fSMohit P. Tahiliani struct pie_params {
29b42a3d7cSMohit P. Tahiliani psched_time_t target;
30b42a3d7cSMohit P. Tahiliani u32 tupdate;
31b42a3d7cSMohit P. Tahiliani u32 limit;
32b42a3d7cSMohit P. Tahiliani u32 alpha;
33b42a3d7cSMohit P. Tahiliani u32 beta;
34b42a3d7cSMohit P. Tahiliani u8 ecn;
35b42a3d7cSMohit P. Tahiliani u8 bytemode;
36b42a3d7cSMohit P. Tahiliani u8 dq_rate_estimator;
3784bf557fSMohit P. Tahiliani };
3884bf557fSMohit P. Tahiliani
39b42a3d7cSMohit P. Tahiliani /**
40b42a3d7cSMohit P. Tahiliani * struct pie_vars - contains pie variables
41b42a3d7cSMohit P. Tahiliani * @qdelay: current queue delay
42b42a3d7cSMohit P. Tahiliani * @qdelay_old: queue delay in previous qdelay calculation
43b42a3d7cSMohit P. Tahiliani * @burst_time: burst time allowance
44b42a3d7cSMohit P. Tahiliani * @dq_tstamp: timestamp at which dq rate was last calculated
45b42a3d7cSMohit P. Tahiliani * @prob: drop probability
46b42a3d7cSMohit P. Tahiliani * @accu_prob: accumulated drop probability
47b42a3d7cSMohit P. Tahiliani * @dq_count: number of bytes dequeued in a measurement cycle
48b42a3d7cSMohit P. Tahiliani * @avg_dq_rate: calculated average dq rate
4990baeb9dSLeslie Monis * @backlog_old: queue backlog during previous qdelay calculation
50b42a3d7cSMohit P. Tahiliani */
5184bf557fSMohit P. Tahiliani struct pie_vars {
5284bf557fSMohit P. Tahiliani psched_time_t qdelay;
5384bf557fSMohit P. Tahiliani psched_time_t qdelay_old;
542dfb1952SMohit P. Tahiliani psched_time_t burst_time;
55b42a3d7cSMohit P. Tahiliani psched_time_t dq_tstamp;
56b42a3d7cSMohit P. Tahiliani u64 prob;
57b42a3d7cSMohit P. Tahiliani u64 accu_prob;
58b42a3d7cSMohit P. Tahiliani u64 dq_count;
59b42a3d7cSMohit P. Tahiliani u32 avg_dq_rate;
6090baeb9dSLeslie Monis u32 backlog_old;
6184bf557fSMohit P. Tahiliani };
6284bf557fSMohit P. Tahiliani
63b42a3d7cSMohit P. Tahiliani /**
64b42a3d7cSMohit P. Tahiliani * struct pie_stats - contains pie stats
65b42a3d7cSMohit P. Tahiliani * @packets_in: total number of packets enqueued
66b42a3d7cSMohit P. Tahiliani * @dropped: packets dropped due to pie action
67b42a3d7cSMohit P. Tahiliani * @overlimit: packets dropped due to lack of space in queue
68b42a3d7cSMohit P. Tahiliani * @ecn_mark: packets marked with ECN
69b42a3d7cSMohit P. Tahiliani * @maxq: maximum queue size
70b42a3d7cSMohit P. Tahiliani */
7184bf557fSMohit P. Tahiliani struct pie_stats {
72b42a3d7cSMohit P. Tahiliani u32 packets_in;
73b42a3d7cSMohit P. Tahiliani u32 dropped;
74b42a3d7cSMohit P. Tahiliani u32 overlimit;
75b42a3d7cSMohit P. Tahiliani u32 ecn_mark;
76b42a3d7cSMohit P. Tahiliani u32 maxq;
7784bf557fSMohit P. Tahiliani };
7884bf557fSMohit P. Tahiliani
79b42a3d7cSMohit P. Tahiliani /**
80b42a3d7cSMohit P. Tahiliani * struct pie_skb_cb - contains private skb vars
81b42a3d7cSMohit P. Tahiliani * @enqueue_time: timestamp when the packet is enqueued
82ec97ecf1SMohit P. Tahiliani * @mem_usage: size of the skb during enqueue
83b42a3d7cSMohit P. Tahiliani */
8484bf557fSMohit P. Tahiliani struct pie_skb_cb {
8584bf557fSMohit P. Tahiliani psched_time_t enqueue_time;
86ec97ecf1SMohit P. Tahiliani u32 mem_usage;
8784bf557fSMohit P. Tahiliani };
8884bf557fSMohit P. Tahiliani
pie_params_init(struct pie_params * params)8984bf557fSMohit P. Tahiliani static inline void pie_params_init(struct pie_params *params)
9084bf557fSMohit P. Tahiliani {
912dfb1952SMohit P. Tahiliani params->target = PSCHED_NS2TICKS(15 * NSEC_PER_MSEC); /* 15 ms */
9284bf557fSMohit P. Tahiliani params->tupdate = usecs_to_jiffies(15 * USEC_PER_MSEC); /* 15 ms */
93b42a3d7cSMohit P. Tahiliani params->limit = 1000;
942dfb1952SMohit P. Tahiliani params->alpha = 2;
952dfb1952SMohit P. Tahiliani params->beta = 20;
9684bf557fSMohit P. Tahiliani params->ecn = false;
9784bf557fSMohit P. Tahiliani params->bytemode = false;
9884bf557fSMohit P. Tahiliani params->dq_rate_estimator = false;
9984bf557fSMohit P. Tahiliani }
10084bf557fSMohit P. Tahiliani
pie_vars_init(struct pie_vars * vars)10184bf557fSMohit P. Tahiliani static inline void pie_vars_init(struct pie_vars *vars)
10284bf557fSMohit P. Tahiliani {
103b42a3d7cSMohit P. Tahiliani vars->burst_time = PSCHED_NS2TICKS(150 * NSEC_PER_MSEC); /* 150 ms */
1042dfb1952SMohit P. Tahiliani vars->dq_tstamp = DTIME_INVALID;
1052dfb1952SMohit P. Tahiliani vars->accu_prob = 0;
1062dfb1952SMohit P. Tahiliani vars->dq_count = DQCOUNT_INVALID;
1072dfb1952SMohit P. Tahiliani vars->avg_dq_rate = 0;
10884bf557fSMohit P. Tahiliani }
10984bf557fSMohit P. Tahiliani
get_pie_cb(const struct sk_buff * skb)11084bf557fSMohit P. Tahiliani static inline struct pie_skb_cb *get_pie_cb(const struct sk_buff *skb)
11184bf557fSMohit P. Tahiliani {
11284bf557fSMohit P. Tahiliani qdisc_cb_private_validate(skb, sizeof(struct pie_skb_cb));
11384bf557fSMohit P. Tahiliani return (struct pie_skb_cb *)qdisc_skb_cb(skb)->data;
11484bf557fSMohit P. Tahiliani }
11584bf557fSMohit P. Tahiliani
pie_get_enqueue_time(const struct sk_buff * skb)11684bf557fSMohit P. Tahiliani static inline psched_time_t pie_get_enqueue_time(const struct sk_buff *skb)
11784bf557fSMohit P. Tahiliani {
11884bf557fSMohit P. Tahiliani return get_pie_cb(skb)->enqueue_time;
11984bf557fSMohit P. Tahiliani }
12084bf557fSMohit P. Tahiliani
pie_set_enqueue_time(struct sk_buff * skb)12184bf557fSMohit P. Tahiliani static inline void pie_set_enqueue_time(struct sk_buff *skb)
12284bf557fSMohit P. Tahiliani {
12384bf557fSMohit P. Tahiliani get_pie_cb(skb)->enqueue_time = psched_get_time();
12484bf557fSMohit P. Tahiliani }
12584bf557fSMohit P. Tahiliani
1265205ea00SMohit P. Tahiliani bool pie_drop_early(struct Qdisc *sch, struct pie_params *params,
12790baeb9dSLeslie Monis struct pie_vars *vars, u32 backlog, u32 packet_size);
1285205ea00SMohit P. Tahiliani
1295205ea00SMohit P. Tahiliani void pie_process_dequeue(struct sk_buff *skb, struct pie_params *params,
13090baeb9dSLeslie Monis struct pie_vars *vars, u32 backlog);
1315205ea00SMohit P. Tahiliani
1325205ea00SMohit P. Tahiliani void pie_calculate_probability(struct pie_params *params, struct pie_vars *vars,
13390baeb9dSLeslie Monis u32 backlog);
1345205ea00SMohit P. Tahiliani
13584bf557fSMohit P. Tahiliani #endif
136