]> git.proxmox.com Git - mirror_ubuntu-disco-kernel.git/blame - include/net/pkt_sched.h
License cleanup: add SPDX GPL-2.0 license identifier to files with no license
[mirror_ubuntu-disco-kernel.git] / include / net / pkt_sched.h
CommitLineData
b2441318 1/* SPDX-License-Identifier: GPL-2.0 */
1da177e4
LT
2#ifndef __NET_PKT_SCHED_H
3#define __NET_PKT_SCHED_H
4
538e43a4 5#include <linux/jiffies.h>
641b9e0e 6#include <linux/ktime.h>
d8b9605d 7#include <linux/if_vlan.h>
1da177e4 8#include <net/sch_generic.h>
861932ec 9#include <uapi/linux/pkt_sched.h>
1da177e4 10
d0a81f67
JDB
11#define DEFAULT_TX_QUEUE_LEN 1000
12
fd2c3ef7 13struct qdisc_walker {
1da177e4
LT
14 int stop;
15 int skip;
16 int count;
17 int (*fn)(struct Qdisc *, unsigned long cl, struct qdisc_walker *);
18};
19
5d944c64 20#define QDISC_ALIGNTO 64
3d54b82f 21#define QDISC_ALIGN(len) (((len) + QDISC_ALIGNTO-1) & ~(QDISC_ALIGNTO-1))
1da177e4
LT
22
23static inline void *qdisc_priv(struct Qdisc *q)
24{
3d54b82f 25 return (char *) q + QDISC_ALIGN(sizeof(struct Qdisc));
1da177e4
LT
26}
27
28/*
29 Timer resolution MUST BE < 10% of min_schedulable_packet_size/bandwidth
30
31 Normal IP packet size ~ 512byte, hence:
32
33 0.5Kbyte/1Mbyte/sec = 0.5msec, so that we need 50usec timer for
34 10Mbit ethernet.
35
36 10msec resolution -> <50Kbit/sec.
37
38 The result: [34]86 is not good choice for QoS router :-(
39
25985edc 40 The things are not so bad, because we may use artificial
1da177e4
LT
41 clock evaluated by integration of network data flow
42 in the most critical places.
1da177e4
LT
43 */
44
1da177e4
LT
45typedef u64 psched_time_t;
46typedef long psched_tdiff_t;
47
a4a710c4
JP
48/* Avoid doing 64 bit divide */
49#define PSCHED_SHIFT 6
ca44d6e6
JP
50#define PSCHED_TICKS2NS(x) ((s64)(x) << PSCHED_SHIFT)
51#define PSCHED_NS2TICKS(x) ((x) >> PSCHED_SHIFT)
1da177e4 52
ca44d6e6 53#define PSCHED_TICKS_PER_SEC PSCHED_NS2TICKS(NSEC_PER_SEC)
a084980d 54#define PSCHED_PASTPERFECT 0
1da177e4 55
3bebcda2
PM
56static inline psched_time_t psched_get_time(void)
57{
d2de875c 58 return PSCHED_NS2TICKS(ktime_get_ns());
3bebcda2
PM
59}
60
03cc45c0
PM
61static inline psched_tdiff_t
62psched_tdiff_bounded(psched_time_t tv1, psched_time_t tv2, psched_time_t bound)
63{
64 return min(tv1 - tv2, bound);
65}
66
4179477f 67struct qdisc_watchdog {
a9efad8b 68 u64 last_expires;
4179477f
PM
69 struct hrtimer timer;
70 struct Qdisc *qdisc;
71};
72
5c15257f 73void qdisc_watchdog_init(struct qdisc_watchdog *wd, struct Qdisc *qdisc);
45f50bed 74void qdisc_watchdog_schedule_ns(struct qdisc_watchdog *wd, u64 expires);
34c5d292
JP
75
76static inline void qdisc_watchdog_schedule(struct qdisc_watchdog *wd,
77 psched_time_t expires)
78{
45f50bed 79 qdisc_watchdog_schedule_ns(wd, PSCHED_TICKS2NS(expires));
34c5d292
JP
80}
81
5c15257f 82void qdisc_watchdog_cancel(struct qdisc_watchdog *wd);
4179477f 83
1da177e4
LT
84extern struct Qdisc_ops pfifo_qdisc_ops;
85extern struct Qdisc_ops bfifo_qdisc_ops;
57dbb2d8 86extern struct Qdisc_ops pfifo_head_drop_qdisc_ops;
1da177e4 87
5c15257f
JP
88int fifo_set_limit(struct Qdisc *q, unsigned int limit);
89struct Qdisc *fifo_create_dflt(struct Qdisc *sch, struct Qdisc_ops *ops,
90 unsigned int limit);
91
92int register_qdisc(struct Qdisc_ops *qops);
93int unregister_qdisc(struct Qdisc_ops *qops);
6da7c8fc 94void qdisc_get_default(char *id, size_t len);
95int qdisc_set_default(const char *id);
96
49b49971 97void qdisc_hash_add(struct Qdisc *q, bool invisible);
59cc1f61 98void qdisc_hash_del(struct Qdisc *q);
5c15257f
JP
99struct Qdisc *qdisc_lookup(struct net_device *dev, u32 handle);
100struct Qdisc *qdisc_lookup_class(struct net_device *dev, u32 handle);
101struct qdisc_rate_table *qdisc_get_rtab(struct tc_ratespec *r,
102 struct nlattr *tab);
103void qdisc_put_rtab(struct qdisc_rate_table *tab);
104void qdisc_put_stab(struct qdisc_size_table *tab);
6e765a00 105void qdisc_warn_nonwc(const char *txt, struct Qdisc *qdisc);
5c15257f
JP
106int sch_direct_xmit(struct sk_buff *skb, struct Qdisc *q,
107 struct net_device *dev, struct netdev_queue *txq,
55a93b3e 108 spinlock_t *root_lock, bool validate);
5c15257f
JP
109
110void __qdisc_run(struct Qdisc *q);
1da177e4 111
37437bb2 112static inline void qdisc_run(struct Qdisc *q)
1da177e4 113{
bc135b23 114 if (qdisc_run_begin(q))
37437bb2 115 __qdisc_run(q);
1da177e4
LT
116}
117
d8b9605d
JP
118static inline __be16 tc_skb_protocol(const struct sk_buff *skb)
119{
120 /* We need to take extra care in case the skb came via
121 * vlan accelerated path. In that case, use skb->vlan_proto
122 * as the original vlan header was already stripped.
123 */
df8a39de 124 if (skb_vlan_tag_present(skb))
d8b9605d
JP
125 return skb->vlan_proto;
126 return skb->protocol;
127}
128
1da177e4
LT
129/* Calculate maximal size of packet seen by hard_start_xmit
130 routine of this device.
131 */
95c96174 132static inline unsigned int psched_mtu(const struct net_device *dev)
1da177e4 133{
3b04ddde 134 return dev->mtu + dev->hard_header_len;
1da177e4
LT
135}
136
861932ec
JP
137static inline bool is_classid_clsact_ingress(u32 classid)
138{
139 /* This also returns true for ingress qdisc */
140 return TC_H_MAJ(classid) == TC_H_MAJ(TC_H_CLSACT) &&
141 TC_H_MIN(classid) != TC_H_MIN(TC_H_MIN_EGRESS);
142}
143
144static inline bool is_classid_clsact_egress(u32 classid)
145{
146 return TC_H_MAJ(classid) == TC_H_MAJ(TC_H_CLSACT) &&
147 TC_H_MIN(classid) == TC_H_MIN(TC_H_MIN_EGRESS);
148}
149
1da177e4 150#endif