-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathlinux-uek5-net.patch
332 lines (313 loc) · 11.5 KB
/
linux-uek5-net.patch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
From 25142c2c2e3502fa62fbddaa750e8aca8df43aeb Mon Sep 17 00:00:00 2001
From: Dongli Zhang <dongli.zhang0129@gmail.com>
Date: Thu, 19 Mar 2020 12:16:00 -0700
Subject: [PATCH 1/1] linux uek5 net
v4.14.35-1902.300.10
Signed-off-by: Dongli Zhang <dongli.zhang0129@gmail.com>
---
drivers/net/tun.c | 36 ++++++++++++++
include/linux/netdevice.h | 10 ++++
include/linux/ptr_ring.h | 99 +++++++++++++++++++++++++++++++++++++++
3 files changed, 145 insertions(+)
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index e0baea2dfd3c..5bf54763221d 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -2785,6 +2785,11 @@ static int tun_queue_resize(struct tun_struct *tun)
{
struct net_device *dev = tun->dev;
struct tun_file *tfile;
+ /*
+ * struct skb_array {
+ * struct ptr_ring ring;
+ * };
+ */
struct skb_array **arrays;
int n = tun->numqueues + tun->numdisabled;
int ret, i;
@@ -2807,6 +2812,27 @@ static int tun_queue_resize(struct tun_struct *tun)
return ret;
}
+/*
+ * [0] save_stack
+ * [0] kasan_kmalloc
+ * [0] __kmalloc_node
+ * [0] kvmalloc_node
+ * [0] tun_device_event
+ * [0] notifier_call_chain
+ * [0] raw_notifier_call_chain
+ * [0] call_netdevice_notifiers_info
+ * [0] call_netdevice_notifiers
+ * [0] dev_ifsioc
+ * [0] dev_ioctl
+ * [0] sock_do_ioctl
+ * [0] sock_ioctl
+ * [0] do_vfs_ioctl
+ * [0] SyS_ioctl
+ * [0] do_syscall_64
+ * [0] entry_SYSCALL_64_after_hwframe
+ *
+ * struct notifier_block tun_notifier_block.notifier_call = tun_device_event()
+ */
static int tun_device_event(struct notifier_block *unused,
unsigned long event, void *ptr)
{
@@ -2817,6 +2843,16 @@ static int tun_device_event(struct notifier_block *unused,
return NOTIFY_DONE;
switch (event) {
+ /*
+ * 使用NETDEV_CHANGE_TX_QUEUE_LEN的地方:
+ * - drivers/net/ipvlan/ipvtap.c|183| <<ipvtap_device_event>> case NETDEV_CHANGE_TX_QUEUE_LEN:
+ * - drivers/net/macvtap.c|190| <<macvtap_device_event>> case NETDEV_CHANGE_TX_QUEUE_LEN:
+ * - drivers/net/tun.c|2820| <<tun_device_event>> case NETDEV_CHANGE_TX_QUEUE_LEN:
+ * - net/core/dev_ioctl.c|312| <<dev_ifsioc>> NETDEV_CHANGE_TX_QUEUE_LEN, dev);
+ * - net/core/net-sysfs.c|338| <<change_tx_queue_len>> res = call_netdevice_notifiers(NETDEV_CHANGE_TX_QUEUE_LEN, dev);
+ * - net/core/rtnetlink.c|2097| <<do_setlink>> NETDEV_CHANGE_TX_QUEUE_LEN, dev);
+ * - net/core/rtnetlink.c|4298| <<rtnetlink_event>> case NETDEV_CHANGE_TX_QUEUE_LEN:
+ */
case NETDEV_CHANGE_TX_QUEUE_LEN:
if (tun_queue_resize(tun))
return NOTIFY_BAD;
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index f56ade9fda30..050c0c0ae21f 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -2340,6 +2340,16 @@ struct netdev_lag_lower_state_info {
#define NETDEV_CHANGELOWERSTATE 0x001B
#define NETDEV_UDP_TUNNEL_PUSH_INFO 0x001C
#define NETDEV_UDP_TUNNEL_DROP_INFO 0x001D
+/*
+ * 使用NETDEV_CHANGE_TX_QUEUE_LEN的地方:
+ * - drivers/net/ipvlan/ipvtap.c|183| <<ipvtap_device_event>> case NETDEV_CHANGE_TX_QUEUE_LEN:
+ * - drivers/net/macvtap.c|190| <<macvtap_device_event>> case NETDEV_CHANGE_TX_QUEUE_LEN:
+ * - drivers/net/tun.c|2820| <<tun_device_event>> case NETDEV_CHANGE_TX_QUEUE_LEN:
+ * - net/core/dev_ioctl.c|312| <<dev_ifsioc>> NETDEV_CHANGE_TX_QUEUE_LEN, dev);
+ * - net/core/net-sysfs.c|338| <<change_tx_queue_len>> res = call_netdevice_notifiers(NETDEV_CHANGE_TX_QUEUE_LEN, dev);
+ * - net/core/rtnetlink.c|2097| <<do_setlink>> NETDEV_CHANGE_TX_QUEUE_LEN, dev);
+ * - net/core/rtnetlink.c|4298| <<rtnetlink_event>> case NETDEV_CHANGE_TX_QUEUE_LEN:
+ */
#define NETDEV_CHANGE_TX_QUEUE_LEN 0x001E
int register_netdevice_notifier(struct notifier_block *nb);
diff --git a/include/linux/ptr_ring.h b/include/linux/ptr_ring.h
index e8b12b79a0de..c0cf9ff62c25 100644
--- a/include/linux/ptr_ring.h
+++ b/include/linux/ptr_ring.h
@@ -49,11 +49,29 @@ struct ptr_ring {
* producer_lock - see e.g. ptr_ring_full. Otherwise, if callers don't hold
* producer_lock, the next call to __ptr_ring_produce may fail.
*/
+/*
+ * called by:
+ * - include/linux/ptr_ring.h|62| <<ptr_ring_full>> ret = __ptr_ring_full(r);
+ * - include/linux/ptr_ring.h|73| <<ptr_ring_full_irq>> ret = __ptr_ring_full(r);
+ * - include/linux/ptr_ring.h|85| <<ptr_ring_full_any>> ret = __ptr_ring_full(r);
+ * - include/linux/ptr_ring.h|96| <<ptr_ring_full_bh>> ret = __ptr_ring_full(r);
+ * - include/linux/skb_array.h|38| <<__skb_array_full>> return __ptr_ring_full(&a->ring);
+ *
+ * 确认下r->queue[r->producer]是否分配了 (queue是void **queue)
+ */
static inline bool __ptr_ring_full(struct ptr_ring *r)
{
+ /*
+ * struct ptr_ring:
+ * - void **queue;
+ */
return r->queue[r->producer];
}
+/*
+ * called by:
+ * - include/linux/skb_array.h|43| <<skb_array_full>> return ptr_ring_full(&a->ring);
+ */
static inline bool ptr_ring_full(struct ptr_ring *r)
{
bool ret;
@@ -104,6 +122,10 @@ static inline bool ptr_ring_full_bh(struct ptr_ring *r)
* Callers are responsible for making sure pointer that is being queued
* points to a valid data.
*/
+/*
+ * 核心思想是r->queue[r->producer++] = ptr;
+ * 如果到头了则设置r->producer = 0
+ */
static inline int __ptr_ring_produce(struct ptr_ring *r, void *ptr)
{
if (unlikely(!r->size) || r->queue[r->producer])
@@ -124,6 +146,10 @@ static inline int __ptr_ring_produce(struct ptr_ring *r, void *ptr)
* consume in interrupt or BH context, you must disable interrupts/BH when
* calling this.
*/
+/*
+ * 核心思想是r->queue[r->producer++] = ptr;
+ * 如果到头了则设置r->producer = 0
+ */
static inline int ptr_ring_produce(struct ptr_ring *r, void *ptr)
{
int ret;
@@ -135,6 +161,10 @@ static inline int ptr_ring_produce(struct ptr_ring *r, void *ptr)
return ret;
}
+/*
+ * 核心思想是r->queue[r->producer++] = ptr;
+ * 如果到头了则设置r->producer = 0
+ */
static inline int ptr_ring_produce_irq(struct ptr_ring *r, void *ptr)
{
int ret;
@@ -146,6 +176,10 @@ static inline int ptr_ring_produce_irq(struct ptr_ring *r, void *ptr)
return ret;
}
+/*
+ * 核心思想是r->queue[r->producer++] = ptr;
+ * 如果到头了则设置r->producer = 0
+ */
static inline int ptr_ring_produce_any(struct ptr_ring *r, void *ptr)
{
unsigned long flags;
@@ -158,6 +192,10 @@ static inline int ptr_ring_produce_any(struct ptr_ring *r, void *ptr)
return ret;
}
+/*
+ * 核心思想是r->queue[r->producer++] = ptr;
+ * 如果到头了则设置r->producer = 0
+ */
static inline int ptr_ring_produce_bh(struct ptr_ring *r, void *ptr)
{
int ret;
@@ -175,6 +213,9 @@ static inline int ptr_ring_produce_bh(struct ptr_ring *r, void *ptr)
* If ring is never resized, and if the pointer is merely
* tested, there's no need to take the lock - see e.g. __ptr_ring_empty.
*/
+/*
+ * 核心思想返回r->queue[r->consumer_head]
+ */
static inline void *__ptr_ring_peek(struct ptr_ring *r)
{
if (likely(r->size))
@@ -188,6 +229,9 @@ static inline void *__ptr_ring_peek(struct ptr_ring *r)
*/
static inline bool __ptr_ring_empty(struct ptr_ring *r)
{
+ /*
+ * 核心思想返回r->queue[r->consumer_head]
+ */
return !__ptr_ring_peek(r);
}
@@ -237,6 +281,10 @@ static inline bool ptr_ring_empty_bh(struct ptr_ring *r)
}
/* Must only be called after __ptr_ring_peek returned !NULL */
+/*
+ * called by:
+ * - include/linux/ptr_ring.h|326| <<__ptr_ring_consume>> __ptr_ring_discard_one(r);
+ */
static inline void __ptr_ring_discard_one(struct ptr_ring *r)
{
/* Fundamentally, what we want to do is update consumer
@@ -277,6 +325,9 @@ static inline void *__ptr_ring_consume(struct ptr_ring *r)
{
void *ptr;
+ /*
+ * 核心思想返回r->queue[r->consumer_head]
+ */
ptr = __ptr_ring_peek(r);
if (ptr)
__ptr_ring_discard_one(r);
@@ -448,6 +499,14 @@ static inline int ptr_ring_consume_batched_bh(struct ptr_ring *r,
/* Not all gfp_t flags (besides GFP_KERNEL) are allowed. See
* documentation for vmalloc for which of them are legal.
*/
+/*
+ * called by:
+ * - include/linux/ptr_ring.h|489| <<ptr_ring_init>> r->queue = __ptr_ring_init_queue_alloc(size, gfp);
+ * - include/linux/ptr_ring.h|595| <<ptr_ring_resize>> void **queue = __ptr_ring_init_queue_alloc(size, gfp);
+ * - include/linux/ptr_ring.h|634| <<ptr_ring_resize_multiple>> queues[i] = __ptr_ring_init_queue_alloc(size, gfp);
+ *
+ * 用slab分配size个(void *)
+ */
static inline void **__ptr_ring_init_queue_alloc(unsigned int size, gfp_t gfp)
{
if (size > KMALLOC_MAX_SIZE / sizeof(void *))
@@ -455,6 +514,13 @@ static inline void **__ptr_ring_init_queue_alloc(unsigned int size, gfp_t gfp)
return kvmalloc_array(size, sizeof(void *), gfp | __GFP_ZERO);
}
+/*
+ * called by:
+ * - include/linux/ptr_ring.h|493| <<ptr_ring_init>> __ptr_ring_set_size(r, size);
+ * - include/linux/ptr_ring.h|575| <<__ptr_ring_swap_queue>> __ptr_ring_set_size(r, size);
+ *
+ * 设置ptr_ring->size和ptr_ring->batch的值
+ */
static inline void __ptr_ring_set_size(struct ptr_ring *r, int size)
{
r->size = size;
@@ -468,12 +534,26 @@ static inline void __ptr_ring_set_size(struct ptr_ring *r, int size)
r->batch = 1;
}
+/*
+ * called by:
+ * - include/linux/skb_array.h|176| <<skb_array_init>> return ptr_ring_init(&a->ring, size, gfp);
+ *
+ * 用slab分配size个(void *)
+ * 设置ptr_ring->size和ptr_ring->batch的值
+ * 初始化r->producer = r->consumer_head = r->consumer_tail = 0;
+ */
static inline int ptr_ring_init(struct ptr_ring *r, int size, gfp_t gfp)
{
+ /*
+ * 用slab分配size个(void *)
+ */
r->queue = __ptr_ring_init_queue_alloc(size, gfp);
if (!r->queue)
return -ENOMEM;
+ /*
+ * 设置ptr_ring->size和ptr_ring->batch的值
+ */
__ptr_ring_set_size(r, size);
r->producer = r->consumer_head = r->consumer_tail = 0;
spin_lock_init(&r->producer_lock);
@@ -492,6 +572,10 @@ static inline int ptr_ring_init(struct ptr_ring *r, int size, gfp_t gfp)
* In particular if you consume ring in interrupt or BH context, you must
* disable interrupts/BH when doing so.
*/
+/*
+ * called by:
+ * - include/linux/skb_array.h|187| <<skb_array_unconsume>> ptr_ring_unconsume(&a->ring, (void **)skbs, n, __skb_array_destroy_skb);
+ */
static inline void ptr_ring_unconsume(struct ptr_ring *r, void **batch, int n,
void (*destroy)(void *))
{
@@ -537,6 +621,11 @@ static inline void ptr_ring_unconsume(struct ptr_ring *r, void **batch, int n,
spin_unlock_irqrestore(&r->consumer_lock, flags);
}
+/*
+ * called by:
+ * - include/linux/ptr_ring.h|583| <<ptr_ring_resize>> old = __ptr_ring_swap_queue(r, queue, size, gfp, destroy);
+ * - include/linux/ptr_ring.h|621| <<ptr_ring_resize_multiple>> queues[i] = __ptr_ring_swap_queue(rings[i], queues[i],
+ */
static inline void **__ptr_ring_swap_queue(struct ptr_ring *r, void **queue,
int size, gfp_t gfp,
void (*destroy)(void *))
@@ -551,6 +640,12 @@ static inline void **__ptr_ring_swap_queue(struct ptr_ring *r, void **queue,
else if (destroy)
destroy(ptr);
+ /*
+ * 这里少不少下面的代码呢
+ * if (producer >= size)
+ * producer = 0;
+ */
+ /* 设置ptr_ring->size和ptr_ring->batch的值 */
__ptr_ring_set_size(r, size);
r->producer = producer;
r->consumer_head = 0;
@@ -567,6 +662,10 @@ static inline void **__ptr_ring_swap_queue(struct ptr_ring *r, void **queue,
* In particular if you consume ring in interrupt or BH context, you must
* disable interrupts/BH when doing so.
*/
+/*
+ * called by:
+ * - include/linux/skb_array.h|192| <<skb_array_resize>> return ptr_ring_resize(&a->ring, size, gfp, __skb_array_destroy_skb);
+ */
static inline int ptr_ring_resize(struct ptr_ring *r, int size, gfp_t gfp,
void (*destroy)(void *))
{
--
2.17.1