From: Greg Kroah-Hartman Date: Fri, 17 Apr 2015 10:05:22 +0000 (+0200) Subject: 3.14-stable patches X-Git-Tag: v3.10.75~22 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=fa7eabcc3009735833e03485c674b81813d6cf06;p=thirdparty%2Fkernel%2Fstable-queue.git 3.14-stable patches added patches: btrfs-simplify-insert_orphan_item.patch ib-core-avoid-leakage-from-kernel-to-user-space.patch ib-uverbs-prevent-integer-overflow-in-ib_umem_get-address-arithmetic.patch iwlwifi-dvm-run-init-firmware-again-upon-.start.patch mm-memory-hotplug-postpone-the-reset-of-obsolete-pgdat.patch nbd-fix-possible-memory-leak.patch radeon-do-not-directly-dereference-pointers-to-bios-area.patch sched-fix-rlimit_rttime-when-pi-boosting-to-rt.patch tcp-fix-crash-in-tcp-fast-open.patch writeback-add-missing-initial_jiffies-init-in-global_update_bandwidth.patch writeback-fix-possible-underflow-in-write-bandwidth-calculation.patch --- diff --git a/queue-3.14/btrfs-simplify-insert_orphan_item.patch b/queue-3.14/btrfs-simplify-insert_orphan_item.patch new file mode 100644 index 00000000000..5d27ef2eea4 --- /dev/null +++ b/queue-3.14/btrfs-simplify-insert_orphan_item.patch @@ -0,0 +1,50 @@ +From 9c4f61f01d269815bb7c37be3ede59c5587747c6 Mon Sep 17 00:00:00 2001 +From: David Sterba +Date: Fri, 2 Jan 2015 19:12:57 +0100 +Subject: btrfs: simplify insert_orphan_item + +From: David Sterba + +commit 9c4f61f01d269815bb7c37be3ede59c5587747c6 upstream. + +We can search and add the orphan item in one go, +btrfs_insert_orphan_item will find out if the item already exists. + +Signed-off-by: David Sterba +Cc: Chris Mason +Cc: Roman Mamedov +Signed-off-by: Greg Kroah-Hartman + + +--- + fs/btrfs/tree-log.c | 16 ++++------------ + 1 file changed, 4 insertions(+), 12 deletions(-) + +--- a/fs/btrfs/tree-log.c ++++ b/fs/btrfs/tree-log.c +@@ -1235,21 +1235,13 @@ out: + } + + static int insert_orphan_item(struct btrfs_trans_handle *trans, +- struct btrfs_root *root, u64 offset) ++ struct btrfs_root *root, u64 ino) + { + int ret; +- struct btrfs_path *path; + +- path = btrfs_alloc_path(); +- if (!path) +- return -ENOMEM; +- +- ret = btrfs_find_item(root, path, BTRFS_ORPHAN_OBJECTID, +- offset, BTRFS_ORPHAN_ITEM_KEY, NULL); +- if (ret > 0) +- ret = btrfs_insert_orphan_item(trans, root, offset); +- +- btrfs_free_path(path); ++ ret = btrfs_insert_orphan_item(trans, root, ino); ++ if (ret == -EEXIST) ++ ret = 0; + + return ret; + } diff --git a/queue-3.14/ib-core-avoid-leakage-from-kernel-to-user-space.patch b/queue-3.14/ib-core-avoid-leakage-from-kernel-to-user-space.patch new file mode 100644 index 00000000000..743b5290cee --- /dev/null +++ b/queue-3.14/ib-core-avoid-leakage-from-kernel-to-user-space.patch @@ -0,0 +1,31 @@ +From 377b513485fd885dea1083a9a5430df65b35e048 Mon Sep 17 00:00:00 2001 +From: Eli Cohen +Date: Sun, 14 Sep 2014 16:47:52 +0300 +Subject: IB/core: Avoid leakage from kernel to user space + +From: Eli Cohen + +commit 377b513485fd885dea1083a9a5430df65b35e048 upstream. + +Clear the reserved field of struct ib_uverbs_async_event_desc which is +copied to user space. + +Signed-off-by: Eli Cohen +Reviewed-by: Yann Droneaud +Signed-off-by: Roland Dreier +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/core/uverbs_main.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/infiniband/core/uverbs_main.c ++++ b/drivers/infiniband/core/uverbs_main.c +@@ -476,6 +476,7 @@ static void ib_uverbs_async_handler(stru + + entry->desc.async.element = element; + entry->desc.async.event_type = event; ++ entry->desc.async.reserved = 0; + entry->counter = counter; + + list_add_tail(&entry->list, &file->async_file->event_list); diff --git a/queue-3.14/ib-uverbs-prevent-integer-overflow-in-ib_umem_get-address-arithmetic.patch b/queue-3.14/ib-uverbs-prevent-integer-overflow-in-ib_umem_get-address-arithmetic.patch new file mode 100644 index 00000000000..24fd8784c7d --- /dev/null +++ b/queue-3.14/ib-uverbs-prevent-integer-overflow-in-ib_umem_get-address-arithmetic.patch @@ -0,0 +1,47 @@ +From 8494057ab5e40df590ef6ef7d66324d3ae33356b Mon Sep 17 00:00:00 2001 +From: Shachar Raindel +Date: Wed, 18 Mar 2015 17:39:08 +0000 +Subject: IB/uverbs: Prevent integer overflow in ib_umem_get address arithmetic + +From: Shachar Raindel + +commit 8494057ab5e40df590ef6ef7d66324d3ae33356b upstream. + +Properly verify that the resulting page aligned end address is larger +than both the start address and the length of the memory area requested. + +Both the start and length arguments for ib_umem_get are controlled by +the user. A misbehaving user can provide values which will cause an +integer overflow when calculating the page aligned end address. + +This overflow can cause also miscalculation of the number of pages +mapped, and additional logic issues. + +Addresses: CVE-2014-8159 +Signed-off-by: Shachar Raindel +Signed-off-by: Jack Morgenstein +Signed-off-by: Or Gerlitz +Signed-off-by: Roland Dreier +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/core/umem.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/drivers/infiniband/core/umem.c ++++ b/drivers/infiniband/core/umem.c +@@ -94,6 +94,14 @@ struct ib_umem *ib_umem_get(struct ib_uc + if (dmasync) + dma_set_attr(DMA_ATTR_WRITE_BARRIER, &attrs); + ++ /* ++ * If the combination of the addr and size requested for this memory ++ * region causes an integer overflow, return error. ++ */ ++ if ((PAGE_ALIGN(addr + size) <= size) || ++ (PAGE_ALIGN(addr + size) <= addr)) ++ return ERR_PTR(-EINVAL); ++ + if (!can_do_mlock()) + return ERR_PTR(-EPERM); + diff --git a/queue-3.14/iwlwifi-dvm-run-init-firmware-again-upon-.start.patch b/queue-3.14/iwlwifi-dvm-run-init-firmware-again-upon-.start.patch new file mode 100644 index 00000000000..d3bd0a14b8b --- /dev/null +++ b/queue-3.14/iwlwifi-dvm-run-init-firmware-again-upon-.start.patch @@ -0,0 +1,58 @@ +From 9c8928f5176766bec79f272bd47b7124e11cccbd Mon Sep 17 00:00:00 2001 +From: Emmanuel Grumbach +Date: Mon, 16 Mar 2015 09:08:07 +0200 +Subject: iwlwifi: dvm: run INIT firmware again upon .start() + +From: Emmanuel Grumbach + +commit 9c8928f5176766bec79f272bd47b7124e11cccbd upstream. + +The assumption before this patch was that we don't need to +run again the INIT firmware after the system booted. The +INIT firmware runs calibrations which impact the physical +layer's behavior. +Users reported that it may be helpful to run these +calibrations again every time the interface is brought up. +The penatly is minimal, since the calibrations run fast. +This fixes: +https://bugzilla.kernel.org/show_bug.cgi?id=94341 + +Signed-off-by: Emmanuel Grumbach +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/iwlwifi/dvm/dev.h | 1 - + drivers/net/wireless/iwlwifi/dvm/ucode.c | 5 ----- + 2 files changed, 6 deletions(-) + +--- a/drivers/net/wireless/iwlwifi/dvm/dev.h ++++ b/drivers/net/wireless/iwlwifi/dvm/dev.h +@@ -708,7 +708,6 @@ struct iwl_priv { + unsigned long reload_jiffies; + int reload_count; + bool ucode_loaded; +- bool init_ucode_run; /* Don't run init uCode again */ + + u8 plcp_delta_threshold; + +--- a/drivers/net/wireless/iwlwifi/dvm/ucode.c ++++ b/drivers/net/wireless/iwlwifi/dvm/ucode.c +@@ -418,9 +418,6 @@ int iwl_run_init_ucode(struct iwl_priv * + if (!priv->fw->img[IWL_UCODE_INIT].sec[0].len) + return 0; + +- if (priv->init_ucode_run) +- return 0; +- + iwl_init_notification_wait(&priv->notif_wait, &calib_wait, + calib_complete, ARRAY_SIZE(calib_complete), + iwlagn_wait_calib, priv); +@@ -440,8 +437,6 @@ int iwl_run_init_ucode(struct iwl_priv * + */ + ret = iwl_wait_notification(&priv->notif_wait, &calib_wait, + UCODE_CALIB_TIMEOUT); +- if (!ret) +- priv->init_ucode_run = true; + + goto out; + diff --git a/queue-3.14/mm-memory-hotplug-postpone-the-reset-of-obsolete-pgdat.patch b/queue-3.14/mm-memory-hotplug-postpone-the-reset-of-obsolete-pgdat.patch new file mode 100644 index 00000000000..9db4535f8fc --- /dev/null +++ b/queue-3.14/mm-memory-hotplug-postpone-the-reset-of-obsolete-pgdat.patch @@ -0,0 +1,111 @@ +From b0dc3a342af36f95a68fe229b8f0f73552c5ca08 Mon Sep 17 00:00:00 2001 +From: Gu Zheng +Date: Wed, 25 Mar 2015 15:55:20 -0700 +Subject: mm/memory hotplug: postpone the reset of obsolete pgdat + +From: Gu Zheng + +commit b0dc3a342af36f95a68fe229b8f0f73552c5ca08 upstream. + +Qiu Xishi reported the following BUG when testing hot-add/hot-remove node under +stress condition: + + BUG: unable to handle kernel paging request at 0000000000025f60 + IP: next_online_pgdat+0x1/0x50 + PGD 0 + Oops: 0000 [#1] SMP + ACPI: Device does not support D3cold + Modules linked in: fuse nls_iso8859_1 nls_cp437 vfat fat loop dm_mod coretemp mperf crc32c_intel ghash_clmulni_intel aesni_intel ablk_helper cryptd lrw gf128mul glue_helper aes_x86_64 pcspkr microcode igb dca i2c_algo_bit ipv6 megaraid_sas iTCO_wdt i2c_i801 i2c_core iTCO_vendor_support tg3 sg hwmon ptp lpc_ich pps_core mfd_core acpi_pad rtc_cmos button ext3 jbd mbcache sd_mod crc_t10dif scsi_dh_alua scsi_dh_rdac scsi_dh_hp_sw scsi_dh_emc scsi_dh ahci libahci libata scsi_mod [last unloaded: rasf] + CPU: 23 PID: 238 Comm: kworker/23:1 Tainted: G O 3.10.15-5885-euler0302 #1 + Hardware name: HUAWEI TECHNOLOGIES CO.,LTD. Huawei N1/Huawei N1, BIOS V100R001 03/02/2015 + Workqueue: events vmstat_update + task: ffffa800d32c0000 ti: ffffa800d32ae000 task.ti: ffffa800d32ae000 + RIP: 0010: next_online_pgdat+0x1/0x50 + RSP: 0018:ffffa800d32afce8 EFLAGS: 00010286 + RAX: 0000000000001440 RBX: ffffffff81da53b8 RCX: 0000000000000082 + RDX: 0000000000000000 RSI: 0000000000000082 RDI: 0000000000000000 + RBP: ffffa800d32afd28 R08: ffffffff81c93bfc R09: ffffffff81cbdc96 + R10: 00000000000040ec R11: 00000000000000a0 R12: ffffa800fffb3440 + R13: ffffa800d32afd38 R14: 0000000000000017 R15: ffffa800e6616800 + FS: 0000000000000000(0000) GS:ffffa800e6600000(0000) knlGS:0000000000000000 + CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 + CR2: 0000000000025f60 CR3: 0000000001a0b000 CR4: 00000000001407e0 + DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 + DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 + Call Trace: + refresh_cpu_vm_stats+0xd0/0x140 + vmstat_update+0x11/0x50 + process_one_work+0x194/0x3d0 + worker_thread+0x12b/0x410 + kthread+0xc6/0xd0 + ret_from_fork+0x7c/0xb0 + +The cause is the "memset(pgdat, 0, sizeof(*pgdat))" at the end of +try_offline_node, which will reset all the content of pgdat to 0, as the +pgdat is accessed lock-free, so that the users still using the pgdat +will panic, such as the vmstat_update routine. + +process A: offline node XX: + +vmstat_updat() + refresh_cpu_vm_stats() + for_each_populated_zone() + find online node XX + cond_resched() + offline cpu and memory, then try_offline_node() + node_set_offline(nid), and memset(pgdat, 0, sizeof(*pgdat)) + zone = next_zone(zone) + pg_data_t *pgdat = zone->zone_pgdat; // here pgdat is NULL now + next_online_pgdat(pgdat) + next_online_node(pgdat->node_id); // NULL pointer access + +So the solution here is postponing the reset of obsolete pgdat from +try_offline_node() to hotadd_new_pgdat(), and just resetting +pgdat->nr_zones and pgdat->classzone_idx to be 0 rather than the memset +0 to avoid breaking pointer information in pgdat. + +Signed-off-by: Gu Zheng +Reported-by: Xishi Qiu +Suggested-by: KAMEZAWA Hiroyuki +Cc: David Rientjes +Cc: Yasuaki Ishimatsu +Cc: Taku Izumi +Cc: Tang Chen +Cc: Xie XiuQi +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + mm/memory_hotplug.c | 13 ++++--------- + 1 file changed, 4 insertions(+), 9 deletions(-) + +--- a/mm/memory_hotplug.c ++++ b/mm/memory_hotplug.c +@@ -1016,6 +1016,10 @@ static pg_data_t __ref *hotadd_new_pgdat + return NULL; + + arch_refresh_nodedata(nid, pgdat); ++ } else { ++ /* Reset the nr_zones and classzone_idx to 0 before reuse */ ++ pgdat->nr_zones = 0; ++ pgdat->classzone_idx = 0; + } + + /* we can use NODE_DATA(nid) from here */ +@@ -1863,15 +1867,6 @@ void try_offline_node(int nid) + if (is_vmalloc_addr(zone->wait_table)) + vfree(zone->wait_table); + } +- +- /* +- * Since there is no way to guarentee the address of pgdat/zone is not +- * on stack of any kernel threads or used by other kernel objects +- * without reference counting or other symchronizing method, do not +- * reset node_data and free pgdat here. Just reset it to 0 and reuse +- * the memory when the node is online again. +- */ +- memset(pgdat, 0, sizeof(*pgdat)); + } + EXPORT_SYMBOL(try_offline_node); + diff --git a/queue-3.14/nbd-fix-possible-memory-leak.patch b/queue-3.14/nbd-fix-possible-memory-leak.patch new file mode 100644 index 00000000000..730540c2dd4 --- /dev/null +++ b/queue-3.14/nbd-fix-possible-memory-leak.patch @@ -0,0 +1,45 @@ +From ff6b8090e26ef7649ef0cc6b42389141ef48b0cf Mon Sep 17 00:00:00 2001 +From: Sudip Mukherjee +Date: Tue, 27 Jan 2015 18:08:22 +0530 +Subject: nbd: fix possible memory leak + +From: Sudip Mukherjee + +commit ff6b8090e26ef7649ef0cc6b42389141ef48b0cf upstream. + +we have already allocated memory for nbd_dev, but we were not +releasing that memory and just returning the error value. + +Signed-off-by: Sudip Mukherjee +Acked-by: Paul Clements +Signed-off-by: Markus Pargmann +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/block/nbd.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/block/nbd.c ++++ b/drivers/block/nbd.c +@@ -814,10 +814,6 @@ static int __init nbd_init(void) + return -EINVAL; + } + +- nbd_dev = kcalloc(nbds_max, sizeof(*nbd_dev), GFP_KERNEL); +- if (!nbd_dev) +- return -ENOMEM; +- + part_shift = 0; + if (max_part > 0) { + part_shift = fls(max_part); +@@ -839,6 +835,10 @@ static int __init nbd_init(void) + if (nbds_max > 1UL << (MINORBITS - part_shift)) + return -EINVAL; + ++ nbd_dev = kcalloc(nbds_max, sizeof(*nbd_dev), GFP_KERNEL); ++ if (!nbd_dev) ++ return -ENOMEM; ++ + for (i = 0; i < nbds_max; i++) { + struct gendisk *disk = alloc_disk(1 << part_shift); + if (!disk) diff --git a/queue-3.14/radeon-do-not-directly-dereference-pointers-to-bios-area.patch b/queue-3.14/radeon-do-not-directly-dereference-pointers-to-bios-area.patch new file mode 100644 index 00000000000..b47caada00a --- /dev/null +++ b/queue-3.14/radeon-do-not-directly-dereference-pointers-to-bios-area.patch @@ -0,0 +1,56 @@ +From f2c9e560b406f2f6b14b345c7da33467dee9cdf2 Mon Sep 17 00:00:00 2001 +From: David Miller +Date: Wed, 18 Mar 2015 23:18:40 -0400 +Subject: radeon: Do not directly dereference pointers to BIOS area. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: David Miller + +commit f2c9e560b406f2f6b14b345c7da33467dee9cdf2 upstream. + +Use readb() and memcpy_fromio() accessors instead. + +Reviewed-by: Christian König +Signed-off-by: David S. Miller +Signed-off-by: Alex Deucher +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/radeon/radeon_bios.c | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +--- a/drivers/gpu/drm/radeon/radeon_bios.c ++++ b/drivers/gpu/drm/radeon/radeon_bios.c +@@ -76,7 +76,7 @@ static bool igp_read_bios_from_vram(stru + + static bool radeon_read_bios(struct radeon_device *rdev) + { +- uint8_t __iomem *bios; ++ uint8_t __iomem *bios, val1, val2; + size_t size; + + rdev->bios = NULL; +@@ -86,15 +86,19 @@ static bool radeon_read_bios(struct rade + return false; + } + +- if (size == 0 || bios[0] != 0x55 || bios[1] != 0xaa) { ++ val1 = readb(&bios[0]); ++ val2 = readb(&bios[1]); ++ ++ if (size == 0 || val1 != 0x55 || val2 != 0xaa) { + pci_unmap_rom(rdev->pdev, bios); + return false; + } +- rdev->bios = kmemdup(bios, size, GFP_KERNEL); ++ rdev->bios = kzalloc(size, GFP_KERNEL); + if (rdev->bios == NULL) { + pci_unmap_rom(rdev->pdev, bios); + return false; + } ++ memcpy_fromio(rdev->bios, bios, size); + pci_unmap_rom(rdev->pdev, bios); + return true; + } diff --git a/queue-3.14/sched-fix-rlimit_rttime-when-pi-boosting-to-rt.patch b/queue-3.14/sched-fix-rlimit_rttime-when-pi-boosting-to-rt.patch new file mode 100644 index 00000000000..2a9a67f65ae --- /dev/null +++ b/queue-3.14/sched-fix-rlimit_rttime-when-pi-boosting-to-rt.patch @@ -0,0 +1,47 @@ +From 746db9443ea57fd9c059f62c4bfbf41cf224fe13 Mon Sep 17 00:00:00 2001 +From: Brian Silverman +Date: Wed, 18 Feb 2015 16:23:56 -0800 +Subject: sched: Fix RLIMIT_RTTIME when PI-boosting to RT + +From: Brian Silverman + +commit 746db9443ea57fd9c059f62c4bfbf41cf224fe13 upstream. + +When non-realtime tasks get priority-inheritance boosted to a realtime +scheduling class, RLIMIT_RTTIME starts to apply to them. However, the +counter used for checking this (the same one used for SCHED_RR +timeslices) was not getting reset. This meant that tasks running with a +non-realtime scheduling class which are repeatedly boosted to a realtime +one, but never block while they are running realtime, eventually hit the +timeout without ever running for a time over the limit. This patch +resets the realtime timeslice counter when un-PI-boosting from an RT to +a non-RT scheduling class. + +I have some test code with two threads and a shared PTHREAD_PRIO_INHERIT +mutex which induces priority boosting and spins while boosted that gets +killed by a SIGXCPU on non-fixed kernels but doesn't with this patch +applied. It happens much faster with a CONFIG_PREEMPT_RT kernel, and +does happen eventually with PREEMPT_VOLUNTARY kernels. + +Signed-off-by: Brian Silverman +Signed-off-by: Peter Zijlstra (Intel) +Cc: austin@peloton-tech.com +Link: http://lkml.kernel.org/r/1424305436-6716-1-git-send-email-brian@peloton-tech.com +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/sched/core.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/kernel/sched/core.c ++++ b/kernel/sched/core.c +@@ -2980,6 +2980,8 @@ void rt_mutex_setprio(struct task_struct + } else { + if (dl_prio(oldprio)) + p->dl.dl_boosted = 0; ++ if (rt_prio(oldprio)) ++ p->rt.timeout = 0; + p->sched_class = &fair_sched_class; + } + diff --git a/queue-3.14/series b/queue-3.14/series index 377d8913843..807151e43a9 100644 --- a/queue-3.14/series +++ b/queue-3.14/series @@ -5,3 +5,14 @@ alsa-hda-fix-headphone-pin-config-for-lifebook-t731.patch pci-aer-avoid-info-leak-in-__print_tlp_header.patch arc-sa_siginfo-ucontext-regs-off-by-one.patch selinux-fix-sel_write_enforce-broken-return-value.patch +tcp-fix-crash-in-tcp-fast-open.patch +btrfs-simplify-insert_orphan_item.patch +ib-core-avoid-leakage-from-kernel-to-user-space.patch +ib-uverbs-prevent-integer-overflow-in-ib_umem_get-address-arithmetic.patch +iwlwifi-dvm-run-init-firmware-again-upon-.start.patch +nbd-fix-possible-memory-leak.patch +mm-memory-hotplug-postpone-the-reset-of-obsolete-pgdat.patch +sched-fix-rlimit_rttime-when-pi-boosting-to-rt.patch +writeback-add-missing-initial_jiffies-init-in-global_update_bandwidth.patch +writeback-fix-possible-underflow-in-write-bandwidth-calculation.patch +radeon-do-not-directly-dereference-pointers-to-bios-area.patch diff --git a/queue-3.14/tcp-fix-crash-in-tcp-fast-open.patch b/queue-3.14/tcp-fix-crash-in-tcp-fast-open.patch new file mode 100644 index 00000000000..a4c1903ed02 --- /dev/null +++ b/queue-3.14/tcp-fix-crash-in-tcp-fast-open.patch @@ -0,0 +1,44 @@ +From ben@decadent.org.uk Fri Apr 17 11:41:49 2015 +From: Ben Hutchings +Date: Wed, 15 Apr 2015 19:00:32 +0100 +Subject: tcp: Fix crash in TCP Fast Open +To: stable +Cc: netdev , Eric Dumazet , 782515@bugs.debian.org +Message-ID: <1429120832.3211.91.camel@decadent.org.uk> + +From: Ben Hutchings + +Commit 355a901e6cf1 ("tcp: make connect() mem charging friendly") +changed tcp_send_syn_data() to perform an open-coded copy of the 'syn' +skb rather than using skb_copy_expand(). + +The open-coded copy does not cover the skb_shared_info::gso_segs +field, so in the new skb it is left set to 0. When this commit was +backported into stable branches between 3.10.y and 3.16.7-ckty +inclusive, it triggered the BUG() in tcp_transmit_skb(). + +Since Linux 3.18 the GSO segment count is kept in the +tcp_skb_cb::tcp_gso_segs field and tcp_send_syn_data() does copy the +tcp_skb_cb structure to the new skb, so mainline and newer stable +branches are not affected. + +Set skb_shared_info::gso_segs to the correct value of 1. + +Signed-off-by: Ben Hutchings +Acked-by: Eric Dumazet +Signed-off-by: Greg Kroah-Hartman + +--- + net/ipv4/tcp_output.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/net/ipv4/tcp_output.c ++++ b/net/ipv4/tcp_output.c +@@ -2933,6 +2933,7 @@ static int tcp_send_syn_data(struct sock + goto fallback; + syn_data->ip_summed = CHECKSUM_PARTIAL; + memcpy(syn_data->cb, syn->cb, sizeof(syn->cb)); ++ skb_shinfo(syn_data)->gso_segs = 1; + if (unlikely(memcpy_fromiovecend(skb_put(syn_data, space), + fo->data->msg_iov, 0, space))) { + kfree_skb(syn_data); diff --git a/queue-3.14/writeback-add-missing-initial_jiffies-init-in-global_update_bandwidth.patch b/queue-3.14/writeback-add-missing-initial_jiffies-init-in-global_update_bandwidth.patch new file mode 100644 index 00000000000..8b0ed8a97fe --- /dev/null +++ b/queue-3.14/writeback-add-missing-initial_jiffies-init-in-global_update_bandwidth.patch @@ -0,0 +1,44 @@ +From 7d70e15480c0450d2bfafaad338a32e884fc215e Mon Sep 17 00:00:00 2001 +From: Tejun Heo +Date: Wed, 4 Mar 2015 10:37:43 -0500 +Subject: writeback: add missing INITIAL_JIFFIES init in global_update_bandwidth() + +From: Tejun Heo + +commit 7d70e15480c0450d2bfafaad338a32e884fc215e upstream. + +global_update_bandwidth() uses static variable update_time as the +timestamp for the last update but forgets to initialize it to +INITIALIZE_JIFFIES. + +This means that global_dirty_limit will be 5 mins into the future on +32bit and some large amount jiffies into the past on 64bit. This +isn't critical as the only effect is that global_dirty_limit won't be +updated for the first 5 mins after booting on 32bit machines, +especially given the auxiliary nature of global_dirty_limit's role - +protecting against global dirty threshold's sudden dips; however, it +does lead to unintended suboptimal behavior. Fix it. + +Fixes: c42843f2f0bb ("writeback: introduce smoothed global dirty limit") +Signed-off-by: Tejun Heo +Acked-by: Jan Kara +Cc: Wu Fengguang +Cc: Jens Axboe +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman + +--- + mm/page-writeback.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/mm/page-writeback.c ++++ b/mm/page-writeback.c +@@ -943,7 +943,7 @@ static void global_update_bandwidth(unsi + unsigned long now) + { + static DEFINE_SPINLOCK(dirty_lock); +- static unsigned long update_time; ++ static unsigned long update_time = INITIAL_JIFFIES; + + /* + * check locklessly first to optimize away locking for the most time diff --git a/queue-3.14/writeback-fix-possible-underflow-in-write-bandwidth-calculation.patch b/queue-3.14/writeback-fix-possible-underflow-in-write-bandwidth-calculation.patch new file mode 100644 index 00000000000..251cf1d42b0 --- /dev/null +++ b/queue-3.14/writeback-fix-possible-underflow-in-write-bandwidth-calculation.patch @@ -0,0 +1,56 @@ +From c72efb658f7c8b27ca3d0efb5cfd5ded9fcac89e Mon Sep 17 00:00:00 2001 +From: Tejun Heo +Date: Mon, 23 Mar 2015 00:18:48 -0400 +Subject: writeback: fix possible underflow in write bandwidth calculation + +From: Tejun Heo + +commit c72efb658f7c8b27ca3d0efb5cfd5ded9fcac89e upstream. + +From 1ebf33901ecc75d9496862dceb1ef0377980587c Mon Sep 17 00:00:00 2001 +From: Tejun Heo +Date: Mon, 23 Mar 2015 00:08:19 -0400 + +2f800fbd777b ("writeback: fix dirtied pages accounting on redirty") +introduced account_page_redirty() which reverts stat updates for a +redirtied page, making BDI_DIRTIED no longer monotonically increasing. + +bdi_update_write_bandwidth() uses the delta in BDI_DIRTIED as the +basis for bandwidth calculation. While unlikely, since the above +patch, the newer value may be lower than the recorded past value and +underflow the bandwidth calculation leading to a wild result. + +Fix it by subtracing min of the old and new values when calculating +delta. AFAIK, there hasn't been any report of it happening but the +resulting erratic behavior would be non-critical and temporary, so +it's possible that the issue is happening without being reported. The +risk of the fix is very low, so tagged for -stable. + +Signed-off-by: Tejun Heo +Cc: Jens Axboe +Cc: Jan Kara +Cc: Wu Fengguang +Cc: Greg Thelen +Fixes: 2f800fbd777b ("writeback: fix dirtied pages accounting on redirty") +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman + +--- + mm/page-writeback.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/mm/page-writeback.c ++++ b/mm/page-writeback.c +@@ -878,8 +878,11 @@ static void bdi_update_write_bandwidth(s + * bw * elapsed + write_bandwidth * (period - elapsed) + * write_bandwidth = --------------------------------------------------- + * period ++ * ++ * @written may have decreased due to account_page_redirty(). ++ * Avoid underflowing @bw calculation. + */ +- bw = written - bdi->written_stamp; ++ bw = written - min(written, bdi->written_stamp); + bw *= HZ; + if (unlikely(elapsed > period)) { + do_div(bw, elapsed);