hc
2024-10-22 8ac6c7a54ed1b98d142dce24b11c6de6a1e239a5
kernel/net/sched/sch_fifo.c
....@@ -1,10 +1,6 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * net/sched/sch_fifo.c The simplest FIFO queue.
3
- *
4
- * This program is free software; you can redistribute it and/or
5
- * modify it under the terms of the GNU General Public License
6
- * as published by the Free Software Foundation; either version
7
- * 2 of the License, or (at your option) any later version.
84 *
95 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
106 */
....@@ -16,6 +12,7 @@
1612 #include <linux/errno.h>
1713 #include <linux/skbuff.h>
1814 #include <net/pkt_sched.h>
15
+#include <net/pkt_cls.h>
1916
2017 /* 1 band FIFO pseudo-"scheduler" */
2118
....@@ -55,8 +52,49 @@
5552 return NET_XMIT_CN;
5653 }
5754
58
-static int fifo_init(struct Qdisc *sch, struct nlattr *opt,
59
- struct netlink_ext_ack *extack)
55
+static void fifo_offload_init(struct Qdisc *sch)
56
+{
57
+ struct net_device *dev = qdisc_dev(sch);
58
+ struct tc_fifo_qopt_offload qopt;
59
+
60
+ if (!tc_can_offload(dev) || !dev->netdev_ops->ndo_setup_tc)
61
+ return;
62
+
63
+ qopt.command = TC_FIFO_REPLACE;
64
+ qopt.handle = sch->handle;
65
+ qopt.parent = sch->parent;
66
+ dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_QDISC_FIFO, &qopt);
67
+}
68
+
69
+static void fifo_offload_destroy(struct Qdisc *sch)
70
+{
71
+ struct net_device *dev = qdisc_dev(sch);
72
+ struct tc_fifo_qopt_offload qopt;
73
+
74
+ if (!tc_can_offload(dev) || !dev->netdev_ops->ndo_setup_tc)
75
+ return;
76
+
77
+ qopt.command = TC_FIFO_DESTROY;
78
+ qopt.handle = sch->handle;
79
+ qopt.parent = sch->parent;
80
+ dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_QDISC_FIFO, &qopt);
81
+}
82
+
83
+static int fifo_offload_dump(struct Qdisc *sch)
84
+{
85
+ struct tc_fifo_qopt_offload qopt;
86
+
87
+ qopt.command = TC_FIFO_STATS;
88
+ qopt.handle = sch->handle;
89
+ qopt.parent = sch->parent;
90
+ qopt.stats.bstats = &sch->bstats;
91
+ qopt.stats.qstats = &sch->qstats;
92
+
93
+ return qdisc_offload_dump_helper(sch, TC_SETUP_QDISC_FIFO, &qopt);
94
+}
95
+
96
+static int __fifo_init(struct Qdisc *sch, struct nlattr *opt,
97
+ struct netlink_ext_ack *extack)
6098 {
6199 bool bypass;
62100 bool is_bfifo = sch->ops == &bfifo_qdisc_ops;
....@@ -86,10 +124,35 @@
86124 sch->flags |= TCQ_F_CAN_BYPASS;
87125 else
88126 sch->flags &= ~TCQ_F_CAN_BYPASS;
127
+
89128 return 0;
90129 }
91130
92
-static int fifo_dump(struct Qdisc *sch, struct sk_buff *skb)
131
+static int fifo_init(struct Qdisc *sch, struct nlattr *opt,
132
+ struct netlink_ext_ack *extack)
133
+{
134
+ int err;
135
+
136
+ err = __fifo_init(sch, opt, extack);
137
+ if (err)
138
+ return err;
139
+
140
+ fifo_offload_init(sch);
141
+ return 0;
142
+}
143
+
144
+static int fifo_hd_init(struct Qdisc *sch, struct nlattr *opt,
145
+ struct netlink_ext_ack *extack)
146
+{
147
+ return __fifo_init(sch, opt, extack);
148
+}
149
+
150
+static void fifo_destroy(struct Qdisc *sch)
151
+{
152
+ fifo_offload_destroy(sch);
153
+}
154
+
155
+static int __fifo_dump(struct Qdisc *sch, struct sk_buff *skb)
93156 {
94157 struct tc_fifo_qopt opt = { .limit = sch->limit };
95158
....@@ -101,6 +164,22 @@
101164 return -1;
102165 }
103166
167
+static int fifo_dump(struct Qdisc *sch, struct sk_buff *skb)
168
+{
169
+ int err;
170
+
171
+ err = fifo_offload_dump(sch);
172
+ if (err)
173
+ return err;
174
+
175
+ return __fifo_dump(sch, skb);
176
+}
177
+
178
+static int fifo_hd_dump(struct Qdisc *sch, struct sk_buff *skb)
179
+{
180
+ return __fifo_dump(sch, skb);
181
+}
182
+
104183 struct Qdisc_ops pfifo_qdisc_ops __read_mostly = {
105184 .id = "pfifo",
106185 .priv_size = 0,
....@@ -108,6 +187,7 @@
108187 .dequeue = qdisc_dequeue_head,
109188 .peek = qdisc_peek_head,
110189 .init = fifo_init,
190
+ .destroy = fifo_destroy,
111191 .reset = qdisc_reset_queue,
112192 .change = fifo_init,
113193 .dump = fifo_dump,
....@@ -122,6 +202,7 @@
122202 .dequeue = qdisc_dequeue_head,
123203 .peek = qdisc_peek_head,
124204 .init = fifo_init,
205
+ .destroy = fifo_destroy,
125206 .reset = qdisc_reset_queue,
126207 .change = fifo_init,
127208 .dump = fifo_dump,
....@@ -135,10 +216,10 @@
135216 .enqueue = pfifo_tail_enqueue,
136217 .dequeue = qdisc_dequeue_head,
137218 .peek = qdisc_peek_head,
138
- .init = fifo_init,
219
+ .init = fifo_hd_init,
139220 .reset = qdisc_reset_queue,
140
- .change = fifo_init,
141
- .dump = fifo_dump,
221
+ .change = fifo_hd_init,
222
+ .dump = fifo_hd_dump,
142223 .owner = THIS_MODULE,
143224 };
144225