From: Greg Kroah-Hartman Date: Sun, 14 Aug 2016 16:15:01 +0000 (+0200) Subject: 4.6-stable patches X-Git-Tag: v3.14.76~14 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=dea05769c878d98def5c81c4d3accf4c0661ef7b;p=thirdparty%2Fkernel%2Fstable-queue.git 4.6-stable patches added patches: mm-memcontrol-fix-memcg-id-ref-counter-on-swap-charge-move.patch mm-memcontrol-fix-swap-counter-leak-on-swapout-from-offline-cgroup.patch powerpc-bpf-jit-disable-classic-bpf-jit-on-ppc64le.patch powerpc-eeh-fix-invalid-cached-pe-primary-bus.patch --- diff --git a/queue-4.6/mm-memcontrol-fix-memcg-id-ref-counter-on-swap-charge-move.patch b/queue-4.6/mm-memcontrol-fix-memcg-id-ref-counter-on-swap-charge-move.patch new file mode 100644 index 00000000000..9601d6c8242 --- /dev/null +++ b/queue-4.6/mm-memcontrol-fix-memcg-id-ref-counter-on-swap-charge-move.patch @@ -0,0 +1,91 @@ +From 615d66c37c755c49ce022c9e5ac0875d27d2603d Mon Sep 17 00:00:00 2001 +From: Vladimir Davydov +Date: Thu, 11 Aug 2016 15:33:03 -0700 +Subject: mm: memcontrol: fix memcg id ref counter on swap charge move + +From: Vladimir Davydov + +commit 615d66c37c755c49ce022c9e5ac0875d27d2603d upstream. + +Since commit 73f576c04b94 ("mm: memcontrol: fix cgroup creation failure +after many small jobs") swap entries do not pin memcg->css.refcnt +directly. Instead, they pin memcg->id.ref. So we should adjust the +reference counters accordingly when moving swap charges between cgroups. + +Fixes: 73f576c04b941 ("mm: memcontrol: fix cgroup creation failure after many small jobs") +Link: http://lkml.kernel.org/r/9ce297c64954a42dc90b543bc76106c4a94f07e8.1470219853.git.vdavydov@virtuozzo.com +Signed-off-by: Vladimir Davydov +Acked-by: Michal Hocko +Acked-by: Johannes Weiner +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + mm/memcontrol.c | 24 ++++++++++++++++++------ + 1 file changed, 18 insertions(+), 6 deletions(-) + +--- a/mm/memcontrol.c ++++ b/mm/memcontrol.c +@@ -4064,9 +4064,9 @@ static struct cftype mem_cgroup_legacy_f + + static DEFINE_IDR(mem_cgroup_idr); + +-static void mem_cgroup_id_get(struct mem_cgroup *memcg) ++static void mem_cgroup_id_get_many(struct mem_cgroup *memcg, unsigned int n) + { +- atomic_inc(&memcg->id.ref); ++ atomic_add(n, &memcg->id.ref); + } + + static struct mem_cgroup *mem_cgroup_id_get_online(struct mem_cgroup *memcg) +@@ -4087,9 +4087,9 @@ static struct mem_cgroup *mem_cgroup_id_ + return memcg; + } + +-static void mem_cgroup_id_put(struct mem_cgroup *memcg) ++static void mem_cgroup_id_put_many(struct mem_cgroup *memcg, unsigned int n) + { +- if (atomic_dec_and_test(&memcg->id.ref)) { ++ if (atomic_sub_and_test(n, &memcg->id.ref)) { + idr_remove(&mem_cgroup_idr, memcg->id.id); + memcg->id.id = 0; + +@@ -4098,6 +4098,16 @@ static void mem_cgroup_id_put(struct mem + } + } + ++static inline void mem_cgroup_id_get(struct mem_cgroup *memcg) ++{ ++ mem_cgroup_id_get_many(memcg, 1); ++} ++ ++static inline void mem_cgroup_id_put(struct mem_cgroup *memcg) ++{ ++ mem_cgroup_id_put_many(memcg, 1); ++} ++ + /** + * mem_cgroup_from_id - look up a memcg from a memcg id + * @id: the memcg id to look up +@@ -4734,6 +4744,8 @@ static void __mem_cgroup_clear_mc(void) + if (!mem_cgroup_is_root(mc.from)) + page_counter_uncharge(&mc.from->memsw, mc.moved_swap); + ++ mem_cgroup_id_put_many(mc.from, mc.moved_swap); ++ + /* + * we charged both to->memory and to->memsw, so we + * should uncharge to->memory. +@@ -4741,9 +4753,9 @@ static void __mem_cgroup_clear_mc(void) + if (!mem_cgroup_is_root(mc.to)) + page_counter_uncharge(&mc.to->memory, mc.moved_swap); + +- css_put_many(&mc.from->css, mc.moved_swap); ++ mem_cgroup_id_get_many(mc.to, mc.moved_swap); ++ css_put_many(&mc.to->css, mc.moved_swap); + +- /* we've already done css_get(mc.to) */ + mc.moved_swap = 0; + } + memcg_oom_recover(from); diff --git a/queue-4.6/mm-memcontrol-fix-swap-counter-leak-on-swapout-from-offline-cgroup.patch b/queue-4.6/mm-memcontrol-fix-swap-counter-leak-on-swapout-from-offline-cgroup.patch new file mode 100644 index 00000000000..5ac2f86877a --- /dev/null +++ b/queue-4.6/mm-memcontrol-fix-swap-counter-leak-on-swapout-from-offline-cgroup.patch @@ -0,0 +1,119 @@ +From 1f47b61fb4077936465dcde872a4e5cc4fe708da Mon Sep 17 00:00:00 2001 +From: Vladimir Davydov +Date: Thu, 11 Aug 2016 15:33:00 -0700 +Subject: mm: memcontrol: fix swap counter leak on swapout from offline cgroup + +From: Vladimir Davydov + +commit 1f47b61fb4077936465dcde872a4e5cc4fe708da upstream. + +An offline memory cgroup might have anonymous memory or shmem left +charged to it and no swap. Since only swap entries pin the id of an +offline cgroup, such a cgroup will have no id and so an attempt to +swapout its anon/shmem will not store memory cgroup info in the swap +cgroup map. As a result, memcg->swap or memcg->memsw will never get +uncharged from it and any of its ascendants. + +Fix this by always charging swapout to the first ancestor cgroup that +hasn't released its id yet. + +[hannes@cmpxchg.org: add comment to mem_cgroup_swapout] +[vdavydov@virtuozzo.com: use WARN_ON_ONCE() in mem_cgroup_id_get_online()] + Link: http://lkml.kernel.org/r/20160803123445.GJ13263@esperanza +Fixes: 73f576c04b941 ("mm: memcontrol: fix cgroup creation failure after many small jobs") +Link: http://lkml.kernel.org/r/5336daa5c9a32e776067773d9da655d2dc126491.1470219853.git.vdavydov@virtuozzo.com +Signed-off-by: Vladimir Davydov +Acked-by: Johannes Weiner +Acked-by: Michal Hocko +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + mm/memcontrol.c | 44 ++++++++++++++++++++++++++++++++++++++------ + 1 file changed, 38 insertions(+), 6 deletions(-) + +--- a/mm/memcontrol.c ++++ b/mm/memcontrol.c +@@ -4069,6 +4069,24 @@ static void mem_cgroup_id_get(struct mem + atomic_inc(&memcg->id.ref); + } + ++static struct mem_cgroup *mem_cgroup_id_get_online(struct mem_cgroup *memcg) ++{ ++ while (!atomic_inc_not_zero(&memcg->id.ref)) { ++ /* ++ * The root cgroup cannot be destroyed, so it's refcount must ++ * always be >= 1. ++ */ ++ if (WARN_ON_ONCE(memcg == root_mem_cgroup)) { ++ VM_BUG_ON(1); ++ break; ++ } ++ memcg = parent_mem_cgroup(memcg); ++ if (!memcg) ++ memcg = root_mem_cgroup; ++ } ++ return memcg; ++} ++ + static void mem_cgroup_id_put(struct mem_cgroup *memcg) + { + if (atomic_dec_and_test(&memcg->id.ref)) { +@@ -5785,7 +5803,7 @@ subsys_initcall(mem_cgroup_init); + */ + void mem_cgroup_swapout(struct page *page, swp_entry_t entry) + { +- struct mem_cgroup *memcg; ++ struct mem_cgroup *memcg, *swap_memcg; + unsigned short oldid; + + VM_BUG_ON_PAGE(PageLRU(page), page); +@@ -5800,16 +5818,27 @@ void mem_cgroup_swapout(struct page *pag + if (!memcg) + return; + +- mem_cgroup_id_get(memcg); +- oldid = swap_cgroup_record(entry, mem_cgroup_id(memcg)); ++ /* ++ * In case the memcg owning these pages has been offlined and doesn't ++ * have an ID allocated to it anymore, charge the closest online ++ * ancestor for the swap instead and transfer the memory+swap charge. ++ */ ++ swap_memcg = mem_cgroup_id_get_online(memcg); ++ oldid = swap_cgroup_record(entry, mem_cgroup_id(swap_memcg)); + VM_BUG_ON_PAGE(oldid, page); +- mem_cgroup_swap_statistics(memcg, true); ++ mem_cgroup_swap_statistics(swap_memcg, true); + + page->mem_cgroup = NULL; + + if (!mem_cgroup_is_root(memcg)) + page_counter_uncharge(&memcg->memory, 1); + ++ if (memcg != swap_memcg) { ++ if (!mem_cgroup_is_root(swap_memcg)) ++ page_counter_charge(&swap_memcg->memsw, 1); ++ page_counter_uncharge(&memcg->memsw, 1); ++ } ++ + /* + * Interrupts should be disabled here because the caller holds the + * mapping->tree_lock lock which is taken with interrupts-off. It is +@@ -5848,11 +5877,14 @@ int mem_cgroup_try_charge_swap(struct pa + if (!memcg) + return 0; + ++ memcg = mem_cgroup_id_get_online(memcg); ++ + if (!mem_cgroup_is_root(memcg) && +- !page_counter_try_charge(&memcg->swap, 1, &counter)) ++ !page_counter_try_charge(&memcg->swap, 1, &counter)) { ++ mem_cgroup_id_put(memcg); + return -ENOMEM; ++ } + +- mem_cgroup_id_get(memcg); + oldid = swap_cgroup_record(entry, mem_cgroup_id(memcg)); + VM_BUG_ON_PAGE(oldid, page); + mem_cgroup_swap_statistics(memcg, true); diff --git a/queue-4.6/powerpc-bpf-jit-disable-classic-bpf-jit-on-ppc64le.patch b/queue-4.6/powerpc-bpf-jit-disable-classic-bpf-jit-on-ppc64le.patch new file mode 100644 index 00000000000..c988ba6d7b3 --- /dev/null +++ b/queue-4.6/powerpc-bpf-jit-disable-classic-bpf-jit-on-ppc64le.patch @@ -0,0 +1,36 @@ +From 844e3be47693f92a108cb1fb3b0606bf25e9c7a6 Mon Sep 17 00:00:00 2001 +From: "Naveen N. Rao" +Date: Wed, 22 Jun 2016 21:55:01 +0530 +Subject: powerpc/bpf/jit: Disable classic BPF JIT on ppc64le + +From: Naveen N. Rao + +commit 844e3be47693f92a108cb1fb3b0606bf25e9c7a6 upstream. + +Classic BPF JIT was never ported completely to work on little endian +powerpc. However, it can be enabled and will crash the system when used. +As such, disable use of BPF JIT on ppc64le. + +Fixes: 7c105b63bd98 ("powerpc: Add CONFIG_CPU_LITTLE_ENDIAN kernel config option.") +Reported-by: Thadeu Lima de Souza Cascardo +Signed-off-by: Naveen N. Rao +Acked-by: Thadeu Lima de Souza Cascardo +Signed-off-by: Michael Ellerman +Signed-off-by: Greg Kroah-Hartman + + +--- + arch/powerpc/Kconfig | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/powerpc/Kconfig ++++ b/arch/powerpc/Kconfig +@@ -126,7 +126,7 @@ config PPC + select IRQ_FORCED_THREADING + select HAVE_RCU_TABLE_FREE if SMP + select HAVE_SYSCALL_TRACEPOINTS +- select HAVE_BPF_JIT ++ select HAVE_BPF_JIT if CPU_BIG_ENDIAN + select HAVE_ARCH_JUMP_LABEL + select ARCH_HAVE_NMI_SAFE_CMPXCHG + select ARCH_HAS_GCOV_PROFILE_ALL diff --git a/queue-4.6/powerpc-eeh-fix-invalid-cached-pe-primary-bus.patch b/queue-4.6/powerpc-eeh-fix-invalid-cached-pe-primary-bus.patch new file mode 100644 index 00000000000..660672206b8 --- /dev/null +++ b/queue-4.6/powerpc-eeh-fix-invalid-cached-pe-primary-bus.patch @@ -0,0 +1,55 @@ +From a3aa256b7258b3d19f8b44557cc64525a993b941 Mon Sep 17 00:00:00 2001 +From: Gavin Shan +Date: Fri, 17 Jun 2016 13:05:11 +1000 +Subject: powerpc/eeh: Fix invalid cached PE primary bus + +From: Gavin Shan + +commit a3aa256b7258b3d19f8b44557cc64525a993b941 upstream. + +The PE primary bus cannot be got from its child devices when having +full hotplug in error recovery. The PE primary bus is cached, which +is done in commit <05ba75f84864> ("powerpc/eeh: Fix stale cached primary +bus"). In eeh_reset_device(), the flag (EEH_PE_PRI_BUS) is cleared +before the PCI hot remove. eeh_pe_bus_get() then returns NULL as the +PE primary bus in pnv_eeh_reset() and it crashes the kernel eventually. + +This fixes the issue by clearing the flag (EEH_PE_PRI_BUS) before the +PCI hot add. With it, the PowerNV EEH reset backend (pnv_eeh_reset()) +can get valid PE primary bus through eeh_pe_bus_get(). + +Fixes: 67086e32b564 ("powerpc/eeh: powerpc/eeh: Support error recovery for VF PE") +Reported-by: Pridhiviraj Paidipeddi +Signed-off-by: Gavin Shan +Signed-off-by: Michael Ellerman +Signed-off-by: Greg Kroah-Hartman + +--- + arch/powerpc/kernel/eeh_driver.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +--- a/arch/powerpc/kernel/eeh_driver.c ++++ b/arch/powerpc/kernel/eeh_driver.c +@@ -648,7 +648,6 @@ static int eeh_reset_device(struct eeh_p + if (pe->type & EEH_PE_VF) { + eeh_pe_dev_traverse(pe, eeh_rmv_device, NULL); + } else { +- eeh_pe_state_clear(pe, EEH_PE_PRI_BUS); + pci_lock_rescan_remove(); + pcibios_remove_pci_devices(bus); + pci_unlock_rescan_remove(); +@@ -698,10 +697,12 @@ static int eeh_reset_device(struct eeh_p + */ + edev = list_first_entry(&pe->edevs, struct eeh_dev, list); + eeh_pe_traverse(pe, eeh_pe_detach_dev, NULL); +- if (pe->type & EEH_PE_VF) ++ if (pe->type & EEH_PE_VF) { + eeh_add_virt_device(edev, NULL); +- else ++ } else { ++ eeh_pe_state_clear(pe, EEH_PE_PRI_BUS); + pcibios_add_pci_devices(bus); ++ } + } else if (frozen_bus && rmv_data->removed) { + pr_info("EEH: Sleep 5s ahead of partial hotplug\n"); + ssleep(5); diff --git a/queue-4.6/series b/queue-4.6/series index 1d8bba3d76f..3d674d8b372 100644 --- a/queue-4.6/series +++ b/queue-4.6/series @@ -29,3 +29,7 @@ x86-xen-pat-remove-pat-table-init-code-from-xen.patch x86-pat-document-the-pat-initialization-sequence.patch x86-mm-pat-fix-bug_on-in-mmap_mem-on-qemu-i386.patch udf-prevent-stack-overflow-on-corrupted-filesystem-mount.patch +powerpc-eeh-fix-invalid-cached-pe-primary-bus.patch +powerpc-bpf-jit-disable-classic-bpf-jit-on-ppc64le.patch +mm-memcontrol-fix-swap-counter-leak-on-swapout-from-offline-cgroup.patch +mm-memcontrol-fix-memcg-id-ref-counter-on-swap-charge-move.patch