Annotation of /trunk/kernel-alx-legacy/patches-4.9/0112-4.9.13-all-fixes.patch
Parent Directory | Revision Log
Revision 3608 -
(hide annotations)
(download)
Fri Aug 14 07:34:29 2020 UTC (4 years, 1 month ago) by niro
File size: 34344 byte(s)
Fri Aug 14 07:34:29 2020 UTC (4 years, 1 month ago) by niro
File size: 34344 byte(s)
-added kerenl-alx-legacy pkg
1 | niro | 3608 | diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt |
2 | index 922dec8fa07e..65b05ba6ef98 100644 | ||
3 | --- a/Documentation/kernel-parameters.txt | ||
4 | +++ b/Documentation/kernel-parameters.txt | ||
5 | @@ -1391,6 +1391,10 @@ bytes respectively. Such letter suffixes can also be entirely omitted. | ||
6 | When zero, profiling data is discarded and associated | ||
7 | debugfs files are removed at module unload time. | ||
8 | |||
9 | + goldfish [X86] Enable the goldfish android emulator platform. | ||
10 | + Don't use this when you are not running on the | ||
11 | + android emulator | ||
12 | + | ||
13 | gpt [EFI] Forces disk with valid GPT signature but | ||
14 | invalid Protective MBR to be treated as GPT. If the | ||
15 | primary GPT is corrupted, it enables the backup/alternate | ||
16 | diff --git a/Makefile b/Makefile | ||
17 | index 3cd6f6fb4f20..14dc2758345b 100644 | ||
18 | --- a/Makefile | ||
19 | +++ b/Makefile | ||
20 | @@ -1,6 +1,6 @@ | ||
21 | VERSION = 4 | ||
22 | PATCHLEVEL = 9 | ||
23 | -SUBLEVEL = 12 | ||
24 | +SUBLEVEL = 13 | ||
25 | EXTRAVERSION = | ||
26 | NAME = Roaring Lionus | ||
27 | |||
28 | diff --git a/arch/x86/platform/goldfish/goldfish.c b/arch/x86/platform/goldfish/goldfish.c | ||
29 | index 1693107a518e..0d17c0aafeb1 100644 | ||
30 | --- a/arch/x86/platform/goldfish/goldfish.c | ||
31 | +++ b/arch/x86/platform/goldfish/goldfish.c | ||
32 | @@ -42,10 +42,22 @@ static struct resource goldfish_pdev_bus_resources[] = { | ||
33 | } | ||
34 | }; | ||
35 | |||
36 | +static bool goldfish_enable __initdata; | ||
37 | + | ||
38 | +static int __init goldfish_setup(char *str) | ||
39 | +{ | ||
40 | + goldfish_enable = true; | ||
41 | + return 0; | ||
42 | +} | ||
43 | +__setup("goldfish", goldfish_setup); | ||
44 | + | ||
45 | static int __init goldfish_init(void) | ||
46 | { | ||
47 | + if (!goldfish_enable) | ||
48 | + return -ENODEV; | ||
49 | + | ||
50 | platform_device_register_simple("goldfish_pdev_bus", -1, | ||
51 | - goldfish_pdev_bus_resources, 2); | ||
52 | + goldfish_pdev_bus_resources, 2); | ||
53 | return 0; | ||
54 | } | ||
55 | device_initcall(goldfish_init); | ||
56 | diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c | ||
57 | index 6bb21b31cfeb..a543ea676de3 100644 | ||
58 | --- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c | ||
59 | +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c | ||
60 | @@ -567,10 +567,14 @@ int mlx5e_stats_flower(struct mlx5e_priv *priv, | ||
61 | |||
62 | mlx5_fc_query_cached(counter, &bytes, &packets, &lastuse); | ||
63 | |||
64 | + preempt_disable(); | ||
65 | + | ||
66 | tcf_exts_to_list(f->exts, &actions); | ||
67 | list_for_each_entry(a, &actions, list) | ||
68 | tcf_action_stats_update(a, bytes, packets, lastuse); | ||
69 | |||
70 | + preempt_enable(); | ||
71 | + | ||
72 | return 0; | ||
73 | } | ||
74 | |||
75 | diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c | ||
76 | index b9087b828eff..3f1971d485f3 100644 | ||
77 | --- a/drivers/net/ethernet/ti/cpsw.c | ||
78 | +++ b/drivers/net/ethernet/ti/cpsw.c | ||
79 | @@ -2925,7 +2925,7 @@ static int cpsw_resume(struct device *dev) | ||
80 | { | ||
81 | struct platform_device *pdev = to_platform_device(dev); | ||
82 | struct net_device *ndev = platform_get_drvdata(pdev); | ||
83 | - struct cpsw_common *cpsw = netdev_priv(ndev); | ||
84 | + struct cpsw_common *cpsw = ndev_to_cpsw(ndev); | ||
85 | |||
86 | /* Select default pin state */ | ||
87 | pinctrl_pm_select_default_state(dev); | ||
88 | diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c | ||
89 | index 0fafaa9d903b..d4f495b41bd4 100644 | ||
90 | --- a/drivers/net/vxlan.c | ||
91 | +++ b/drivers/net/vxlan.c | ||
92 | @@ -2449,7 +2449,8 @@ static int vxlan_fill_metadata_dst(struct net_device *dev, struct sk_buff *skb) | ||
93 | return -EINVAL; | ||
94 | rt = vxlan_get_route(vxlan, skb, 0, info->key.tos, | ||
95 | info->key.u.ipv4.dst, | ||
96 | - &info->key.u.ipv4.src, NULL, info); | ||
97 | + &info->key.u.ipv4.src, | ||
98 | + &info->dst_cache, info); | ||
99 | if (IS_ERR(rt)) | ||
100 | return PTR_ERR(rt); | ||
101 | ip_rt_put(rt); | ||
102 | @@ -2459,7 +2460,8 @@ static int vxlan_fill_metadata_dst(struct net_device *dev, struct sk_buff *skb) | ||
103 | |||
104 | ndst = vxlan6_get_route(vxlan, skb, 0, info->key.tos, | ||
105 | info->key.label, &info->key.u.ipv6.dst, | ||
106 | - &info->key.u.ipv6.src, NULL, info); | ||
107 | + &info->key.u.ipv6.src, | ||
108 | + &info->dst_cache, info); | ||
109 | if (IS_ERR(ndst)) | ||
110 | return PTR_ERR(ndst); | ||
111 | dst_release(ndst); | ||
112 | diff --git a/drivers/net/wireless/realtek/rtlwifi/usb.c b/drivers/net/wireless/realtek/rtlwifi/usb.c | ||
113 | index 3837bbdecf05..ae0c48f3c2bc 100644 | ||
114 | --- a/drivers/net/wireless/realtek/rtlwifi/usb.c | ||
115 | +++ b/drivers/net/wireless/realtek/rtlwifi/usb.c | ||
116 | @@ -831,12 +831,30 @@ static void rtl_usb_stop(struct ieee80211_hw *hw) | ||
117 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
118 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
119 | struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); | ||
120 | + struct urb *urb; | ||
121 | |||
122 | /* should after adapter start and interrupt enable. */ | ||
123 | set_hal_stop(rtlhal); | ||
124 | cancel_work_sync(&rtlpriv->works.fill_h2c_cmd); | ||
125 | /* Enable software */ | ||
126 | SET_USB_STOP(rtlusb); | ||
127 | + | ||
128 | + /* free pre-allocated URBs from rtl_usb_start() */ | ||
129 | + usb_kill_anchored_urbs(&rtlusb->rx_submitted); | ||
130 | + | ||
131 | + tasklet_kill(&rtlusb->rx_work_tasklet); | ||
132 | + cancel_work_sync(&rtlpriv->works.lps_change_work); | ||
133 | + | ||
134 | + flush_workqueue(rtlpriv->works.rtl_wq); | ||
135 | + | ||
136 | + skb_queue_purge(&rtlusb->rx_queue); | ||
137 | + | ||
138 | + while ((urb = usb_get_from_anchor(&rtlusb->rx_cleanup_urbs))) { | ||
139 | + usb_free_coherent(urb->dev, urb->transfer_buffer_length, | ||
140 | + urb->transfer_buffer, urb->transfer_dma); | ||
141 | + usb_free_urb(urb); | ||
142 | + } | ||
143 | + | ||
144 | rtlpriv->cfg->ops->hw_disable(hw); | ||
145 | } | ||
146 | |||
147 | diff --git a/drivers/platform/goldfish/pdev_bus.c b/drivers/platform/goldfish/pdev_bus.c | ||
148 | index 1f52462f4cdd..dd9ea463c2a4 100644 | ||
149 | --- a/drivers/platform/goldfish/pdev_bus.c | ||
150 | +++ b/drivers/platform/goldfish/pdev_bus.c | ||
151 | @@ -157,23 +157,26 @@ static int goldfish_new_pdev(void) | ||
152 | static irqreturn_t goldfish_pdev_bus_interrupt(int irq, void *dev_id) | ||
153 | { | ||
154 | irqreturn_t ret = IRQ_NONE; | ||
155 | + | ||
156 | while (1) { | ||
157 | u32 op = readl(pdev_bus_base + PDEV_BUS_OP); | ||
158 | - switch (op) { | ||
159 | - case PDEV_BUS_OP_DONE: | ||
160 | - return IRQ_NONE; | ||
161 | |||
162 | + switch (op) { | ||
163 | case PDEV_BUS_OP_REMOVE_DEV: | ||
164 | goldfish_pdev_remove(); | ||
165 | + ret = IRQ_HANDLED; | ||
166 | break; | ||
167 | |||
168 | case PDEV_BUS_OP_ADD_DEV: | ||
169 | goldfish_new_pdev(); | ||
170 | + ret = IRQ_HANDLED; | ||
171 | break; | ||
172 | + | ||
173 | + case PDEV_BUS_OP_DONE: | ||
174 | + default: | ||
175 | + return ret; | ||
176 | } | ||
177 | - ret = IRQ_HANDLED; | ||
178 | } | ||
179 | - return ret; | ||
180 | } | ||
181 | |||
182 | static int goldfish_pdev_bus_probe(struct platform_device *pdev) | ||
183 | diff --git a/drivers/tty/serial/msm_serial.c b/drivers/tty/serial/msm_serial.c | ||
184 | index 7312e7e01b7e..6788e7532dff 100644 | ||
185 | --- a/drivers/tty/serial/msm_serial.c | ||
186 | +++ b/drivers/tty/serial/msm_serial.c | ||
187 | @@ -1809,6 +1809,7 @@ static const struct of_device_id msm_match_table[] = { | ||
188 | { .compatible = "qcom,msm-uartdm" }, | ||
189 | {} | ||
190 | }; | ||
191 | +MODULE_DEVICE_TABLE(of, msm_match_table); | ||
192 | |||
193 | static struct platform_driver msm_platform_driver = { | ||
194 | .remove = msm_serial_remove, | ||
195 | diff --git a/drivers/usb/serial/ark3116.c b/drivers/usb/serial/ark3116.c | ||
196 | index 1532cde8a437..7812052dc700 100644 | ||
197 | --- a/drivers/usb/serial/ark3116.c | ||
198 | +++ b/drivers/usb/serial/ark3116.c | ||
199 | @@ -99,10 +99,17 @@ static int ark3116_read_reg(struct usb_serial *serial, | ||
200 | usb_rcvctrlpipe(serial->dev, 0), | ||
201 | 0xfe, 0xc0, 0, reg, | ||
202 | buf, 1, ARK_TIMEOUT); | ||
203 | - if (result < 0) | ||
204 | + if (result < 1) { | ||
205 | + dev_err(&serial->interface->dev, | ||
206 | + "failed to read register %u: %d\n", | ||
207 | + reg, result); | ||
208 | + if (result >= 0) | ||
209 | + result = -EIO; | ||
210 | + | ||
211 | return result; | ||
212 | - else | ||
213 | - return buf[0]; | ||
214 | + } | ||
215 | + | ||
216 | + return buf[0]; | ||
217 | } | ||
218 | |||
219 | static inline int calc_divisor(int bps) | ||
220 | diff --git a/drivers/usb/serial/console.c b/drivers/usb/serial/console.c | ||
221 | index 8967715fe6fc..b6f1adefb758 100644 | ||
222 | --- a/drivers/usb/serial/console.c | ||
223 | +++ b/drivers/usb/serial/console.c | ||
224 | @@ -143,6 +143,7 @@ static int usb_console_setup(struct console *co, char *options) | ||
225 | tty->driver = usb_serial_tty_driver; | ||
226 | tty->index = co->index; | ||
227 | init_ldsem(&tty->ldisc_sem); | ||
228 | + spin_lock_init(&tty->files_lock); | ||
229 | INIT_LIST_HEAD(&tty->tty_files); | ||
230 | kref_get(&tty->driver->kref); | ||
231 | __module_get(tty->driver->owner); | ||
232 | diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c | ||
233 | index 243ac5ebe46a..8bb48751028c 100644 | ||
234 | --- a/drivers/usb/serial/cp210x.c | ||
235 | +++ b/drivers/usb/serial/cp210x.c | ||
236 | @@ -172,6 +172,8 @@ static const struct usb_device_id id_table[] = { | ||
237 | { USB_DEVICE(0x1901, 0x0190) }, /* GE B850 CP2105 Recorder interface */ | ||
238 | { USB_DEVICE(0x1901, 0x0193) }, /* GE B650 CP2104 PMC interface */ | ||
239 | { USB_DEVICE(0x1901, 0x0194) }, /* GE Healthcare Remote Alarm Box */ | ||
240 | + { USB_DEVICE(0x1901, 0x0195) }, /* GE B850/B650/B450 CP2104 DP UART interface */ | ||
241 | + { USB_DEVICE(0x1901, 0x0196) }, /* GE B850 CP2105 DP UART interface */ | ||
242 | { USB_DEVICE(0x19CF, 0x3000) }, /* Parrot NMEA GPS Flight Recorder */ | ||
243 | { USB_DEVICE(0x1ADB, 0x0001) }, /* Schweitzer Engineering C662 Cable */ | ||
244 | { USB_DEVICE(0x1B1C, 0x1C00) }, /* Corsair USB Dongle */ | ||
245 | diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c | ||
246 | index 6e9fc8bcc285..99a0a5f1b400 100644 | ||
247 | --- a/drivers/usb/serial/ftdi_sio.c | ||
248 | +++ b/drivers/usb/serial/ftdi_sio.c | ||
249 | @@ -1807,8 +1807,6 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port) | ||
250 | |||
251 | mutex_init(&priv->cfg_lock); | ||
252 | |||
253 | - priv->flags = ASYNC_LOW_LATENCY; | ||
254 | - | ||
255 | if (quirk && quirk->port_probe) | ||
256 | quirk->port_probe(priv); | ||
257 | |||
258 | @@ -2072,6 +2070,20 @@ static int ftdi_process_packet(struct usb_serial_port *port, | ||
259 | priv->prev_status = status; | ||
260 | } | ||
261 | |||
262 | + /* save if the transmitter is empty or not */ | ||
263 | + if (packet[1] & FTDI_RS_TEMT) | ||
264 | + priv->transmit_empty = 1; | ||
265 | + else | ||
266 | + priv->transmit_empty = 0; | ||
267 | + | ||
268 | + len -= 2; | ||
269 | + if (!len) | ||
270 | + return 0; /* status only */ | ||
271 | + | ||
272 | + /* | ||
273 | + * Break and error status must only be processed for packets with | ||
274 | + * data payload to avoid over-reporting. | ||
275 | + */ | ||
276 | flag = TTY_NORMAL; | ||
277 | if (packet[1] & FTDI_RS_ERR_MASK) { | ||
278 | /* Break takes precedence over parity, which takes precedence | ||
279 | @@ -2094,15 +2106,6 @@ static int ftdi_process_packet(struct usb_serial_port *port, | ||
280 | } | ||
281 | } | ||
282 | |||
283 | - /* save if the transmitter is empty or not */ | ||
284 | - if (packet[1] & FTDI_RS_TEMT) | ||
285 | - priv->transmit_empty = 1; | ||
286 | - else | ||
287 | - priv->transmit_empty = 0; | ||
288 | - | ||
289 | - len -= 2; | ||
290 | - if (!len) | ||
291 | - return 0; /* status only */ | ||
292 | port->icount.rx += len; | ||
293 | ch = packet + 2; | ||
294 | |||
295 | @@ -2433,8 +2436,12 @@ static int ftdi_get_modem_status(struct usb_serial_port *port, | ||
296 | FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE, | ||
297 | 0, priv->interface, | ||
298 | buf, len, WDR_TIMEOUT); | ||
299 | - if (ret < 0) { | ||
300 | + | ||
301 | + /* NOTE: We allow short responses and handle that below. */ | ||
302 | + if (ret < 1) { | ||
303 | dev_err(&port->dev, "failed to get modem status: %d\n", ret); | ||
304 | + if (ret >= 0) | ||
305 | + ret = -EIO; | ||
306 | ret = usb_translate_errors(ret); | ||
307 | goto out; | ||
308 | } | ||
309 | diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c | ||
310 | index 4f9af47e6a29..5c4fc3abf6a7 100644 | ||
311 | --- a/drivers/usb/serial/mos7840.c | ||
312 | +++ b/drivers/usb/serial/mos7840.c | ||
313 | @@ -1024,6 +1024,7 @@ static int mos7840_open(struct tty_struct *tty, struct usb_serial_port *port) | ||
314 | * (can't set it up in mos7840_startup as the structures * | ||
315 | * were not set up at that time.) */ | ||
316 | if (port0->open_ports == 1) { | ||
317 | + /* FIXME: Buffer never NULL, so URB is not submitted. */ | ||
318 | if (serial->port[0]->interrupt_in_buffer == NULL) { | ||
319 | /* set up interrupt urb */ | ||
320 | usb_fill_int_urb(serial->port[0]->interrupt_in_urb, | ||
321 | @@ -2119,7 +2120,8 @@ static int mos7840_calc_num_ports(struct usb_serial *serial) | ||
322 | static int mos7840_attach(struct usb_serial *serial) | ||
323 | { | ||
324 | if (serial->num_bulk_in < serial->num_ports || | ||
325 | - serial->num_bulk_out < serial->num_ports) { | ||
326 | + serial->num_bulk_out < serial->num_ports || | ||
327 | + serial->num_interrupt_in < 1) { | ||
328 | dev_err(&serial->interface->dev, "missing endpoints\n"); | ||
329 | return -ENODEV; | ||
330 | } | ||
331 | diff --git a/drivers/usb/serial/opticon.c b/drivers/usb/serial/opticon.c | ||
332 | index 4b7bfb394a32..64bf258e7e00 100644 | ||
333 | --- a/drivers/usb/serial/opticon.c | ||
334 | +++ b/drivers/usb/serial/opticon.c | ||
335 | @@ -142,7 +142,7 @@ static int opticon_open(struct tty_struct *tty, struct usb_serial_port *port) | ||
336 | usb_clear_halt(port->serial->dev, port->read_urb->pipe); | ||
337 | |||
338 | res = usb_serial_generic_open(tty, port); | ||
339 | - if (!res) | ||
340 | + if (res) | ||
341 | return res; | ||
342 | |||
343 | /* Request CTS line state, sometimes during opening the current | ||
344 | diff --git a/drivers/usb/serial/spcp8x5.c b/drivers/usb/serial/spcp8x5.c | ||
345 | index 475e6c31b266..ddfd787c461c 100644 | ||
346 | --- a/drivers/usb/serial/spcp8x5.c | ||
347 | +++ b/drivers/usb/serial/spcp8x5.c | ||
348 | @@ -232,11 +232,17 @@ static int spcp8x5_get_msr(struct usb_serial_port *port, u8 *status) | ||
349 | ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), | ||
350 | GET_UART_STATUS, GET_UART_STATUS_TYPE, | ||
351 | 0, GET_UART_STATUS_MSR, buf, 1, 100); | ||
352 | - if (ret < 0) | ||
353 | + if (ret < 1) { | ||
354 | dev_err(&port->dev, "failed to get modem status: %d\n", ret); | ||
355 | + if (ret >= 0) | ||
356 | + ret = -EIO; | ||
357 | + goto out; | ||
358 | + } | ||
359 | |||
360 | dev_dbg(&port->dev, "0xc0:0x22:0:6 %d - 0x02%x\n", ret, *buf); | ||
361 | *status = *buf; | ||
362 | + ret = 0; | ||
363 | +out: | ||
364 | kfree(buf); | ||
365 | |||
366 | return ret; | ||
367 | diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c | ||
368 | index cdc6bdd495be..e8889614cec3 100644 | ||
369 | --- a/fs/xfs/xfs_iomap.c | ||
370 | +++ b/fs/xfs/xfs_iomap.c | ||
371 | @@ -1068,7 +1068,15 @@ xfs_file_iomap_end_delalloc( | ||
372 | xfs_fileoff_t end_fsb; | ||
373 | int error = 0; | ||
374 | |||
375 | - start_fsb = XFS_B_TO_FSB(mp, offset + written); | ||
376 | + /* | ||
377 | + * start_fsb refers to the first unused block after a short write. If | ||
378 | + * nothing was written, round offset down to point at the first block in | ||
379 | + * the range. | ||
380 | + */ | ||
381 | + if (unlikely(!written)) | ||
382 | + start_fsb = XFS_B_TO_FSBT(mp, offset); | ||
383 | + else | ||
384 | + start_fsb = XFS_B_TO_FSB(mp, offset + written); | ||
385 | end_fsb = XFS_B_TO_FSB(mp, offset + length); | ||
386 | |||
387 | /* | ||
388 | @@ -1080,6 +1088,9 @@ xfs_file_iomap_end_delalloc( | ||
389 | * blocks in the range, they are ours. | ||
390 | */ | ||
391 | if (start_fsb < end_fsb) { | ||
392 | + truncate_pagecache_range(VFS_I(ip), XFS_FSB_TO_B(mp, start_fsb), | ||
393 | + XFS_FSB_TO_B(mp, end_fsb) - 1); | ||
394 | + | ||
395 | xfs_ilock(ip, XFS_ILOCK_EXCL); | ||
396 | error = xfs_bmap_punch_delalloc_range(ip, start_fsb, | ||
397 | end_fsb - start_fsb); | ||
398 | diff --git a/include/acpi/platform/acenv.h b/include/acpi/platform/acenv.h | ||
399 | index 34cce729109c..fca15390a42c 100644 | ||
400 | --- a/include/acpi/platform/acenv.h | ||
401 | +++ b/include/acpi/platform/acenv.h | ||
402 | @@ -177,7 +177,7 @@ | ||
403 | #include "acmsvc.h" | ||
404 | |||
405 | #elif defined(__INTEL_COMPILER) | ||
406 | -#include "acintel.h" | ||
407 | +#include <acpi/platform/acintel.h> | ||
408 | |||
409 | #endif | ||
410 | |||
411 | diff --git a/include/acpi/platform/acintel.h b/include/acpi/platform/acintel.h | ||
412 | new file mode 100644 | ||
413 | index 000000000000..17bd3b7b4e5a | ||
414 | --- /dev/null | ||
415 | +++ b/include/acpi/platform/acintel.h | ||
416 | @@ -0,0 +1,87 @@ | ||
417 | +/****************************************************************************** | ||
418 | + * | ||
419 | + * Name: acintel.h - VC specific defines, etc. | ||
420 | + * | ||
421 | + *****************************************************************************/ | ||
422 | + | ||
423 | +/* | ||
424 | + * Copyright (C) 2000 - 2017, Intel Corp. | ||
425 | + * All rights reserved. | ||
426 | + * | ||
427 | + * Redistribution and use in source and binary forms, with or without | ||
428 | + * modification, are permitted provided that the following conditions | ||
429 | + * are met: | ||
430 | + * 1. Redistributions of source code must retain the above copyright | ||
431 | + * notice, this list of conditions, and the following disclaimer, | ||
432 | + * without modification. | ||
433 | + * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
434 | + * substantially similar to the "NO WARRANTY" disclaimer below | ||
435 | + * ("Disclaimer") and any redistribution must be conditioned upon | ||
436 | + * including a substantially similar Disclaimer requirement for further | ||
437 | + * binary redistribution. | ||
438 | + * 3. Neither the names of the above-listed copyright holders nor the names | ||
439 | + * of any contributors may be used to endorse or promote products derived | ||
440 | + * from this software without specific prior written permission. | ||
441 | + * | ||
442 | + * Alternatively, this software may be distributed under the terms of the | ||
443 | + * GNU General Public License ("GPL") version 2 as published by the Free | ||
444 | + * Software Foundation. | ||
445 | + * | ||
446 | + * NO WARRANTY | ||
447 | + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
448 | + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
449 | + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
450 | + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
451 | + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
452 | + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
453 | + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
454 | + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
455 | + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
456 | + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
457 | + * POSSIBILITY OF SUCH DAMAGES. | ||
458 | + */ | ||
459 | + | ||
460 | +#ifndef __ACINTEL_H__ | ||
461 | +#define __ACINTEL_H__ | ||
462 | + | ||
463 | +/* | ||
464 | + * Use compiler specific <stdarg.h> is a good practice for even when | ||
465 | + * -nostdinc is specified (i.e., ACPI_USE_STANDARD_HEADERS undefined. | ||
466 | + */ | ||
467 | +#include <stdarg.h> | ||
468 | + | ||
469 | +/* Configuration specific to Intel 64-bit C compiler */ | ||
470 | + | ||
471 | +#define COMPILER_DEPENDENT_INT64 __int64 | ||
472 | +#define COMPILER_DEPENDENT_UINT64 unsigned __int64 | ||
473 | +#define ACPI_INLINE __inline | ||
474 | + | ||
475 | +/* | ||
476 | + * Calling conventions: | ||
477 | + * | ||
478 | + * ACPI_SYSTEM_XFACE - Interfaces to host OS (handlers, threads) | ||
479 | + * ACPI_EXTERNAL_XFACE - External ACPI interfaces | ||
480 | + * ACPI_INTERNAL_XFACE - Internal ACPI interfaces | ||
481 | + * ACPI_INTERNAL_VAR_XFACE - Internal variable-parameter list interfaces | ||
482 | + */ | ||
483 | +#define ACPI_SYSTEM_XFACE | ||
484 | +#define ACPI_EXTERNAL_XFACE | ||
485 | +#define ACPI_INTERNAL_XFACE | ||
486 | +#define ACPI_INTERNAL_VAR_XFACE | ||
487 | + | ||
488 | +/* remark 981 - operands evaluated in no particular order */ | ||
489 | +#pragma warning(disable:981) | ||
490 | + | ||
491 | +/* warn C4100: unreferenced formal parameter */ | ||
492 | +#pragma warning(disable:4100) | ||
493 | + | ||
494 | +/* warn C4127: conditional expression is constant */ | ||
495 | +#pragma warning(disable:4127) | ||
496 | + | ||
497 | +/* warn C4706: assignment within conditional expression */ | ||
498 | +#pragma warning(disable:4706) | ||
499 | + | ||
500 | +/* warn C4214: bit field types other than int */ | ||
501 | +#pragma warning(disable:4214) | ||
502 | + | ||
503 | +#endif /* __ACINTEL_H__ */ | ||
504 | diff --git a/include/linux/ptr_ring.h b/include/linux/ptr_ring.h | ||
505 | index 2052011bf9fb..6c70444da3b9 100644 | ||
506 | --- a/include/linux/ptr_ring.h | ||
507 | +++ b/include/linux/ptr_ring.h | ||
508 | @@ -111,6 +111,11 @@ static inline int __ptr_ring_produce(struct ptr_ring *r, void *ptr) | ||
509 | return 0; | ||
510 | } | ||
511 | |||
512 | +/* | ||
513 | + * Note: resize (below) nests producer lock within consumer lock, so if you | ||
514 | + * consume in interrupt or BH context, you must disable interrupts/BH when | ||
515 | + * calling this. | ||
516 | + */ | ||
517 | static inline int ptr_ring_produce(struct ptr_ring *r, void *ptr) | ||
518 | { | ||
519 | int ret; | ||
520 | @@ -242,6 +247,11 @@ static inline void *__ptr_ring_consume(struct ptr_ring *r) | ||
521 | return ptr; | ||
522 | } | ||
523 | |||
524 | +/* | ||
525 | + * Note: resize (below) nests producer lock within consumer lock, so if you | ||
526 | + * call this in interrupt or BH context, you must disable interrupts/BH when | ||
527 | + * producing. | ||
528 | + */ | ||
529 | static inline void *ptr_ring_consume(struct ptr_ring *r) | ||
530 | { | ||
531 | void *ptr; | ||
532 | @@ -357,7 +367,7 @@ static inline void **__ptr_ring_swap_queue(struct ptr_ring *r, void **queue, | ||
533 | void **old; | ||
534 | void *ptr; | ||
535 | |||
536 | - while ((ptr = ptr_ring_consume(r))) | ||
537 | + while ((ptr = __ptr_ring_consume(r))) | ||
538 | if (producer < size) | ||
539 | queue[producer++] = ptr; | ||
540 | else if (destroy) | ||
541 | @@ -372,6 +382,12 @@ static inline void **__ptr_ring_swap_queue(struct ptr_ring *r, void **queue, | ||
542 | return old; | ||
543 | } | ||
544 | |||
545 | +/* | ||
546 | + * Note: producer lock is nested within consumer lock, so if you | ||
547 | + * resize you must make sure all uses nest correctly. | ||
548 | + * In particular if you consume ring in interrupt or BH context, you must | ||
549 | + * disable interrupts/BH when doing so. | ||
550 | + */ | ||
551 | static inline int ptr_ring_resize(struct ptr_ring *r, int size, gfp_t gfp, | ||
552 | void (*destroy)(void *)) | ||
553 | { | ||
554 | @@ -382,17 +398,25 @@ static inline int ptr_ring_resize(struct ptr_ring *r, int size, gfp_t gfp, | ||
555 | if (!queue) | ||
556 | return -ENOMEM; | ||
557 | |||
558 | - spin_lock_irqsave(&(r)->producer_lock, flags); | ||
559 | + spin_lock_irqsave(&(r)->consumer_lock, flags); | ||
560 | + spin_lock(&(r)->producer_lock); | ||
561 | |||
562 | old = __ptr_ring_swap_queue(r, queue, size, gfp, destroy); | ||
563 | |||
564 | - spin_unlock_irqrestore(&(r)->producer_lock, flags); | ||
565 | + spin_unlock(&(r)->producer_lock); | ||
566 | + spin_unlock_irqrestore(&(r)->consumer_lock, flags); | ||
567 | |||
568 | kfree(old); | ||
569 | |||
570 | return 0; | ||
571 | } | ||
572 | |||
573 | +/* | ||
574 | + * Note: producer lock is nested within consumer lock, so if you | ||
575 | + * resize you must make sure all uses nest correctly. | ||
576 | + * In particular if you consume ring in interrupt or BH context, you must | ||
577 | + * disable interrupts/BH when doing so. | ||
578 | + */ | ||
579 | static inline int ptr_ring_resize_multiple(struct ptr_ring **rings, int nrings, | ||
580 | int size, | ||
581 | gfp_t gfp, void (*destroy)(void *)) | ||
582 | @@ -412,10 +436,12 @@ static inline int ptr_ring_resize_multiple(struct ptr_ring **rings, int nrings, | ||
583 | } | ||
584 | |||
585 | for (i = 0; i < nrings; ++i) { | ||
586 | - spin_lock_irqsave(&(rings[i])->producer_lock, flags); | ||
587 | + spin_lock_irqsave(&(rings[i])->consumer_lock, flags); | ||
588 | + spin_lock(&(rings[i])->producer_lock); | ||
589 | queues[i] = __ptr_ring_swap_queue(rings[i], queues[i], | ||
590 | size, gfp, destroy); | ||
591 | - spin_unlock_irqrestore(&(rings[i])->producer_lock, flags); | ||
592 | + spin_unlock(&(rings[i])->producer_lock); | ||
593 | + spin_unlock_irqrestore(&(rings[i])->consumer_lock, flags); | ||
594 | } | ||
595 | |||
596 | for (i = 0; i < nrings; ++i) | ||
597 | diff --git a/mm/backing-dev.c b/mm/backing-dev.c | ||
598 | index 8fde443f36d7..6ff2d7744223 100644 | ||
599 | --- a/mm/backing-dev.c | ||
600 | +++ b/mm/backing-dev.c | ||
601 | @@ -757,15 +757,20 @@ static int cgwb_bdi_init(struct backing_dev_info *bdi) | ||
602 | if (!bdi->wb_congested) | ||
603 | return -ENOMEM; | ||
604 | |||
605 | + atomic_set(&bdi->wb_congested->refcnt, 1); | ||
606 | + | ||
607 | err = wb_init(&bdi->wb, bdi, 1, GFP_KERNEL); | ||
608 | if (err) { | ||
609 | - kfree(bdi->wb_congested); | ||
610 | + wb_congested_put(bdi->wb_congested); | ||
611 | return err; | ||
612 | } | ||
613 | return 0; | ||
614 | } | ||
615 | |||
616 | -static void cgwb_bdi_destroy(struct backing_dev_info *bdi) { } | ||
617 | +static void cgwb_bdi_destroy(struct backing_dev_info *bdi) | ||
618 | +{ | ||
619 | + wb_congested_put(bdi->wb_congested); | ||
620 | +} | ||
621 | |||
622 | #endif /* CONFIG_CGROUP_WRITEBACK */ | ||
623 | |||
624 | diff --git a/net/core/neighbour.c b/net/core/neighbour.c | ||
625 | index 2ae929f9bd06..9901e5b75a05 100644 | ||
626 | --- a/net/core/neighbour.c | ||
627 | +++ b/net/core/neighbour.c | ||
628 | @@ -2927,7 +2927,8 @@ static void neigh_proc_update(struct ctl_table *ctl, int write) | ||
629 | return; | ||
630 | |||
631 | set_bit(index, p->data_state); | ||
632 | - call_netevent_notifiers(NETEVENT_DELAY_PROBE_TIME_UPDATE, p); | ||
633 | + if (index == NEIGH_VAR_DELAY_PROBE_TIME) | ||
634 | + call_netevent_notifiers(NETEVENT_DELAY_PROBE_TIME_UPDATE, p); | ||
635 | if (!dev) /* NULL dev means this is default value */ | ||
636 | neigh_copy_dflt_parms(net, p, index); | ||
637 | } | ||
638 | diff --git a/net/dccp/input.c b/net/dccp/input.c | ||
639 | index ba347184bda9..8fedc2d49770 100644 | ||
640 | --- a/net/dccp/input.c | ||
641 | +++ b/net/dccp/input.c | ||
642 | @@ -606,7 +606,8 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb, | ||
643 | if (inet_csk(sk)->icsk_af_ops->conn_request(sk, | ||
644 | skb) < 0) | ||
645 | return 1; | ||
646 | - goto discard; | ||
647 | + consume_skb(skb); | ||
648 | + return 0; | ||
649 | } | ||
650 | if (dh->dccph_type == DCCP_PKT_RESET) | ||
651 | goto discard; | ||
652 | diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c | ||
653 | index 65336f38a5d8..9826695ddfc6 100644 | ||
654 | --- a/net/ipv4/ip_sockglue.c | ||
655 | +++ b/net/ipv4/ip_sockglue.c | ||
656 | @@ -105,10 +105,10 @@ static void ip_cmsg_recv_checksum(struct msghdr *msg, struct sk_buff *skb, | ||
657 | if (skb->ip_summed != CHECKSUM_COMPLETE) | ||
658 | return; | ||
659 | |||
660 | - if (offset != 0) | ||
661 | - csum = csum_sub(csum, | ||
662 | - csum_partial(skb_transport_header(skb) + tlen, | ||
663 | - offset, 0)); | ||
664 | + if (offset != 0) { | ||
665 | + int tend_off = skb_transport_offset(skb) + tlen; | ||
666 | + csum = csum_sub(csum, skb_checksum(skb, tend_off, offset, 0)); | ||
667 | + } | ||
668 | |||
669 | put_cmsg(msg, SOL_IP, IP_CHECKSUM, sizeof(__wsum), &csum); | ||
670 | } | ||
671 | diff --git a/net/irda/irqueue.c b/net/irda/irqueue.c | ||
672 | index acbe61c7e683..160dc89335e2 100644 | ||
673 | --- a/net/irda/irqueue.c | ||
674 | +++ b/net/irda/irqueue.c | ||
675 | @@ -383,9 +383,6 @@ EXPORT_SYMBOL(hashbin_new); | ||
676 | * for deallocating this structure if it's complex. If not the user can | ||
677 | * just supply kfree, which should take care of the job. | ||
678 | */ | ||
679 | -#ifdef CONFIG_LOCKDEP | ||
680 | -static int hashbin_lock_depth = 0; | ||
681 | -#endif | ||
682 | int hashbin_delete( hashbin_t* hashbin, FREE_FUNC free_func) | ||
683 | { | ||
684 | irda_queue_t* queue; | ||
685 | @@ -396,22 +393,27 @@ int hashbin_delete( hashbin_t* hashbin, FREE_FUNC free_func) | ||
686 | IRDA_ASSERT(hashbin->magic == HB_MAGIC, return -1;); | ||
687 | |||
688 | /* Synchronize */ | ||
689 | - if ( hashbin->hb_type & HB_LOCK ) { | ||
690 | - spin_lock_irqsave_nested(&hashbin->hb_spinlock, flags, | ||
691 | - hashbin_lock_depth++); | ||
692 | - } | ||
693 | + if (hashbin->hb_type & HB_LOCK) | ||
694 | + spin_lock_irqsave(&hashbin->hb_spinlock, flags); | ||
695 | |||
696 | /* | ||
697 | * Free the entries in the hashbin, TODO: use hashbin_clear when | ||
698 | * it has been shown to work | ||
699 | */ | ||
700 | for (i = 0; i < HASHBIN_SIZE; i ++ ) { | ||
701 | - queue = dequeue_first((irda_queue_t**) &hashbin->hb_queue[i]); | ||
702 | - while (queue ) { | ||
703 | - if (free_func) | ||
704 | - (*free_func)(queue); | ||
705 | - queue = dequeue_first( | ||
706 | - (irda_queue_t**) &hashbin->hb_queue[i]); | ||
707 | + while (1) { | ||
708 | + queue = dequeue_first((irda_queue_t**) &hashbin->hb_queue[i]); | ||
709 | + | ||
710 | + if (!queue) | ||
711 | + break; | ||
712 | + | ||
713 | + if (free_func) { | ||
714 | + if (hashbin->hb_type & HB_LOCK) | ||
715 | + spin_unlock_irqrestore(&hashbin->hb_spinlock, flags); | ||
716 | + free_func(queue); | ||
717 | + if (hashbin->hb_type & HB_LOCK) | ||
718 | + spin_lock_irqsave(&hashbin->hb_spinlock, flags); | ||
719 | + } | ||
720 | } | ||
721 | } | ||
722 | |||
723 | @@ -420,12 +422,8 @@ int hashbin_delete( hashbin_t* hashbin, FREE_FUNC free_func) | ||
724 | hashbin->magic = ~HB_MAGIC; | ||
725 | |||
726 | /* Release lock */ | ||
727 | - if ( hashbin->hb_type & HB_LOCK) { | ||
728 | + if (hashbin->hb_type & HB_LOCK) | ||
729 | spin_unlock_irqrestore(&hashbin->hb_spinlock, flags); | ||
730 | -#ifdef CONFIG_LOCKDEP | ||
731 | - hashbin_lock_depth--; | ||
732 | -#endif | ||
733 | - } | ||
734 | |||
735 | /* | ||
736 | * Free the hashbin structure | ||
737 | diff --git a/net/kcm/kcmsock.c b/net/kcm/kcmsock.c | ||
738 | index 7e08a4d3d77d..a646f3481240 100644 | ||
739 | --- a/net/kcm/kcmsock.c | ||
740 | +++ b/net/kcm/kcmsock.c | ||
741 | @@ -929,23 +929,25 @@ static int kcm_sendmsg(struct socket *sock, struct msghdr *msg, size_t len) | ||
742 | goto out_error; | ||
743 | } | ||
744 | |||
745 | - /* New message, alloc head skb */ | ||
746 | - head = alloc_skb(0, sk->sk_allocation); | ||
747 | - while (!head) { | ||
748 | - kcm_push(kcm); | ||
749 | - err = sk_stream_wait_memory(sk, &timeo); | ||
750 | - if (err) | ||
751 | - goto out_error; | ||
752 | - | ||
753 | + if (msg_data_left(msg)) { | ||
754 | + /* New message, alloc head skb */ | ||
755 | head = alloc_skb(0, sk->sk_allocation); | ||
756 | - } | ||
757 | + while (!head) { | ||
758 | + kcm_push(kcm); | ||
759 | + err = sk_stream_wait_memory(sk, &timeo); | ||
760 | + if (err) | ||
761 | + goto out_error; | ||
762 | |||
763 | - skb = head; | ||
764 | + head = alloc_skb(0, sk->sk_allocation); | ||
765 | + } | ||
766 | |||
767 | - /* Set ip_summed to CHECKSUM_UNNECESSARY to avoid calling | ||
768 | - * csum_and_copy_from_iter from skb_do_copy_data_nocache. | ||
769 | - */ | ||
770 | - skb->ip_summed = CHECKSUM_UNNECESSARY; | ||
771 | + skb = head; | ||
772 | + | ||
773 | + /* Set ip_summed to CHECKSUM_UNNECESSARY to avoid calling | ||
774 | + * csum_and_copy_from_iter from skb_do_copy_data_nocache. | ||
775 | + */ | ||
776 | + skb->ip_summed = CHECKSUM_UNNECESSARY; | ||
777 | + } | ||
778 | |||
779 | start: | ||
780 | while (msg_data_left(msg)) { | ||
781 | @@ -1018,10 +1020,12 @@ static int kcm_sendmsg(struct socket *sock, struct msghdr *msg, size_t len) | ||
782 | if (eor) { | ||
783 | bool not_busy = skb_queue_empty(&sk->sk_write_queue); | ||
784 | |||
785 | - /* Message complete, queue it on send buffer */ | ||
786 | - __skb_queue_tail(&sk->sk_write_queue, head); | ||
787 | - kcm->seq_skb = NULL; | ||
788 | - KCM_STATS_INCR(kcm->stats.tx_msgs); | ||
789 | + if (head) { | ||
790 | + /* Message complete, queue it on send buffer */ | ||
791 | + __skb_queue_tail(&sk->sk_write_queue, head); | ||
792 | + kcm->seq_skb = NULL; | ||
793 | + KCM_STATS_INCR(kcm->stats.tx_msgs); | ||
794 | + } | ||
795 | |||
796 | if (msg->msg_flags & MSG_BATCH) { | ||
797 | kcm->tx_wait_more = true; | ||
798 | @@ -1040,8 +1044,10 @@ static int kcm_sendmsg(struct socket *sock, struct msghdr *msg, size_t len) | ||
799 | } else { | ||
800 | /* Message not complete, save state */ | ||
801 | partial_message: | ||
802 | - kcm->seq_skb = head; | ||
803 | - kcm_tx_msg(head)->last_skb = skb; | ||
804 | + if (head) { | ||
805 | + kcm->seq_skb = head; | ||
806 | + kcm_tx_msg(head)->last_skb = skb; | ||
807 | + } | ||
808 | } | ||
809 | |||
810 | KCM_STATS_ADD(kcm->stats.tx_bytes, copied); | ||
811 | diff --git a/net/llc/llc_conn.c b/net/llc/llc_conn.c | ||
812 | index 3e821daf9dd4..8bc5a1bd2d45 100644 | ||
813 | --- a/net/llc/llc_conn.c | ||
814 | +++ b/net/llc/llc_conn.c | ||
815 | @@ -821,7 +821,10 @@ void llc_conn_handler(struct llc_sap *sap, struct sk_buff *skb) | ||
816 | * another trick required to cope with how the PROCOM state | ||
817 | * machine works. -acme | ||
818 | */ | ||
819 | + skb_orphan(skb); | ||
820 | + sock_hold(sk); | ||
821 | skb->sk = sk; | ||
822 | + skb->destructor = sock_efree; | ||
823 | } | ||
824 | if (!sock_owned_by_user(sk)) | ||
825 | llc_conn_rcv(sk, skb); | ||
826 | diff --git a/net/llc/llc_sap.c b/net/llc/llc_sap.c | ||
827 | index d0e1e804ebd7..5404d0d195cc 100644 | ||
828 | --- a/net/llc/llc_sap.c | ||
829 | +++ b/net/llc/llc_sap.c | ||
830 | @@ -290,7 +290,10 @@ static void llc_sap_rcv(struct llc_sap *sap, struct sk_buff *skb, | ||
831 | |||
832 | ev->type = LLC_SAP_EV_TYPE_PDU; | ||
833 | ev->reason = 0; | ||
834 | + skb_orphan(skb); | ||
835 | + sock_hold(sk); | ||
836 | skb->sk = sk; | ||
837 | + skb->destructor = sock_efree; | ||
838 | llc_sap_state_process(sap, skb); | ||
839 | } | ||
840 | |||
841 | diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c | ||
842 | index 7341adf7059d..6dc44d9b4190 100644 | ||
843 | --- a/net/netfilter/nf_conntrack_helper.c | ||
844 | +++ b/net/netfilter/nf_conntrack_helper.c | ||
845 | @@ -188,6 +188,26 @@ nf_ct_helper_ext_add(struct nf_conn *ct, | ||
846 | } | ||
847 | EXPORT_SYMBOL_GPL(nf_ct_helper_ext_add); | ||
848 | |||
849 | +static struct nf_conntrack_helper * | ||
850 | +nf_ct_lookup_helper(struct nf_conn *ct, struct net *net) | ||
851 | +{ | ||
852 | + if (!net->ct.sysctl_auto_assign_helper) { | ||
853 | + if (net->ct.auto_assign_helper_warned) | ||
854 | + return NULL; | ||
855 | + if (!__nf_ct_helper_find(&ct->tuplehash[IP_CT_DIR_REPLY].tuple)) | ||
856 | + return NULL; | ||
857 | + pr_info("nf_conntrack: default automatic helper assignment " | ||
858 | + "has been turned off for security reasons and CT-based " | ||
859 | + " firewall rule not found. Use the iptables CT target " | ||
860 | + "to attach helpers instead.\n"); | ||
861 | + net->ct.auto_assign_helper_warned = 1; | ||
862 | + return NULL; | ||
863 | + } | ||
864 | + | ||
865 | + return __nf_ct_helper_find(&ct->tuplehash[IP_CT_DIR_REPLY].tuple); | ||
866 | +} | ||
867 | + | ||
868 | + | ||
869 | int __nf_ct_try_assign_helper(struct nf_conn *ct, struct nf_conn *tmpl, | ||
870 | gfp_t flags) | ||
871 | { | ||
872 | @@ -213,21 +233,14 @@ int __nf_ct_try_assign_helper(struct nf_conn *ct, struct nf_conn *tmpl, | ||
873 | } | ||
874 | |||
875 | help = nfct_help(ct); | ||
876 | - if (net->ct.sysctl_auto_assign_helper && helper == NULL) { | ||
877 | - helper = __nf_ct_helper_find(&ct->tuplehash[IP_CT_DIR_REPLY].tuple); | ||
878 | - if (unlikely(!net->ct.auto_assign_helper_warned && helper)) { | ||
879 | - pr_info("nf_conntrack: automatic helper " | ||
880 | - "assignment is deprecated and it will " | ||
881 | - "be removed soon. Use the iptables CT target " | ||
882 | - "to attach helpers instead.\n"); | ||
883 | - net->ct.auto_assign_helper_warned = true; | ||
884 | - } | ||
885 | - } | ||
886 | |||
887 | if (helper == NULL) { | ||
888 | - if (help) | ||
889 | - RCU_INIT_POINTER(help->helper, NULL); | ||
890 | - return 0; | ||
891 | + helper = nf_ct_lookup_helper(ct, net); | ||
892 | + if (helper == NULL) { | ||
893 | + if (help) | ||
894 | + RCU_INIT_POINTER(help->helper, NULL); | ||
895 | + return 0; | ||
896 | + } | ||
897 | } | ||
898 | |||
899 | if (help == NULL) { | ||
900 | diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c | ||
901 | index 458722b938c7..34de326b4f09 100644 | ||
902 | --- a/net/packet/af_packet.c | ||
903 | +++ b/net/packet/af_packet.c | ||
904 | @@ -1497,6 +1497,8 @@ static void __fanout_link(struct sock *sk, struct packet_sock *po) | ||
905 | f->arr[f->num_members] = sk; | ||
906 | smp_wmb(); | ||
907 | f->num_members++; | ||
908 | + if (f->num_members == 1) | ||
909 | + dev_add_pack(&f->prot_hook); | ||
910 | spin_unlock(&f->lock); | ||
911 | } | ||
912 | |||
913 | @@ -1513,6 +1515,8 @@ static void __fanout_unlink(struct sock *sk, struct packet_sock *po) | ||
914 | BUG_ON(i >= f->num_members); | ||
915 | f->arr[i] = f->arr[f->num_members - 1]; | ||
916 | f->num_members--; | ||
917 | + if (f->num_members == 0) | ||
918 | + __dev_remove_pack(&f->prot_hook); | ||
919 | spin_unlock(&f->lock); | ||
920 | } | ||
921 | |||
922 | @@ -1619,6 +1623,7 @@ static void fanout_release_data(struct packet_fanout *f) | ||
923 | |||
924 | static int fanout_add(struct sock *sk, u16 id, u16 type_flags) | ||
925 | { | ||
926 | + struct packet_rollover *rollover = NULL; | ||
927 | struct packet_sock *po = pkt_sk(sk); | ||
928 | struct packet_fanout *f, *match; | ||
929 | u8 type = type_flags & 0xff; | ||
930 | @@ -1641,23 +1646,28 @@ static int fanout_add(struct sock *sk, u16 id, u16 type_flags) | ||
931 | return -EINVAL; | ||
932 | } | ||
933 | |||
934 | + mutex_lock(&fanout_mutex); | ||
935 | + | ||
936 | + err = -EINVAL; | ||
937 | if (!po->running) | ||
938 | - return -EINVAL; | ||
939 | + goto out; | ||
940 | |||
941 | + err = -EALREADY; | ||
942 | if (po->fanout) | ||
943 | - return -EALREADY; | ||
944 | + goto out; | ||
945 | |||
946 | if (type == PACKET_FANOUT_ROLLOVER || | ||
947 | (type_flags & PACKET_FANOUT_FLAG_ROLLOVER)) { | ||
948 | - po->rollover = kzalloc(sizeof(*po->rollover), GFP_KERNEL); | ||
949 | - if (!po->rollover) | ||
950 | - return -ENOMEM; | ||
951 | - atomic_long_set(&po->rollover->num, 0); | ||
952 | - atomic_long_set(&po->rollover->num_huge, 0); | ||
953 | - atomic_long_set(&po->rollover->num_failed, 0); | ||
954 | + err = -ENOMEM; | ||
955 | + rollover = kzalloc(sizeof(*rollover), GFP_KERNEL); | ||
956 | + if (!rollover) | ||
957 | + goto out; | ||
958 | + atomic_long_set(&rollover->num, 0); | ||
959 | + atomic_long_set(&rollover->num_huge, 0); | ||
960 | + atomic_long_set(&rollover->num_failed, 0); | ||
961 | + po->rollover = rollover; | ||
962 | } | ||
963 | |||
964 | - mutex_lock(&fanout_mutex); | ||
965 | match = NULL; | ||
966 | list_for_each_entry(f, &fanout_list, list) { | ||
967 | if (f->id == id && | ||
968 | @@ -1687,7 +1697,6 @@ static int fanout_add(struct sock *sk, u16 id, u16 type_flags) | ||
969 | match->prot_hook.func = packet_rcv_fanout; | ||
970 | match->prot_hook.af_packet_priv = match; | ||
971 | match->prot_hook.id_match = match_fanout_group; | ||
972 | - dev_add_pack(&match->prot_hook); | ||
973 | list_add(&match->list, &fanout_list); | ||
974 | } | ||
975 | err = -EINVAL; | ||
976 | @@ -1704,36 +1713,40 @@ static int fanout_add(struct sock *sk, u16 id, u16 type_flags) | ||
977 | } | ||
978 | } | ||
979 | out: | ||
980 | - mutex_unlock(&fanout_mutex); | ||
981 | - if (err) { | ||
982 | - kfree(po->rollover); | ||
983 | + if (err && rollover) { | ||
984 | + kfree(rollover); | ||
985 | po->rollover = NULL; | ||
986 | } | ||
987 | + mutex_unlock(&fanout_mutex); | ||
988 | return err; | ||
989 | } | ||
990 | |||
991 | -static void fanout_release(struct sock *sk) | ||
992 | +/* If pkt_sk(sk)->fanout->sk_ref is zero, this function removes | ||
993 | + * pkt_sk(sk)->fanout from fanout_list and returns pkt_sk(sk)->fanout. | ||
994 | + * It is the responsibility of the caller to call fanout_release_data() and | ||
995 | + * free the returned packet_fanout (after synchronize_net()) | ||
996 | + */ | ||
997 | +static struct packet_fanout *fanout_release(struct sock *sk) | ||
998 | { | ||
999 | struct packet_sock *po = pkt_sk(sk); | ||
1000 | struct packet_fanout *f; | ||
1001 | |||
1002 | + mutex_lock(&fanout_mutex); | ||
1003 | f = po->fanout; | ||
1004 | - if (!f) | ||
1005 | - return; | ||
1006 | + if (f) { | ||
1007 | + po->fanout = NULL; | ||
1008 | |||
1009 | - mutex_lock(&fanout_mutex); | ||
1010 | - po->fanout = NULL; | ||
1011 | + if (atomic_dec_and_test(&f->sk_ref)) | ||
1012 | + list_del(&f->list); | ||
1013 | + else | ||
1014 | + f = NULL; | ||
1015 | |||
1016 | - if (atomic_dec_and_test(&f->sk_ref)) { | ||
1017 | - list_del(&f->list); | ||
1018 | - dev_remove_pack(&f->prot_hook); | ||
1019 | - fanout_release_data(f); | ||
1020 | - kfree(f); | ||
1021 | + if (po->rollover) | ||
1022 | + kfree_rcu(po->rollover, rcu); | ||
1023 | } | ||
1024 | mutex_unlock(&fanout_mutex); | ||
1025 | |||
1026 | - if (po->rollover) | ||
1027 | - kfree_rcu(po->rollover, rcu); | ||
1028 | + return f; | ||
1029 | } | ||
1030 | |||
1031 | static bool packet_extra_vlan_len_allowed(const struct net_device *dev, | ||
1032 | @@ -2965,6 +2978,7 @@ static int packet_release(struct socket *sock) | ||
1033 | { | ||
1034 | struct sock *sk = sock->sk; | ||
1035 | struct packet_sock *po; | ||
1036 | + struct packet_fanout *f; | ||
1037 | struct net *net; | ||
1038 | union tpacket_req_u req_u; | ||
1039 | |||
1040 | @@ -3004,9 +3018,14 @@ static int packet_release(struct socket *sock) | ||
1041 | packet_set_ring(sk, &req_u, 1, 1); | ||
1042 | } | ||
1043 | |||
1044 | - fanout_release(sk); | ||
1045 | + f = fanout_release(sk); | ||
1046 | |||
1047 | synchronize_net(); | ||
1048 | + | ||
1049 | + if (f) { | ||
1050 | + fanout_release_data(f); | ||
1051 | + kfree(f); | ||
1052 | + } | ||
1053 | /* | ||
1054 | * Now the socket is dead. No more input will appear. | ||
1055 | */ | ||
1056 | @@ -3958,7 +3977,6 @@ static int packet_notifier(struct notifier_block *this, | ||
1057 | } | ||
1058 | if (msg == NETDEV_UNREGISTER) { | ||
1059 | packet_cached_dev_reset(po); | ||
1060 | - fanout_release(sk); | ||
1061 | po->ifindex = -1; | ||
1062 | if (po->prot_hook.dev) | ||
1063 | dev_put(po->prot_hook.dev); | ||
1064 | diff --git a/net/socket.c b/net/socket.c | ||
1065 | index 73dc69f9681e..6bbccf05854f 100644 | ||
1066 | --- a/net/socket.c | ||
1067 | +++ b/net/socket.c | ||
1068 | @@ -2197,8 +2197,10 @@ int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, | ||
1069 | return err; | ||
1070 | |||
1071 | err = sock_error(sock->sk); | ||
1072 | - if (err) | ||
1073 | + if (err) { | ||
1074 | + datagrams = err; | ||
1075 | goto out_put; | ||
1076 | + } | ||
1077 | |||
1078 | entry = mmsg; | ||
1079 | compat_entry = (struct compat_mmsghdr __user *)mmsg; |