From: Greg Kroah-Hartman Date: Tue, 28 Mar 2017 10:58:20 +0000 (+0200) Subject: 4.9-stable patches X-Git-Tag: v4.4.58~11 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=5d6caaedb6c1db8855a2af0a9d0d91ca1ed8d73d;p=thirdparty%2Fkernel%2Fstable-queue.git 4.9-stable patches added patches: arm-at91-pm-cpu_idle-switch-ddr-to-power-down-mode.patch arm64-kaslr-fix-up-the-kernel-image-alignment.patch auxdisplay-img-ascii-lcd-add-missing-sentinel-entry-in-img_ascii_lcd_matches.patch blk-mq-don-t-complete-un-started-request-in-timeout-handler.patch cgroup-net_cls-iterate-the-fds-of-only-the-tasks-which-are-being-migrated.patch cpufreq-restore-policy-min-max-limits-on-cpu-online.patch drivers-hv-vmbus-don-t-leak-channel-ids.patch drivers-hv-vmbus-don-t-leak-memory-when-a-channel-is-rescinded.patch drm-amdgpu-reinstate-oland-workaround-for-sclk.patch intel_th-don-t-leak-module-refcount-on-failure-to-activate.patch jbd2-don-t-leak-memory-if-setting-up-journal-fails.patch libceph-force-gfp_noio-for-socket-allocations.patch revert-arm-at91-dt-sama5d2-use-new-compatible-for-ohci-node.patch --- diff --git a/queue-4.9/arm-at91-pm-cpu_idle-switch-ddr-to-power-down-mode.patch b/queue-4.9/arm-at91-pm-cpu_idle-switch-ddr-to-power-down-mode.patch new file mode 100644 index 00000000000..b61381caab4 --- /dev/null +++ b/queue-4.9/arm-at91-pm-cpu_idle-switch-ddr-to-power-down-mode.patch @@ -0,0 +1,68 @@ +From 60b89f1928af80b546b5c3fd8714a62f6f4b8844 Mon Sep 17 00:00:00 2001 +From: Nicolas Ferre +Date: Tue, 14 Mar 2017 09:38:04 +0100 +Subject: ARM: at91: pm: cpu_idle: switch DDR to power-down mode + +From: Nicolas Ferre + +commit 60b89f1928af80b546b5c3fd8714a62f6f4b8844 upstream. + +On some DDR controllers, compatible with the sama5d3 one, +the sequence to enter/exit/re-enter the self-refresh mode adds +more constrains than what is currently written in the at91_idle +driver. An actual access to the DDR chip is needed between exit +and re-enter of this mode which is somehow difficult to implement. +This sequence can completely hang the SoC. It is particularly +experienced on parts which embed a L2 cache if the code run +between IDLE calls fits in it... + +Moreover, as the intention is to enter and exit pretty rapidly +from IDLE, the power-down mode is a good candidate. + +So now we use power-down instead of self-refresh. As we can +simplify the code for sama5d3 compatible DDR controllers, +we instantiate a new sama5d3_ddr_standby() function. + +Signed-off-by: Nicolas Ferre +Fixes: 017b5522d5e3 ("ARM: at91: Add new binding for sama5d3-ddramc") +Signed-off-by: Alexandre Belloni +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arm/mach-at91/pm.c | 18 +++++++++++++++++- + 1 file changed, 17 insertions(+), 1 deletion(-) + +--- a/arch/arm/mach-at91/pm.c ++++ b/arch/arm/mach-at91/pm.c +@@ -289,6 +289,22 @@ static void at91_ddr_standby(void) + at91_ramc_write(1, AT91_DDRSDRC_LPR, saved_lpr1); + } + ++static void sama5d3_ddr_standby(void) ++{ ++ u32 lpr0; ++ u32 saved_lpr0; ++ ++ saved_lpr0 = at91_ramc_read(0, AT91_DDRSDRC_LPR); ++ lpr0 = saved_lpr0 & ~AT91_DDRSDRC_LPCB; ++ lpr0 |= AT91_DDRSDRC_LPCB_POWER_DOWN; ++ ++ at91_ramc_write(0, AT91_DDRSDRC_LPR, lpr0); ++ ++ cpu_do_idle(); ++ ++ at91_ramc_write(0, AT91_DDRSDRC_LPR, saved_lpr0); ++} ++ + /* We manage both DDRAM/SDRAM controllers, we need more than one value to + * remember. + */ +@@ -323,7 +339,7 @@ static const struct of_device_id const r + { .compatible = "atmel,at91rm9200-sdramc", .data = at91rm9200_standby }, + { .compatible = "atmel,at91sam9260-sdramc", .data = at91sam9_sdram_standby }, + { .compatible = "atmel,at91sam9g45-ddramc", .data = at91_ddr_standby }, +- { .compatible = "atmel,sama5d3-ddramc", .data = at91_ddr_standby }, ++ { .compatible = "atmel,sama5d3-ddramc", .data = sama5d3_ddr_standby }, + { /*sentinel*/ } + }; + diff --git a/queue-4.9/arm64-kaslr-fix-up-the-kernel-image-alignment.patch b/queue-4.9/arm64-kaslr-fix-up-the-kernel-image-alignment.patch new file mode 100644 index 00000000000..76c9990398c --- /dev/null +++ b/queue-4.9/arm64-kaslr-fix-up-the-kernel-image-alignment.patch @@ -0,0 +1,81 @@ +From afd0e5a876703accb95894f23317a13e2c49b523 Mon Sep 17 00:00:00 2001 +From: Neeraj Upadhyay +Date: Wed, 22 Mar 2017 17:08:25 +0530 +Subject: arm64: kaslr: Fix up the kernel image alignment + +From: Neeraj Upadhyay + +commit afd0e5a876703accb95894f23317a13e2c49b523 upstream. + +If kernel image extends across alignment boundary, existing +code increases the KASLR offset by size of kernel image. The +offset is masked after resizing. There are cases, where after +masking, we may still have kernel image extending across +boundary. This eventually results in only 2MB block getting +mapped while creating the page tables. This results in data aborts +while accessing unmapped regions during second relocation (with +kaslr offset) in __primary_switch. To fix this problem, round up the +kernel image size, by swapper block size, before adding it for +correction. + +For example consider below case, where kernel image still crosses +1GB alignment boundary, after masking the offset, which is fixed +by rounding up kernel image size. + +SWAPPER_TABLE_SHIFT = 30 +Swapper using section maps with section size 2MB. +CONFIG_PGTABLE_LEVELS = 3 +VA_BITS = 39 + +_text : 0xffffff8008080000 +_end : 0xffffff800aa1b000 +offset : 0x1f35600000 +mask = ((1UL << (VA_BITS - 2)) - 1) & ~(SZ_2M - 1) + +(_text + offset) >> SWAPPER_TABLE_SHIFT = 0x3fffffe7c +(_end + offset) >> SWAPPER_TABLE_SHIFT = 0x3fffffe7d + +offset after existing correction (before mask) = 0x1f37f9b000 +(_text + offset) >> SWAPPER_TABLE_SHIFT = 0x3fffffe7d +(_end + offset) >> SWAPPER_TABLE_SHIFT = 0x3fffffe7d + +offset (after mask) = 0x1f37e00000 +(_text + offset) >> SWAPPER_TABLE_SHIFT = 0x3fffffe7c +(_end + offset) >> SWAPPER_TABLE_SHIFT = 0x3fffffe7d + +new offset w/ rounding up = 0x1f38000000 +(_text + offset) >> SWAPPER_TABLE_SHIFT = 0x3fffffe7d +(_end + offset) >> SWAPPER_TABLE_SHIFT = 0x3fffffe7d + +Fixes: f80fb3a3d508 ("arm64: add support for kernel ASLR") +Reviewed-by: Ard Biesheuvel +Signed-off-by: Neeraj Upadhyay +Signed-off-by: Srinivas Ramana +Signed-off-by: Will Deacon +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arm64/kernel/kaslr.c | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +--- a/arch/arm64/kernel/kaslr.c ++++ b/arch/arm64/kernel/kaslr.c +@@ -131,11 +131,15 @@ u64 __init kaslr_early_init(u64 dt_phys, + /* + * The kernel Image should not extend across a 1GB/32MB/512MB alignment + * boundary (for 4KB/16KB/64KB granule kernels, respectively). If this +- * happens, increase the KASLR offset by the size of the kernel image. ++ * happens, increase the KASLR offset by the size of the kernel image ++ * rounded up by SWAPPER_BLOCK_SIZE. + */ + if ((((u64)_text + offset + modulo_offset) >> SWAPPER_TABLE_SHIFT) != +- (((u64)_end + offset + modulo_offset) >> SWAPPER_TABLE_SHIFT)) +- offset = (offset + (u64)(_end - _text)) & mask; ++ (((u64)_end + offset + modulo_offset) >> SWAPPER_TABLE_SHIFT)) { ++ u64 kimg_sz = _end - _text; ++ offset = (offset + round_up(kimg_sz, SWAPPER_BLOCK_SIZE)) ++ & mask; ++ } + + if (IS_ENABLED(CONFIG_KASAN)) + /* diff --git a/queue-4.9/auxdisplay-img-ascii-lcd-add-missing-sentinel-entry-in-img_ascii_lcd_matches.patch b/queue-4.9/auxdisplay-img-ascii-lcd-add-missing-sentinel-entry-in-img_ascii_lcd_matches.patch new file mode 100644 index 00000000000..b02848d05c4 --- /dev/null +++ b/queue-4.9/auxdisplay-img-ascii-lcd-add-missing-sentinel-entry-in-img_ascii_lcd_matches.patch @@ -0,0 +1,31 @@ +From abda288bb207e5c681306299126af8c022709c18 Mon Sep 17 00:00:00 2001 +From: Dmitry Torokhov +Date: Sun, 19 Feb 2017 16:33:35 -0800 +Subject: auxdisplay: img-ascii-lcd: add missing sentinel entry in img_ascii_lcd_matches + +From: Dmitry Torokhov + +commit abda288bb207e5c681306299126af8c022709c18 upstream. + +The OF device table must be terminated, otherwise we'll be walking past it +and into areas unknown. + +Fixes: 0cad855fbd08 ("auxdisplay: img-ascii-lcd: driver for simple ASCII...") +Signed-off-by: Dmitry Torokhov +Tested-by: Fengguang Wu +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/auxdisplay/img-ascii-lcd.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/auxdisplay/img-ascii-lcd.c ++++ b/drivers/auxdisplay/img-ascii-lcd.c +@@ -218,6 +218,7 @@ static const struct of_device_id img_asc + { .compatible = "img,boston-lcd", .data = &boston_config }, + { .compatible = "mti,malta-lcd", .data = &malta_config }, + { .compatible = "mti,sead3-lcd", .data = &sead3_config }, ++ { /* sentinel */ } + }; + + /** diff --git a/queue-4.9/blk-mq-don-t-complete-un-started-request-in-timeout-handler.patch b/queue-4.9/blk-mq-don-t-complete-un-started-request-in-timeout-handler.patch new file mode 100644 index 00000000000..56e680e3b72 --- /dev/null +++ b/queue-4.9/blk-mq-don-t-complete-un-started-request-in-timeout-handler.patch @@ -0,0 +1,154 @@ +From 95a49603707d982b25d17c5b70e220a05556a2f9 Mon Sep 17 00:00:00 2001 +From: Ming Lei +Date: Wed, 22 Mar 2017 10:14:43 +0800 +Subject: blk-mq: don't complete un-started request in timeout handler + +From: Ming Lei + +commit 95a49603707d982b25d17c5b70e220a05556a2f9 upstream. + +When iterating busy requests in timeout handler, +if the STARTED flag of one request isn't set, that means +the request is being processed in block layer or driver, and +isn't submitted to hardware yet. + +In current implementation of blk_mq_check_expired(), +if the request queue becomes dying, un-started requests are +handled as being completed/freed immediately. This way is +wrong, and can cause rq corruption or double allocation[1][2], +when doing I/O and removing&resetting NVMe device at the sametime. + +This patch fixes several issues reported by Yi Zhang. + +[1]. oops log 1 +[ 581.789754] ------------[ cut here ]------------ +[ 581.789758] kernel BUG at block/blk-mq.c:374! +[ 581.789760] invalid opcode: 0000 [#1] SMP +[ 581.789761] Modules linked in: vfat fat ipmi_ssif intel_rapl sb_edac +edac_core x86_pkg_temp_thermal intel_powerclamp coretemp kvm_intel kvm nvme +irqbypass crct10dif_pclmul nvme_core crc32_pclmul ghash_clmulni_intel +intel_cstate ipmi_si mei_me ipmi_devintf intel_uncore sg ipmi_msghandler +intel_rapl_perf iTCO_wdt mei iTCO_vendor_support mxm_wmi lpc_ich dcdbas shpchp +pcspkr acpi_power_meter wmi nfsd auth_rpcgss nfs_acl lockd dm_multipath grace +sunrpc ip_tables xfs libcrc32c sd_mod mgag200 i2c_algo_bit drm_kms_helper +syscopyarea sysfillrect sysimgblt fb_sys_fops ttm drm ahci libahci +crc32c_intel tg3 libata megaraid_sas i2c_core ptp fjes pps_core dm_mirror +dm_region_hash dm_log dm_mod +[ 581.789796] CPU: 1 PID: 1617 Comm: kworker/1:1H Not tainted 4.10.0.bz1420297+ #4 +[ 581.789797] Hardware name: Dell Inc. PowerEdge R730xd/072T6D, BIOS 2.2.5 09/06/2016 +[ 581.789804] Workqueue: kblockd blk_mq_timeout_work +[ 581.789806] task: ffff8804721c8000 task.stack: ffffc90006ee4000 +[ 581.789809] RIP: 0010:blk_mq_end_request+0x58/0x70 +[ 581.789810] RSP: 0018:ffffc90006ee7d50 EFLAGS: 00010202 +[ 581.789811] RAX: 0000000000000001 RBX: ffff8802e4195340 RCX: ffff88028e2f4b88 +[ 581.789812] RDX: 0000000000001000 RSI: 0000000000001000 RDI: 0000000000000000 +[ 581.789813] RBP: ffffc90006ee7d60 R08: 0000000000000003 R09: ffff88028e2f4b00 +[ 581.789814] R10: 0000000000001000 R11: 0000000000000001 R12: 00000000fffffffb +[ 581.789815] R13: ffff88042abe5780 R14: 000000000000002d R15: ffff88046fbdff80 +[ 581.789817] FS: 0000000000000000(0000) GS:ffff88047fc00000(0000) knlGS:0000000000000000 +[ 581.789818] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[ 581.789819] CR2: 00007f64f403a008 CR3: 000000014d078000 CR4: 00000000001406e0 +[ 581.789820] Call Trace: +[ 581.789825] blk_mq_check_expired+0x76/0x80 +[ 581.789828] bt_iter+0x45/0x50 +[ 581.789830] blk_mq_queue_tag_busy_iter+0xdd/0x1f0 +[ 581.789832] ? blk_mq_rq_timed_out+0x70/0x70 +[ 581.789833] ? blk_mq_rq_timed_out+0x70/0x70 +[ 581.789840] ? __switch_to+0x140/0x450 +[ 581.789841] blk_mq_timeout_work+0x88/0x170 +[ 581.789845] process_one_work+0x165/0x410 +[ 581.789847] worker_thread+0x137/0x4c0 +[ 581.789851] kthread+0x101/0x140 +[ 581.789853] ? rescuer_thread+0x3b0/0x3b0 +[ 581.789855] ? kthread_park+0x90/0x90 +[ 581.789860] ret_from_fork+0x2c/0x40 +[ 581.789861] Code: 48 85 c0 74 0d 44 89 e6 48 89 df ff d0 5b 41 5c 5d c3 48 +8b bb 70 01 00 00 48 85 ff 75 0f 48 89 df e8 7d f0 ff ff 5b 41 5c 5d c3 <0f> +0b e8 71 f0 ff ff 90 eb e9 0f 1f 40 00 66 2e 0f 1f 84 00 00 +[ 581.789882] RIP: blk_mq_end_request+0x58/0x70 RSP: ffffc90006ee7d50 +[ 581.789889] ---[ end trace bcaf03d9a14a0a70 ]--- + +[2]. oops log2 +[ 6984.857362] BUG: unable to handle kernel NULL pointer dereference at 0000000000000010 +[ 6984.857372] IP: nvme_queue_rq+0x6e6/0x8cd [nvme] +[ 6984.857373] PGD 0 +[ 6984.857374] +[ 6984.857376] Oops: 0000 [#1] SMP +[ 6984.857379] Modules linked in: ipmi_ssif vfat fat intel_rapl sb_edac +edac_core x86_pkg_temp_thermal intel_powerclamp coretemp kvm_intel kvm +irqbypass crct10dif_pclmul crc32_pclmul ghash_clmulni_intel ipmi_si iTCO_wdt +iTCO_vendor_support mxm_wmi ipmi_devintf intel_cstate sg dcdbas intel_uncore +mei_me intel_rapl_perf mei pcspkr lpc_ich ipmi_msghandler shpchp +acpi_power_meter wmi nfsd auth_rpcgss dm_multipath nfs_acl lockd grace sunrpc +ip_tables xfs libcrc32c sd_mod mgag200 i2c_algo_bit drm_kms_helper syscopyarea +sysfillrect crc32c_intel sysimgblt fb_sys_fops ttm nvme drm nvme_core ahci +libahci i2c_core tg3 libata ptp megaraid_sas pps_core fjes dm_mirror +dm_region_hash dm_log dm_mod +[ 6984.857416] CPU: 7 PID: 1635 Comm: kworker/7:1H Not tainted +4.10.0-2.el7.bz1420297.x86_64 #1 +[ 6984.857417] Hardware name: Dell Inc. PowerEdge R730xd/072T6D, BIOS 2.2.5 09/06/2016 +[ 6984.857427] Workqueue: kblockd blk_mq_run_work_fn +[ 6984.857429] task: ffff880476e3da00 task.stack: ffffc90002e90000 +[ 6984.857432] RIP: 0010:nvme_queue_rq+0x6e6/0x8cd [nvme] +[ 6984.857433] RSP: 0018:ffffc90002e93c50 EFLAGS: 00010246 +[ 6984.857434] RAX: 0000000000000000 RBX: ffff880275646600 RCX: 0000000000001000 +[ 6984.857435] RDX: 0000000000000fff RSI: 00000002fba2a000 RDI: ffff8804734e6950 +[ 6984.857436] RBP: ffffc90002e93d30 R08: 0000000000002000 R09: 0000000000001000 +[ 6984.857437] R10: 0000000000001000 R11: 0000000000000000 R12: ffff8804741d8000 +[ 6984.857438] R13: 0000000000000040 R14: ffff880475649f80 R15: ffff8804734e6780 +[ 6984.857439] FS: 0000000000000000(0000) GS:ffff88047fcc0000(0000) knlGS:0000000000000000 +[ 6984.857440] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[ 6984.857442] CR2: 0000000000000010 CR3: 0000000001c09000 CR4: 00000000001406e0 +[ 6984.857443] Call Trace: +[ 6984.857451] ? mempool_free+0x2b/0x80 +[ 6984.857455] ? bio_free+0x4e/0x60 +[ 6984.857459] blk_mq_dispatch_rq_list+0xf5/0x230 +[ 6984.857462] blk_mq_process_rq_list+0x133/0x170 +[ 6984.857465] __blk_mq_run_hw_queue+0x8c/0xa0 +[ 6984.857467] blk_mq_run_work_fn+0x12/0x20 +[ 6984.857473] process_one_work+0x165/0x410 +[ 6984.857475] worker_thread+0x137/0x4c0 +[ 6984.857478] kthread+0x101/0x140 +[ 6984.857480] ? rescuer_thread+0x3b0/0x3b0 +[ 6984.857481] ? kthread_park+0x90/0x90 +[ 6984.857489] ret_from_fork+0x2c/0x40 +[ 6984.857490] Code: 8b bd 70 ff ff ff 89 95 50 ff ff ff 89 8d 58 ff ff ff 44 +89 95 60 ff ff ff e8 b7 dd 12 e1 8b 95 50 ff ff ff 48 89 85 68 ff ff ff <4c> +8b 48 10 44 8b 58 18 8b 8d 58 ff ff ff 44 8b 95 60 ff ff ff +[ 6984.857511] RIP: nvme_queue_rq+0x6e6/0x8cd [nvme] RSP: ffffc90002e93c50 +[ 6984.857512] CR2: 0000000000000010 +[ 6984.895359] ---[ end trace 2d7ceb528432bf83 ]--- + +Reported-by: Yi Zhang +Tested-by: Yi Zhang +Reviewed-by: Bart Van Assche +Reviewed-by: Hannes Reinecke +Signed-off-by: Ming Lei +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman + +--- + block/blk-mq.c | 11 +---------- + 1 file changed, 1 insertion(+), 10 deletions(-) + +--- a/block/blk-mq.c ++++ b/block/blk-mq.c +@@ -629,17 +629,8 @@ static void blk_mq_check_expired(struct + { + struct blk_mq_timeout_data *data = priv; + +- if (!test_bit(REQ_ATOM_STARTED, &rq->atomic_flags)) { +- /* +- * If a request wasn't started before the queue was +- * marked dying, kill it here or it'll go unnoticed. +- */ +- if (unlikely(blk_queue_dying(rq->q))) { +- rq->errors = -EIO; +- blk_mq_end_request(rq, rq->errors); +- } ++ if (!test_bit(REQ_ATOM_STARTED, &rq->atomic_flags)) + return; +- } + + if (time_after_eq(jiffies, rq->deadline)) { + if (!blk_mark_rq_complete(rq)) diff --git a/queue-4.9/cgroup-net_cls-iterate-the-fds-of-only-the-tasks-which-are-being-migrated.patch b/queue-4.9/cgroup-net_cls-iterate-the-fds-of-only-the-tasks-which-are-being-migrated.patch new file mode 100644 index 00000000000..787ecbd66ab --- /dev/null +++ b/queue-4.9/cgroup-net_cls-iterate-the-fds-of-only-the-tasks-which-are-being-migrated.patch @@ -0,0 +1,128 @@ +From a05d4fd9176003e0c1f9c3d083f4dac19fd346ab Mon Sep 17 00:00:00 2001 +From: Tejun Heo +Date: Tue, 14 Mar 2017 19:25:56 -0400 +Subject: cgroup, net_cls: iterate the fds of only the tasks which are being migrated + +From: Tejun Heo + +commit a05d4fd9176003e0c1f9c3d083f4dac19fd346ab upstream. + +The net_cls controller controls the classid field of each socket which +is associated with the cgroup. Because the classid is per-socket +attribute, when a task migrates to another cgroup or the configured +classid of the cgroup changes, the controller needs to walk all +sockets and update the classid value, which was implemented by +3b13758f51de ("cgroups: Allow dynamically changing net_classid"). + +While the approach is not scalable, migrating tasks which have a lot +of fds attached to them is rare and the cost is born by the ones +initiating the operations. However, for simplicity, both the +migration and classid config change paths call update_classid() which +scans all fds of all tasks in the target css. This is an overkill for +the migration path which only needs to cover a much smaller subset of +tasks which are actually getting migrated in. + +On cgroup v1, this can lead to unexpected scalability issues when one +tries to migrate a task or process into a net_cls cgroup which already +contains a lot of fds. Even if the migration traget doesn't have many +to get scanned, update_classid() ends up scanning all fds in the +target cgroup which can be extremely numerous. + +Unfortunately, on cgroup v2 which doesn't use net_cls, the problem is +even worse. Before bfc2cf6f61fc ("cgroup: call subsys->*attach() only +for subsystems which are actually affected by migration"), cgroup core +would call the ->css_attach callback even for controllers which don't +see actual migration to a different css. + +As net_cls is always disabled but still mounted on cgroup v2, whenever +a process is migrated on the cgroup v2 hierarchy, net_cls sees +identity migration from root to root and cgroup core used to call +->css_attach callback for those. The net_cls ->css_attach ends up +calling update_classid() on the root net_cls css to which all +processes on the system belong to as the controller isn't used. This +makes any cgroup v2 migration O(total_number_of_fds_on_the_system) +which is horrible and easily leads to noticeable stalls triggering RCU +stall warnings and so on. + +The worst symptom is already fixed in upstream by bfc2cf6f61fc +("cgroup: call subsys->*attach() only for subsystems which are +actually affected by migration"); however, backporting that commit is +too invasive and we want to avoid other cases too. + +This patch updates net_cls's cgrp_attach() to iterate fds of only the +processes which are actually getting migrated. This removes the +surprising migration cost which is dependent on the total number of +fds in the target cgroup. As this leaves write_classid() the only +user of update_classid(), open-code the helper into write_classid(). + +Reported-by: David Goode +Fixes: 3b13758f51de ("cgroups: Allow dynamically changing net_classid") +Cc: Nina Schiff +Cc: David S. Miller +Signed-off-by: Tejun Heo +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + net/core/netclassid_cgroup.c | 32 ++++++++++++++++---------------- + 1 file changed, 16 insertions(+), 16 deletions(-) + +--- a/net/core/netclassid_cgroup.c ++++ b/net/core/netclassid_cgroup.c +@@ -69,27 +69,17 @@ static int update_classid_sock(const voi + return 0; + } + +-static void update_classid(struct cgroup_subsys_state *css, void *v) ++static void cgrp_attach(struct cgroup_taskset *tset) + { +- struct css_task_iter it; ++ struct cgroup_subsys_state *css; + struct task_struct *p; + +- css_task_iter_start(css, &it); +- while ((p = css_task_iter_next(&it))) { ++ cgroup_taskset_for_each(p, css, tset) { + task_lock(p); +- iterate_fd(p->files, 0, update_classid_sock, v); ++ iterate_fd(p->files, 0, update_classid_sock, ++ (void *)(unsigned long)css_cls_state(css)->classid); + task_unlock(p); + } +- css_task_iter_end(&it); +-} +- +-static void cgrp_attach(struct cgroup_taskset *tset) +-{ +- struct cgroup_subsys_state *css; +- +- cgroup_taskset_first(tset, &css); +- update_classid(css, +- (void *)(unsigned long)css_cls_state(css)->classid); + } + + static u64 read_classid(struct cgroup_subsys_state *css, struct cftype *cft) +@@ -101,12 +91,22 @@ static int write_classid(struct cgroup_s + u64 value) + { + struct cgroup_cls_state *cs = css_cls_state(css); ++ struct css_task_iter it; ++ struct task_struct *p; + + cgroup_sk_alloc_disable(); + + cs->classid = (u32)value; + +- update_classid(css, (void *)(unsigned long)cs->classid); ++ css_task_iter_start(css, &it); ++ while ((p = css_task_iter_next(&it))) { ++ task_lock(p); ++ iterate_fd(p->files, 0, update_classid_sock, ++ (void *)(unsigned long)cs->classid); ++ task_unlock(p); ++ } ++ css_task_iter_end(&it); ++ + return 0; + } + diff --git a/queue-4.9/cpufreq-restore-policy-min-max-limits-on-cpu-online.patch b/queue-4.9/cpufreq-restore-policy-min-max-limits-on-cpu-online.patch new file mode 100644 index 00000000000..10de46dac89 --- /dev/null +++ b/queue-4.9/cpufreq-restore-policy-min-max-limits-on-cpu-online.patch @@ -0,0 +1,42 @@ +From ff010472fb75670cb5c08671e820eeea3af59c87 Mon Sep 17 00:00:00 2001 +From: Viresh Kumar +Date: Tue, 21 Mar 2017 11:36:06 +0530 +Subject: cpufreq: Restore policy min/max limits on CPU online + +From: Viresh Kumar + +commit ff010472fb75670cb5c08671e820eeea3af59c87 upstream. + +On CPU online the cpufreq core restores the previous governor (or +the previous "policy" setting for ->setpolicy drivers), but it does +not restore the min/max limits at the same time, which is confusing, +inconsistent and real pain for users who set the limits and then +suspend/resume the system (using full suspend), in which case the +limits are reset on all CPUs except for the boot one. + +Fix this by making cpufreq_online() restore the limits when an inactive +policy is brought online. + +The commit log and patch are inspired from Rafael's earlier work. + +Reported-by: Rafael J. Wysocki +Signed-off-by: Viresh Kumar +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/cpufreq/cpufreq.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/cpufreq/cpufreq.c ++++ b/drivers/cpufreq/cpufreq.c +@@ -1190,6 +1190,9 @@ static int cpufreq_online(unsigned int c + for_each_cpu(j, policy->related_cpus) + per_cpu(cpufreq_cpu_data, j) = policy; + write_unlock_irqrestore(&cpufreq_driver_lock, flags); ++ } else { ++ policy->min = policy->user_policy.min; ++ policy->max = policy->user_policy.max; + } + + if (cpufreq_driver->get && !cpufreq_driver->setpolicy) { diff --git a/queue-4.9/drivers-hv-vmbus-don-t-leak-channel-ids.patch b/queue-4.9/drivers-hv-vmbus-don-t-leak-channel-ids.patch new file mode 100644 index 00000000000..655f9024613 --- /dev/null +++ b/queue-4.9/drivers-hv-vmbus-don-t-leak-channel-ids.patch @@ -0,0 +1,29 @@ +From 9a5476020a5f06a0fc6f17097efc80275d2f03cd Mon Sep 17 00:00:00 2001 +From: "K. Y. Srinivasan" +Date: Mon, 13 Mar 2017 15:57:09 -0700 +Subject: Drivers: hv: vmbus: Don't leak channel ids + +From: K. Y. Srinivasan + +commit 9a5476020a5f06a0fc6f17097efc80275d2f03cd upstream. + +If we cannot allocate memory for the channel, free the relid +associated with the channel. + +Signed-off-by: K. Y. Srinivasan +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/hv/channel_mgmt.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/hv/channel_mgmt.c ++++ b/drivers/hv/channel_mgmt.c +@@ -779,6 +779,7 @@ static void vmbus_onoffer(struct vmbus_c + /* Allocate the channel object and save this offer. */ + newchannel = alloc_channel(); + if (!newchannel) { ++ vmbus_release_relid(offer->child_relid); + pr_err("Unable to allocate channel object\n"); + return; + } diff --git a/queue-4.9/drivers-hv-vmbus-don-t-leak-memory-when-a-channel-is-rescinded.patch b/queue-4.9/drivers-hv-vmbus-don-t-leak-memory-when-a-channel-is-rescinded.patch new file mode 100644 index 00000000000..51756833e8b --- /dev/null +++ b/queue-4.9/drivers-hv-vmbus-don-t-leak-memory-when-a-channel-is-rescinded.patch @@ -0,0 +1,46 @@ +From 5e030d5ce9d99a899b648413139ff65bab12b038 Mon Sep 17 00:00:00 2001 +From: "K. Y. Srinivasan" +Date: Sun, 12 Mar 2017 20:00:30 -0700 +Subject: Drivers: hv: vmbus: Don't leak memory when a channel is rescinded + +From: K. Y. Srinivasan + +commit 5e030d5ce9d99a899b648413139ff65bab12b038 upstream. + +When we close a channel that has been rescinded, we will leak memory since +vmbus_teardown_gpadl() returns an error. Fix this so that we can properly +cleanup the memory allocated to the ring buffers. + +Fixes: ccb61f8a99e6 ("Drivers: hv: vmbus: Fix a rescind handling bug") + +Signed-off-by: K. Y. Srinivasan +Cc: Dexuan Cui +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/hv/channel.c | 13 ++++++++----- + 1 file changed, 8 insertions(+), 5 deletions(-) + +--- a/drivers/hv/channel.c ++++ b/drivers/hv/channel.c +@@ -506,12 +506,15 @@ int vmbus_teardown_gpadl(struct vmbus_ch + + wait_for_completion(&info->waitevent); + +- if (channel->rescind) { +- ret = -ENODEV; +- goto post_msg_err; +- } +- + post_msg_err: ++ /* ++ * If the channel has been rescinded; ++ * we will be awakened by the rescind ++ * handler; set the error code to zero so we don't leak memory. ++ */ ++ if (channel->rescind) ++ ret = 0; ++ + spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); + list_del(&info->msglistentry); + spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags); diff --git a/queue-4.9/drm-amdgpu-reinstate-oland-workaround-for-sclk.patch b/queue-4.9/drm-amdgpu-reinstate-oland-workaround-for-sclk.patch new file mode 100644 index 00000000000..001965dc8e7 --- /dev/null +++ b/queue-4.9/drm-amdgpu-reinstate-oland-workaround-for-sclk.patch @@ -0,0 +1,39 @@ +From e11ddff68a7c455e63c4b46154a3e75c699a7b55 Mon Sep 17 00:00:00 2001 +From: Alex Deucher +Date: Wed, 15 Mar 2017 21:13:25 -0400 +Subject: drm/amdgpu: reinstate oland workaround for sclk + +From: Alex Deucher + +commit e11ddff68a7c455e63c4b46154a3e75c699a7b55 upstream. + +Higher sclks seem to be unstable on some boards. + +bug: https://bugs.freedesktop.org/show_bug.cgi?id=100222 + +Signed-off-by: Alex Deucher +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/amd/amdgpu/si_dpm.c | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +--- a/drivers/gpu/drm/amd/amdgpu/si_dpm.c ++++ b/drivers/gpu/drm/amd/amdgpu/si_dpm.c +@@ -3507,9 +3507,13 @@ static void si_apply_state_adjust_rules( + max_mclk = 80000; + } + } else if (adev->asic_type == CHIP_OLAND) { +- if ((adev->pdev->device == 0x6604) && +- (adev->pdev->subsystem_vendor == 0x1028) && +- (adev->pdev->subsystem_device == 0x066F)) { ++ if ((adev->pdev->revision == 0xC7) || ++ (adev->pdev->revision == 0x80) || ++ (adev->pdev->revision == 0x81) || ++ (adev->pdev->revision == 0x83) || ++ (adev->pdev->revision == 0x87) || ++ (adev->pdev->device == 0x6604) || ++ (adev->pdev->device == 0x6605)) { + max_sclk = 75000; + } + } diff --git a/queue-4.9/intel_th-don-t-leak-module-refcount-on-failure-to-activate.patch b/queue-4.9/intel_th-don-t-leak-module-refcount-on-failure-to-activate.patch new file mode 100644 index 00000000000..244f82b32e8 --- /dev/null +++ b/queue-4.9/intel_th-don-t-leak-module-refcount-on-failure-to-activate.patch @@ -0,0 +1,39 @@ +From e609ccef5222c73b46b322be7d3796d60bff353d Mon Sep 17 00:00:00 2001 +From: Alexander Shishkin +Date: Fri, 24 Feb 2017 16:04:15 +0200 +Subject: intel_th: Don't leak module refcount on failure to activate + +From: Alexander Shishkin + +commit e609ccef5222c73b46b322be7d3796d60bff353d upstream. + +Output 'activation' may fail for the reasons of the output driver, +for example, if msc's buffer is not allocated. We forget, however, +to drop the module reference in this case. So each attempt at +activation in this case leaks a reference, preventing the module +from ever unloading. + +This patch adds the missing module_put() in the activation error +path. + +Signed-off-by: Alexander Shishkin +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/hwtracing/intel_th/core.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/hwtracing/intel_th/core.c ++++ b/drivers/hwtracing/intel_th/core.c +@@ -218,8 +218,10 @@ static int intel_th_output_activate(stru + else + intel_th_trace_enable(thdev); + +- if (ret) ++ if (ret) { + pm_runtime_put(&thdev->dev); ++ module_put(thdrv->driver.owner); ++ } + + return ret; + } diff --git a/queue-4.9/jbd2-don-t-leak-memory-if-setting-up-journal-fails.patch b/queue-4.9/jbd2-don-t-leak-memory-if-setting-up-journal-fails.patch new file mode 100644 index 00000000000..7d7a9b57ced --- /dev/null +++ b/queue-4.9/jbd2-don-t-leak-memory-if-setting-up-journal-fails.patch @@ -0,0 +1,82 @@ +From cd9cb405e0b948363811dc74dbb2890f56f2cb87 Mon Sep 17 00:00:00 2001 +From: Eric Biggers +Date: Wed, 15 Mar 2017 15:08:48 -0400 +Subject: jbd2: don't leak memory if setting up journal fails + +From: Eric Biggers + +commit cd9cb405e0b948363811dc74dbb2890f56f2cb87 upstream. + +In journal_init_common(), if we failed to allocate the j_wbuf array, or +if we failed to create the buffer_head for the journal superblock, we +leaked the memory allocated for the revocation tables. Fix this. + +Fixes: f0c9fd5458bacf7b12a9a579a727dc740cbe047e +Signed-off-by: Eric Biggers +Signed-off-by: Theodore Ts'o +Reviewed-by: Jan Kara +Signed-off-by: Greg Kroah-Hartman + +--- + fs/jbd2/journal.c | 22 +++++++++++----------- + fs/jbd2/revoke.c | 1 + + 2 files changed, 12 insertions(+), 11 deletions(-) + +--- a/fs/jbd2/journal.c ++++ b/fs/jbd2/journal.c +@@ -1125,10 +1125,8 @@ static journal_t *journal_init_common(st + + /* Set up a default-sized revoke table for the new mount. */ + err = jbd2_journal_init_revoke(journal, JOURNAL_REVOKE_DEFAULT_HASH); +- if (err) { +- kfree(journal); +- return NULL; +- } ++ if (err) ++ goto err_cleanup; + + spin_lock_init(&journal->j_history_lock); + +@@ -1145,23 +1143,25 @@ static journal_t *journal_init_common(st + journal->j_wbufsize = n; + journal->j_wbuf = kmalloc_array(n, sizeof(struct buffer_head *), + GFP_KERNEL); +- if (!journal->j_wbuf) { +- kfree(journal); +- return NULL; +- } ++ if (!journal->j_wbuf) ++ goto err_cleanup; + + bh = getblk_unmovable(journal->j_dev, start, journal->j_blocksize); + if (!bh) { + pr_err("%s: Cannot get buffer for journal superblock\n", + __func__); +- kfree(journal->j_wbuf); +- kfree(journal); +- return NULL; ++ goto err_cleanup; + } + journal->j_sb_buffer = bh; + journal->j_superblock = (journal_superblock_t *)bh->b_data; + + return journal; ++ ++err_cleanup: ++ kfree(journal->j_wbuf); ++ jbd2_journal_destroy_revoke(journal); ++ kfree(journal); ++ return NULL; + } + + /* jbd2_journal_init_dev and jbd2_journal_init_inode: +--- a/fs/jbd2/revoke.c ++++ b/fs/jbd2/revoke.c +@@ -280,6 +280,7 @@ int jbd2_journal_init_revoke(journal_t * + + fail1: + jbd2_journal_destroy_revoke_table(journal->j_revoke_table[0]); ++ journal->j_revoke_table[0] = NULL; + fail0: + return -ENOMEM; + } diff --git a/queue-4.9/libceph-force-gfp_noio-for-socket-allocations.patch b/queue-4.9/libceph-force-gfp_noio-for-socket-allocations.patch new file mode 100644 index 00000000000..75ce33ffe3d --- /dev/null +++ b/queue-4.9/libceph-force-gfp_noio-for-socket-allocations.patch @@ -0,0 +1,108 @@ +From 633ee407b9d15a75ac9740ba9d3338815e1fcb95 Mon Sep 17 00:00:00 2001 +From: Ilya Dryomov +Date: Tue, 21 Mar 2017 13:44:28 +0100 +Subject: libceph: force GFP_NOIO for socket allocations + +From: Ilya Dryomov + +commit 633ee407b9d15a75ac9740ba9d3338815e1fcb95 upstream. + +sock_alloc_inode() allocates socket+inode and socket_wq with +GFP_KERNEL, which is not allowed on the writeback path: + + Workqueue: ceph-msgr con_work [libceph] + ffff8810871cb018 0000000000000046 0000000000000000 ffff881085d40000 + 0000000000012b00 ffff881025cad428 ffff8810871cbfd8 0000000000012b00 + ffff880102fc1000 ffff881085d40000 ffff8810871cb038 ffff8810871cb148 + Call Trace: + [] schedule+0x29/0x70 + [] schedule_timeout+0x1bd/0x200 + [] ? ttwu_do_wakeup+0x2c/0x120 + [] ? ttwu_do_activate.constprop.135+0x66/0x70 + [] wait_for_completion+0xbf/0x180 + [] ? try_to_wake_up+0x390/0x390 + [] flush_work+0x165/0x250 + [] ? worker_detach_from_pool+0xd0/0xd0 + [] xlog_cil_force_lsn+0x81/0x200 [xfs] + [] ? __slab_free+0xee/0x234 + [] _xfs_log_force_lsn+0x4d/0x2c0 [xfs] + [] ? lookup_page_cgroup_used+0xe/0x30 + [] ? xfs_reclaim_inode+0xa3/0x330 [xfs] + [] xfs_log_force_lsn+0x3f/0xf0 [xfs] + [] ? xfs_reclaim_inode+0xa3/0x330 [xfs] + [] xfs_iunpin_wait+0xc6/0x1a0 [xfs] + [] ? wake_atomic_t_function+0x40/0x40 + [] xfs_reclaim_inode+0xa3/0x330 [xfs] + [] xfs_reclaim_inodes_ag+0x257/0x3d0 [xfs] + [] xfs_reclaim_inodes_nr+0x33/0x40 [xfs] + [] xfs_fs_free_cached_objects+0x15/0x20 [xfs] + [] super_cache_scan+0x178/0x180 + [] shrink_slab_node+0x14e/0x340 + [] ? mem_cgroup_iter+0x16b/0x450 + [] shrink_slab+0x100/0x140 + [] do_try_to_free_pages+0x335/0x490 + [] try_to_free_pages+0xb9/0x1f0 + [] ? __alloc_pages_direct_compact+0x69/0x1be + [] __alloc_pages_nodemask+0x69a/0xb40 + [] alloc_pages_current+0x9e/0x110 + [] new_slab+0x2c5/0x390 + [] __slab_alloc+0x33b/0x459 + [] ? sock_alloc_inode+0x2d/0xd0 + [] ? inet_sendmsg+0x71/0xc0 + [] ? sock_alloc_inode+0x2d/0xd0 + [] kmem_cache_alloc+0x1a2/0x1b0 + [] sock_alloc_inode+0x2d/0xd0 + [] alloc_inode+0x26/0xa0 + [] new_inode_pseudo+0x1a/0x70 + [] sock_alloc+0x1e/0x80 + [] __sock_create+0x95/0x220 + [] sock_create_kern+0x24/0x30 + [] con_work+0xef9/0x2050 [libceph] + [] ? rbd_img_request_submit+0x4c/0x60 [rbd] + [] process_one_work+0x159/0x4f0 + [] worker_thread+0x11b/0x530 + [] ? create_worker+0x1d0/0x1d0 + [] kthread+0xc9/0xe0 + [] ? flush_kthread_worker+0x90/0x90 + [] ret_from_fork+0x58/0x90 + [] ? flush_kthread_worker+0x90/0x90 + +Use memalloc_noio_{save,restore}() to temporarily force GFP_NOIO here. + +Link: http://tracker.ceph.com/issues/19309 +Reported-by: Sergey Jerusalimov +Signed-off-by: Ilya Dryomov +Reviewed-by: Jeff Layton +Signed-off-by: Greg Kroah-Hartman + +--- + net/ceph/messenger.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/net/ceph/messenger.c ++++ b/net/ceph/messenger.c +@@ -7,6 +7,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -469,11 +470,16 @@ static int ceph_tcp_connect(struct ceph_ + { + struct sockaddr_storage *paddr = &con->peer_addr.in_addr; + struct socket *sock; ++ unsigned int noio_flag; + int ret; + + BUG_ON(con->sock); ++ ++ /* sock_create_kern() allocates with GFP_KERNEL */ ++ noio_flag = memalloc_noio_save(); + ret = sock_create_kern(read_pnet(&con->msgr->net), paddr->ss_family, + SOCK_STREAM, IPPROTO_TCP, &sock); ++ memalloc_noio_restore(noio_flag); + if (ret) + return ret; + sock->sk->sk_allocation = GFP_NOFS; diff --git a/queue-4.9/revert-arm-at91-dt-sama5d2-use-new-compatible-for-ohci-node.patch b/queue-4.9/revert-arm-at91-dt-sama5d2-use-new-compatible-for-ohci-node.patch new file mode 100644 index 00000000000..72da6dcf7a3 --- /dev/null +++ b/queue-4.9/revert-arm-at91-dt-sama5d2-use-new-compatible-for-ohci-node.patch @@ -0,0 +1,42 @@ +From 9e10889a3177340dcda7d29c6d8fbd97247b007b Mon Sep 17 00:00:00 2001 +From: Romain Izard +Date: Fri, 17 Feb 2017 16:12:50 +0100 +Subject: Revert "ARM: at91/dt: sama5d2: Use new compatible for ohci node" + +From: Romain Izard + +commit 9e10889a3177340dcda7d29c6d8fbd97247b007b upstream. + +This reverts commit cab43282682e ("ARM: at91/dt: sama5d2: Use new +compatible for ohci node") + +It depends from commit 7150bc9b4d43 ("usb: ohci-at91: Forcibly suspend +ports while USB suspend") which was reverted and implemented +differently. With the new implementation, the compatible string must +remain the same. + +The compatible string introduced by this commit has been used in the +default SAMA5D2 dtsi starting from Linux 4.8. As it has never been +working correctly in an official release, removing it should not be +breaking the stability rules. + +Fixes: cab43282682e ("ARM: at91/dt: sama5d2: Use new compatible for ohci node") +Signed-off-by: Romain Izard +Signed-off-by: Alexandre Belloni +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arm/boot/dts/sama5d2.dtsi | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/arm/boot/dts/sama5d2.dtsi ++++ b/arch/arm/boot/dts/sama5d2.dtsi +@@ -266,7 +266,7 @@ + }; + + usb1: ohci@00400000 { +- compatible = "atmel,sama5d2-ohci", "usb-ohci"; ++ compatible = "atmel,at91rm9200-ohci", "usb-ohci"; + reg = <0x00400000 0x100000>; + interrupts = <41 IRQ_TYPE_LEVEL_HIGH 2>; + clocks = <&uhphs_clk>, <&uhphs_clk>, <&uhpck>; diff --git a/queue-4.9/series b/queue-4.9/series index 107455d32b3..d128e1c84b6 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -66,3 +66,16 @@ mwifiex-pcie-don-t-leak-dma-buffers-when-removing.patch crypto-ccp-assign-dma-commands-to-the-channel-s-ccp.patch xen-acpi-upload-pm-state-from-init-domain-to-xen.patch iommu-vt-d-fix-null-pointer-dereference-in-device_to_iommu.patch +revert-arm-at91-dt-sama5d2-use-new-compatible-for-ohci-node.patch +arm-at91-pm-cpu_idle-switch-ddr-to-power-down-mode.patch +arm64-kaslr-fix-up-the-kernel-image-alignment.patch +cpufreq-restore-policy-min-max-limits-on-cpu-online.patch +cgroup-net_cls-iterate-the-fds-of-only-the-tasks-which-are-being-migrated.patch +blk-mq-don-t-complete-un-started-request-in-timeout-handler.patch +libceph-force-gfp_noio-for-socket-allocations.patch +drm-amdgpu-reinstate-oland-workaround-for-sclk.patch +auxdisplay-img-ascii-lcd-add-missing-sentinel-entry-in-img_ascii_lcd_matches.patch +jbd2-don-t-leak-memory-if-setting-up-journal-fails.patch +intel_th-don-t-leak-module-refcount-on-failure-to-activate.patch +drivers-hv-vmbus-don-t-leak-channel-ids.patch +drivers-hv-vmbus-don-t-leak-memory-when-a-channel-is-rescinded.patch