Annotation of /trunk/kernel-alx/patches-5.4/0276-5.4.177-all-fixes.patch
Parent Directory | Revision Log
Revision 3635 -
(hide annotations)
(download)
Mon Oct 24 12:34:12 2022 UTC (19 months, 3 weeks ago) by niro
File size: 15062 byte(s)
Mon Oct 24 12:34:12 2022 UTC (19 months, 3 weeks ago) by niro
File size: 15062 byte(s)
-sync kernel patches
1 | niro | 3635 | diff --git a/Documentation/accounting/psi.rst b/Documentation/accounting/psi.rst |
2 | index 621111ce57401..28c0461ba2e1b 100644 | ||
3 | --- a/Documentation/accounting/psi.rst | ||
4 | +++ b/Documentation/accounting/psi.rst | ||
5 | @@ -90,7 +90,8 @@ Triggers can be set on more than one psi metric and more than one trigger | ||
6 | for the same psi metric can be specified. However for each trigger a separate | ||
7 | file descriptor is required to be able to poll it separately from others, | ||
8 | therefore for each trigger a separate open() syscall should be made even | ||
9 | -when opening the same psi interface file. | ||
10 | +when opening the same psi interface file. Write operations to a file descriptor | ||
11 | +with an already existing psi trigger will fail with EBUSY. | ||
12 | |||
13 | Monitors activate only when system enters stall state for the monitored | ||
14 | psi metric and deactivates upon exit from the stall state. While system is | ||
15 | diff --git a/Makefile b/Makefile | ||
16 | index b23aa51ada93e..324939b64d7b7 100644 | ||
17 | --- a/Makefile | ||
18 | +++ b/Makefile | ||
19 | @@ -1,7 +1,7 @@ | ||
20 | # SPDX-License-Identifier: GPL-2.0 | ||
21 | VERSION = 5 | ||
22 | PATCHLEVEL = 4 | ||
23 | -SUBLEVEL = 176 | ||
24 | +SUBLEVEL = 177 | ||
25 | EXTRAVERSION = | ||
26 | NAME = Kleptomaniac Octopus | ||
27 | |||
28 | diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c | ||
29 | index da8c2c4aca7ef..0442d7e1cd20b 100644 | ||
30 | --- a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c | ||
31 | +++ b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c | ||
32 | @@ -721,7 +721,9 @@ static void xgbe_stop_timers(struct xgbe_prv_data *pdata) | ||
33 | if (!channel->tx_ring) | ||
34 | break; | ||
35 | |||
36 | + /* Deactivate the Tx timer */ | ||
37 | del_timer_sync(&channel->tx_timer); | ||
38 | + channel->tx_timer_active = 0; | ||
39 | } | ||
40 | } | ||
41 | |||
42 | @@ -2765,6 +2767,14 @@ read_again: | ||
43 | buf2_len = xgbe_rx_buf2_len(rdata, packet, len); | ||
44 | len += buf2_len; | ||
45 | |||
46 | + if (buf2_len > rdata->rx.buf.dma_len) { | ||
47 | + /* Hardware inconsistency within the descriptors | ||
48 | + * that has resulted in a length underflow. | ||
49 | + */ | ||
50 | + error = 1; | ||
51 | + goto skip_data; | ||
52 | + } | ||
53 | + | ||
54 | if (!skb) { | ||
55 | skb = xgbe_create_skb(pdata, napi, rdata, | ||
56 | buf1_len); | ||
57 | @@ -2794,8 +2804,10 @@ skip_data: | ||
58 | if (!last || context_next) | ||
59 | goto read_again; | ||
60 | |||
61 | - if (!skb) | ||
62 | + if (!skb || error) { | ||
63 | + dev_kfree_skb(skb); | ||
64 | goto next_packet; | ||
65 | + } | ||
66 | |||
67 | /* Be sure we don't exceed the configured MTU */ | ||
68 | max_len = netdev->mtu + ETH_HLEN; | ||
69 | diff --git a/drivers/net/usb/ipheth.c b/drivers/net/usb/ipheth.c | ||
70 | index 345576f1a7470..73ad78f47763c 100644 | ||
71 | --- a/drivers/net/usb/ipheth.c | ||
72 | +++ b/drivers/net/usb/ipheth.c | ||
73 | @@ -121,7 +121,7 @@ static int ipheth_alloc_urbs(struct ipheth_device *iphone) | ||
74 | if (tx_buf == NULL) | ||
75 | goto free_rx_urb; | ||
76 | |||
77 | - rx_buf = usb_alloc_coherent(iphone->udev, IPHETH_BUF_SIZE, | ||
78 | + rx_buf = usb_alloc_coherent(iphone->udev, IPHETH_BUF_SIZE + IPHETH_IP_ALIGN, | ||
79 | GFP_KERNEL, &rx_urb->transfer_dma); | ||
80 | if (rx_buf == NULL) | ||
81 | goto free_tx_buf; | ||
82 | @@ -146,7 +146,7 @@ error_nomem: | ||
83 | |||
84 | static void ipheth_free_urbs(struct ipheth_device *iphone) | ||
85 | { | ||
86 | - usb_free_coherent(iphone->udev, IPHETH_BUF_SIZE, iphone->rx_buf, | ||
87 | + usb_free_coherent(iphone->udev, IPHETH_BUF_SIZE + IPHETH_IP_ALIGN, iphone->rx_buf, | ||
88 | iphone->rx_urb->transfer_dma); | ||
89 | usb_free_coherent(iphone->udev, IPHETH_BUF_SIZE, iphone->tx_buf, | ||
90 | iphone->tx_urb->transfer_dma); | ||
91 | @@ -317,7 +317,7 @@ static int ipheth_rx_submit(struct ipheth_device *dev, gfp_t mem_flags) | ||
92 | |||
93 | usb_fill_bulk_urb(dev->rx_urb, udev, | ||
94 | usb_rcvbulkpipe(udev, dev->bulk_in), | ||
95 | - dev->rx_buf, IPHETH_BUF_SIZE, | ||
96 | + dev->rx_buf, IPHETH_BUF_SIZE + IPHETH_IP_ALIGN, | ||
97 | ipheth_rcvbulk_callback, | ||
98 | dev); | ||
99 | dev->rx_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | ||
100 | diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c | ||
101 | index 88b996764ff95..907b8be86ce04 100644 | ||
102 | --- a/drivers/pci/hotplug/pciehp_hpc.c | ||
103 | +++ b/drivers/pci/hotplug/pciehp_hpc.c | ||
104 | @@ -577,6 +577,8 @@ read_status: | ||
105 | */ | ||
106 | if (ctrl->power_fault_detected) | ||
107 | status &= ~PCI_EXP_SLTSTA_PFD; | ||
108 | + else if (status & PCI_EXP_SLTSTA_PFD) | ||
109 | + ctrl->power_fault_detected = true; | ||
110 | |||
111 | events |= status; | ||
112 | if (!events) { | ||
113 | @@ -586,7 +588,7 @@ read_status: | ||
114 | } | ||
115 | |||
116 | if (status) { | ||
117 | - pcie_capability_write_word(pdev, PCI_EXP_SLTSTA, events); | ||
118 | + pcie_capability_write_word(pdev, PCI_EXP_SLTSTA, status); | ||
119 | |||
120 | /* | ||
121 | * In MSI mode, all event bits must be zero before the port | ||
122 | @@ -660,8 +662,7 @@ static irqreturn_t pciehp_ist(int irq, void *dev_id) | ||
123 | } | ||
124 | |||
125 | /* Check Power Fault Detected */ | ||
126 | - if ((events & PCI_EXP_SLTSTA_PFD) && !ctrl->power_fault_detected) { | ||
127 | - ctrl->power_fault_detected = 1; | ||
128 | + if (events & PCI_EXP_SLTSTA_PFD) { | ||
129 | ctrl_err(ctrl, "Slot(%s): Power fault\n", slot_name(ctrl)); | ||
130 | pciehp_set_indicators(ctrl, PCI_EXP_SLTCTL_PWR_IND_OFF, | ||
131 | PCI_EXP_SLTCTL_ATTN_IND_ON); | ||
132 | diff --git a/include/linux/psi.h b/include/linux/psi.h | ||
133 | index 7b3de73212199..7712b58009276 100644 | ||
134 | --- a/include/linux/psi.h | ||
135 | +++ b/include/linux/psi.h | ||
136 | @@ -31,7 +31,7 @@ void cgroup_move_task(struct task_struct *p, struct css_set *to); | ||
137 | |||
138 | struct psi_trigger *psi_trigger_create(struct psi_group *group, | ||
139 | char *buf, size_t nbytes, enum psi_res res); | ||
140 | -void psi_trigger_replace(void **trigger_ptr, struct psi_trigger *t); | ||
141 | +void psi_trigger_destroy(struct psi_trigger *t); | ||
142 | |||
143 | __poll_t psi_trigger_poll(void **trigger_ptr, struct file *file, | ||
144 | poll_table *wait); | ||
145 | diff --git a/include/linux/psi_types.h b/include/linux/psi_types.h | ||
146 | index 07aaf9b822416..0023052eab23f 100644 | ||
147 | --- a/include/linux/psi_types.h | ||
148 | +++ b/include/linux/psi_types.h | ||
149 | @@ -120,9 +120,6 @@ struct psi_trigger { | ||
150 | * events to one per window | ||
151 | */ | ||
152 | u64 last_event_time; | ||
153 | - | ||
154 | - /* Refcounting to prevent premature destruction */ | ||
155 | - struct kref refcount; | ||
156 | }; | ||
157 | |||
158 | struct psi_group { | ||
159 | diff --git a/kernel/cgroup/cgroup-v1.c b/kernel/cgroup/cgroup-v1.c | ||
160 | index 2d0ef613ca070..5e465c4b1e64c 100644 | ||
161 | --- a/kernel/cgroup/cgroup-v1.c | ||
162 | +++ b/kernel/cgroup/cgroup-v1.c | ||
163 | @@ -549,6 +549,14 @@ static ssize_t cgroup_release_agent_write(struct kernfs_open_file *of, | ||
164 | |||
165 | BUILD_BUG_ON(sizeof(cgrp->root->release_agent_path) < PATH_MAX); | ||
166 | |||
167 | + /* | ||
168 | + * Release agent gets called with all capabilities, | ||
169 | + * require capabilities to set release agent. | ||
170 | + */ | ||
171 | + if ((of->file->f_cred->user_ns != &init_user_ns) || | ||
172 | + !capable(CAP_SYS_ADMIN)) | ||
173 | + return -EPERM; | ||
174 | + | ||
175 | cgrp = cgroup_kn_lock_live(of->kn, false); | ||
176 | if (!cgrp) | ||
177 | return -ENODEV; | ||
178 | @@ -961,6 +969,12 @@ int cgroup1_parse_param(struct fs_context *fc, struct fs_parameter *param) | ||
179 | /* Specifying two release agents is forbidden */ | ||
180 | if (ctx->release_agent) | ||
181 | return cg_invalf(fc, "cgroup1: release_agent respecified"); | ||
182 | + /* | ||
183 | + * Release agent gets called with all capabilities, | ||
184 | + * require capabilities to set release agent. | ||
185 | + */ | ||
186 | + if ((fc->user_ns != &init_user_ns) || !capable(CAP_SYS_ADMIN)) | ||
187 | + return cg_invalf(fc, "cgroup1: Setting release_agent not allowed"); | ||
188 | ctx->release_agent = param->string; | ||
189 | param->string = NULL; | ||
190 | break; | ||
191 | diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c | ||
192 | index 1904ffcee0f1e..ce1745ac7b8c0 100644 | ||
193 | --- a/kernel/cgroup/cgroup.c | ||
194 | +++ b/kernel/cgroup/cgroup.c | ||
195 | @@ -3659,6 +3659,12 @@ static ssize_t cgroup_pressure_write(struct kernfs_open_file *of, char *buf, | ||
196 | cgroup_get(cgrp); | ||
197 | cgroup_kn_unlock(of->kn); | ||
198 | |||
199 | + /* Allow only one trigger per file descriptor */ | ||
200 | + if (of->priv) { | ||
201 | + cgroup_put(cgrp); | ||
202 | + return -EBUSY; | ||
203 | + } | ||
204 | + | ||
205 | psi = cgroup_ino(cgrp) == 1 ? &psi_system : &cgrp->psi; | ||
206 | new = psi_trigger_create(psi, buf, nbytes, res); | ||
207 | if (IS_ERR(new)) { | ||
208 | @@ -3666,8 +3672,7 @@ static ssize_t cgroup_pressure_write(struct kernfs_open_file *of, char *buf, | ||
209 | return PTR_ERR(new); | ||
210 | } | ||
211 | |||
212 | - psi_trigger_replace(&of->priv, new); | ||
213 | - | ||
214 | + smp_store_release(&of->priv, new); | ||
215 | cgroup_put(cgrp); | ||
216 | |||
217 | return nbytes; | ||
218 | @@ -3702,7 +3707,7 @@ static __poll_t cgroup_pressure_poll(struct kernfs_open_file *of, | ||
219 | |||
220 | static void cgroup_pressure_release(struct kernfs_open_file *of) | ||
221 | { | ||
222 | - psi_trigger_replace(&of->priv, NULL); | ||
223 | + psi_trigger_destroy(of->priv); | ||
224 | } | ||
225 | #endif /* CONFIG_PSI */ | ||
226 | |||
227 | diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c | ||
228 | index badfa8f153599..411be8b2e837e 100644 | ||
229 | --- a/kernel/cgroup/cpuset.c | ||
230 | +++ b/kernel/cgroup/cpuset.c | ||
231 | @@ -1558,8 +1558,7 @@ static int update_cpumask(struct cpuset *cs, struct cpuset *trialcs, | ||
232 | * Make sure that subparts_cpus is a subset of cpus_allowed. | ||
233 | */ | ||
234 | if (cs->nr_subparts_cpus) { | ||
235 | - cpumask_andnot(cs->subparts_cpus, cs->subparts_cpus, | ||
236 | - cs->cpus_allowed); | ||
237 | + cpumask_and(cs->subparts_cpus, cs->subparts_cpus, cs->cpus_allowed); | ||
238 | cs->nr_subparts_cpus = cpumask_weight(cs->subparts_cpus); | ||
239 | } | ||
240 | spin_unlock_irq(&callback_lock); | ||
241 | diff --git a/kernel/sched/psi.c b/kernel/sched/psi.c | ||
242 | index 9154e745f0978..9dd83eb74a9da 100644 | ||
243 | --- a/kernel/sched/psi.c | ||
244 | +++ b/kernel/sched/psi.c | ||
245 | @@ -1046,7 +1046,6 @@ struct psi_trigger *psi_trigger_create(struct psi_group *group, | ||
246 | t->event = 0; | ||
247 | t->last_event_time = 0; | ||
248 | init_waitqueue_head(&t->event_wait); | ||
249 | - kref_init(&t->refcount); | ||
250 | |||
251 | mutex_lock(&group->trigger_lock); | ||
252 | |||
253 | @@ -1079,15 +1078,19 @@ struct psi_trigger *psi_trigger_create(struct psi_group *group, | ||
254 | return t; | ||
255 | } | ||
256 | |||
257 | -static void psi_trigger_destroy(struct kref *ref) | ||
258 | +void psi_trigger_destroy(struct psi_trigger *t) | ||
259 | { | ||
260 | - struct psi_trigger *t = container_of(ref, struct psi_trigger, refcount); | ||
261 | - struct psi_group *group = t->group; | ||
262 | + struct psi_group *group; | ||
263 | struct kthread_worker *kworker_to_destroy = NULL; | ||
264 | |||
265 | - if (static_branch_likely(&psi_disabled)) | ||
266 | + /* | ||
267 | + * We do not check psi_disabled since it might have been disabled after | ||
268 | + * the trigger got created. | ||
269 | + */ | ||
270 | + if (!t) | ||
271 | return; | ||
272 | |||
273 | + group = t->group; | ||
274 | /* | ||
275 | * Wakeup waiters to stop polling. Can happen if cgroup is deleted | ||
276 | * from under a polling process. | ||
277 | @@ -1122,9 +1125,9 @@ static void psi_trigger_destroy(struct kref *ref) | ||
278 | mutex_unlock(&group->trigger_lock); | ||
279 | |||
280 | /* | ||
281 | - * Wait for both *trigger_ptr from psi_trigger_replace and | ||
282 | - * poll_kworker RCUs to complete their read-side critical sections | ||
283 | - * before destroying the trigger and optionally the poll_kworker | ||
284 | + * Wait for psi_schedule_poll_work RCU to complete its read-side | ||
285 | + * critical section before destroying the trigger and optionally the | ||
286 | + * poll_task. | ||
287 | */ | ||
288 | synchronize_rcu(); | ||
289 | /* | ||
290 | @@ -1146,18 +1149,6 @@ static void psi_trigger_destroy(struct kref *ref) | ||
291 | kfree(t); | ||
292 | } | ||
293 | |||
294 | -void psi_trigger_replace(void **trigger_ptr, struct psi_trigger *new) | ||
295 | -{ | ||
296 | - struct psi_trigger *old = *trigger_ptr; | ||
297 | - | ||
298 | - if (static_branch_likely(&psi_disabled)) | ||
299 | - return; | ||
300 | - | ||
301 | - rcu_assign_pointer(*trigger_ptr, new); | ||
302 | - if (old) | ||
303 | - kref_put(&old->refcount, psi_trigger_destroy); | ||
304 | -} | ||
305 | - | ||
306 | __poll_t psi_trigger_poll(void **trigger_ptr, | ||
307 | struct file *file, poll_table *wait) | ||
308 | { | ||
309 | @@ -1167,24 +1158,15 @@ __poll_t psi_trigger_poll(void **trigger_ptr, | ||
310 | if (static_branch_likely(&psi_disabled)) | ||
311 | return DEFAULT_POLLMASK | EPOLLERR | EPOLLPRI; | ||
312 | |||
313 | - rcu_read_lock(); | ||
314 | - | ||
315 | - t = rcu_dereference(*(void __rcu __force **)trigger_ptr); | ||
316 | - if (!t) { | ||
317 | - rcu_read_unlock(); | ||
318 | + t = smp_load_acquire(trigger_ptr); | ||
319 | + if (!t) | ||
320 | return DEFAULT_POLLMASK | EPOLLERR | EPOLLPRI; | ||
321 | - } | ||
322 | - kref_get(&t->refcount); | ||
323 | - | ||
324 | - rcu_read_unlock(); | ||
325 | |||
326 | poll_wait(file, &t->event_wait, wait); | ||
327 | |||
328 | if (cmpxchg(&t->event, 1, 0) == 1) | ||
329 | ret |= EPOLLPRI; | ||
330 | |||
331 | - kref_put(&t->refcount, psi_trigger_destroy); | ||
332 | - | ||
333 | return ret; | ||
334 | } | ||
335 | |||
336 | @@ -1208,14 +1190,24 @@ static ssize_t psi_write(struct file *file, const char __user *user_buf, | ||
337 | |||
338 | buf[buf_size - 1] = '\0'; | ||
339 | |||
340 | - new = psi_trigger_create(&psi_system, buf, nbytes, res); | ||
341 | - if (IS_ERR(new)) | ||
342 | - return PTR_ERR(new); | ||
343 | - | ||
344 | seq = file->private_data; | ||
345 | + | ||
346 | /* Take seq->lock to protect seq->private from concurrent writes */ | ||
347 | mutex_lock(&seq->lock); | ||
348 | - psi_trigger_replace(&seq->private, new); | ||
349 | + | ||
350 | + /* Allow only one trigger per file descriptor */ | ||
351 | + if (seq->private) { | ||
352 | + mutex_unlock(&seq->lock); | ||
353 | + return -EBUSY; | ||
354 | + } | ||
355 | + | ||
356 | + new = psi_trigger_create(&psi_system, buf, nbytes, res); | ||
357 | + if (IS_ERR(new)) { | ||
358 | + mutex_unlock(&seq->lock); | ||
359 | + return PTR_ERR(new); | ||
360 | + } | ||
361 | + | ||
362 | + smp_store_release(&seq->private, new); | ||
363 | mutex_unlock(&seq->lock); | ||
364 | |||
365 | return nbytes; | ||
366 | @@ -1250,7 +1242,7 @@ static int psi_fop_release(struct inode *inode, struct file *file) | ||
367 | { | ||
368 | struct seq_file *seq = file->private_data; | ||
369 | |||
370 | - psi_trigger_replace(&seq->private, NULL); | ||
371 | + psi_trigger_destroy(seq->private); | ||
372 | return single_release(inode, file); | ||
373 | } | ||
374 | |||
375 | diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c | ||
376 | index 55c0f32b9375b..dbc9b2f53649d 100644 | ||
377 | --- a/net/core/rtnetlink.c | ||
378 | +++ b/net/core/rtnetlink.c | ||
379 | @@ -3022,8 +3022,8 @@ static int __rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh, | ||
380 | struct nlattr *slave_attr[RTNL_SLAVE_MAX_TYPE + 1]; | ||
381 | unsigned char name_assign_type = NET_NAME_USER; | ||
382 | struct nlattr *linkinfo[IFLA_INFO_MAX + 1]; | ||
383 | - const struct rtnl_link_ops *m_ops = NULL; | ||
384 | - struct net_device *master_dev = NULL; | ||
385 | + const struct rtnl_link_ops *m_ops; | ||
386 | + struct net_device *master_dev; | ||
387 | struct net *net = sock_net(skb->sk); | ||
388 | const struct rtnl_link_ops *ops; | ||
389 | struct nlattr *tb[IFLA_MAX + 1]; | ||
390 | @@ -3063,6 +3063,8 @@ replay: | ||
391 | dev = NULL; | ||
392 | } | ||
393 | |||
394 | + master_dev = NULL; | ||
395 | + m_ops = NULL; | ||
396 | if (dev) { | ||
397 | master_dev = netdev_master_upper_dev_get(dev); | ||
398 | if (master_dev) | ||
399 | diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c | ||
400 | index 839e1caa57a59..ed11013d4b953 100644 | ||
401 | --- a/net/packet/af_packet.c | ||
402 | +++ b/net/packet/af_packet.c | ||
403 | @@ -1729,7 +1729,10 @@ static int fanout_add(struct sock *sk, u16 id, u16 type_flags) | ||
404 | err = -ENOSPC; | ||
405 | if (refcount_read(&match->sk_ref) < PACKET_FANOUT_MAX) { | ||
406 | __dev_remove_pack(&po->prot_hook); | ||
407 | - po->fanout = match; | ||
408 | + | ||
409 | + /* Paired with packet_setsockopt(PACKET_FANOUT_DATA) */ | ||
410 | + WRITE_ONCE(po->fanout, match); | ||
411 | + | ||
412 | po->rollover = rollover; | ||
413 | rollover = NULL; | ||
414 | refcount_set(&match->sk_ref, refcount_read(&match->sk_ref) + 1); | ||
415 | @@ -3876,7 +3879,8 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv | ||
416 | } | ||
417 | case PACKET_FANOUT_DATA: | ||
418 | { | ||
419 | - if (!po->fanout) | ||
420 | + /* Paired with the WRITE_ONCE() in fanout_add() */ | ||
421 | + if (!READ_ONCE(po->fanout)) | ||
422 | return -EINVAL; | ||
423 | |||
424 | return fanout_set_data(po, optval, optlen); | ||
425 | diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c | ||
426 | index a4c61205462ac..80205b138d113 100644 | ||
427 | --- a/net/sched/cls_api.c | ||
428 | +++ b/net/sched/cls_api.c | ||
429 | @@ -1928,9 +1928,9 @@ static int tc_new_tfilter(struct sk_buff *skb, struct nlmsghdr *n, | ||
430 | bool prio_allocate; | ||
431 | u32 parent; | ||
432 | u32 chain_index; | ||
433 | - struct Qdisc *q = NULL; | ||
434 | + struct Qdisc *q; | ||
435 | struct tcf_chain_info chain_info; | ||
436 | - struct tcf_chain *chain = NULL; | ||
437 | + struct tcf_chain *chain; | ||
438 | struct tcf_block *block; | ||
439 | struct tcf_proto *tp; | ||
440 | unsigned long cl; | ||
441 | @@ -1958,6 +1958,8 @@ replay: | ||
442 | tp = NULL; | ||
443 | cl = 0; | ||
444 | block = NULL; | ||
445 | + q = NULL; | ||
446 | + chain = NULL; | ||
447 | |||
448 | if (prio == 0) { | ||
449 | /* If no priority is provided by the user, | ||
450 | @@ -2764,8 +2766,8 @@ static int tc_ctl_chain(struct sk_buff *skb, struct nlmsghdr *n, | ||
451 | struct tcmsg *t; | ||
452 | u32 parent; | ||
453 | u32 chain_index; | ||
454 | - struct Qdisc *q = NULL; | ||
455 | - struct tcf_chain *chain = NULL; | ||
456 | + struct Qdisc *q; | ||
457 | + struct tcf_chain *chain; | ||
458 | struct tcf_block *block; | ||
459 | unsigned long cl; | ||
460 | int err; | ||
461 | @@ -2775,6 +2777,7 @@ static int tc_ctl_chain(struct sk_buff *skb, struct nlmsghdr *n, | ||
462 | return -EPERM; | ||
463 | |||
464 | replay: | ||
465 | + q = NULL; | ||
466 | err = nlmsg_parse_deprecated(n, sizeof(*t), tca, TCA_MAX, | ||
467 | rtm_tca_policy, extack); | ||
468 | if (err < 0) |