Re: [PATCH v2] powerpc: mm: fixup preempt undefflow with huge pages
From: Sebastian Andrzej Siewior <hidden>
Date: 2016-03-29 13:58:43
On 2016-03-10 01:04:24 [+0530], Aneesh Kumar K.V wrote:
Sebastian Andrzej Siewior [off-list ref] writes:
*ping* http://patchwork.ozlabs.org/patch/593943/
quoted
[ text/plain ] hugepd_free() used __get_cpu_var() once. Nothing ensured that the code accessing the variable did not migrate from one CPU to another and soon this was noticed by Tiejun Chen in 94b09d755462 ("powerpc/hugetlb: Replace __get_cpu_var with get_cpu_var"). So we had it fixed. Christoph Lameter was doing his __get_cpu_var() replaces and forgot PowerPC. Then he noticed this and sent his fixed up batch again which got applied as 69111bac42f5 ("powerpc: Replace __get_cpu_var uses"). The careful reader will noticed one little detail: get_cpu_var() got replaced with this_cpu_ptr(). So now we have a put_cpu_var() which does a preempt_enable() and nothing that does preempt_disable() so we underflow the preempt counter.=20 Reviewed-by: Aneesh Kumar K.V <redacted> =20quoted
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> Cc: Christoph Lameter <redacted> Cc: Michael Ellerman <mpe@ellerman.id.au> Cc: <redacted> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- v1=E2=80=A6v2: - use get_cpu_var() instead of get_cpu_ptr() - correct indentation of put_cpu_var() arch/powerpc/mm/hugetlbpage.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpag=
e.c
quoted
index 744e24bcb85c..4a811ca7ac9d 100644--- a/arch/powerpc/mm/hugetlbpage.c +++ b/arch/powerpc/mm/hugetlbpage.c@@ -414,13 +414,13 @@ static void hugepd_free(struct mmu_gather *tlb, v=
oid *hugepte)
quoted
{ struct hugepd_freelist **batchp; =20 - batchp =3D this_cpu_ptr(&hugepd_freelist_cur); + batchp =3D &get_cpu_var(hugepd_freelist_cur); =20 if (atomic_read(&tlb->mm->mm_users) < 2 || cpumask_equal(mm_cpumask(tlb->mm), cpumask_of(smp_processor_id()))) { kmem_cache_free(hugepte_cache, hugepte); - put_cpu_var(hugepd_freelist_cur); + put_cpu_var(hugepd_freelist_cur); return; } =20
Sebastian