linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH -next v2 0/3] riscv: Fix two vdso issue
@ 2021-08-20 12:50 Tong Tiangen
  2021-08-20 12:50 ` [PATCH -next v2 1/3] riscv/vdso: Refactor asm/vdso.h Tong Tiangen
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Tong Tiangen @ 2021-08-20 12:50 UTC (permalink / raw)
  To: Paul Walmsley, Palmer Dabbelt, Palmer Dabbelt, Albert Ou
  Cc: linux-riscv, linux-kernel, Tong Tiangen

v2->v1:
 Add patch "Refactor asm/vdso.h" to avoid vdso.lds syntax error if
 CONFIG_GENERIC_TIME_VSYSCALL=n.

1) Refactor the asm/vdso.h to avoid vdso.lds syntax error.

2) Move vdso data page up front and introduce enum vvar_pages, To pave the
way for the subsequent support of TIME_NS, the support of TIME_NS will be
issued in the later patch.

3) In arch_setup_additional_pages(), make Wait for the lock in the
killable mode and return with EINTR if the task got killed while waiting.

Tong Tiangen (3):
  riscv/vdso: Refactor asm/vdso.h
  riscv/vdso: Move vdso data page up front
  riscv/vdso: make arch_setup_additional_pages wait for mmap_sem for
    write killable

 arch/riscv/include/asm/syscall.h  |  1 +
 arch/riscv/include/asm/vdso.h     | 10 ++----
 arch/riscv/kernel/syscall_table.c |  1 -
 arch/riscv/kernel/vdso.c          | 53 +++++++++++++++++++------------
 arch/riscv/kernel/vdso/vdso.lds.S |  3 +-
 5 files changed, 39 insertions(+), 29 deletions(-)

-- 
2.18.0.huawei.25


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH -next v2 1/3] riscv/vdso: Refactor asm/vdso.h
  2021-08-20 12:50 [PATCH -next v2 0/3] riscv: Fix two vdso issue Tong Tiangen
@ 2021-08-20 12:50 ` Tong Tiangen
  2021-08-20 12:50 ` [PATCH -next v2 2/3] riscv/vdso: Move vdso data page up front Tong Tiangen
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Tong Tiangen @ 2021-08-20 12:50 UTC (permalink / raw)
  To: Paul Walmsley, Palmer Dabbelt, Palmer Dabbelt, Albert Ou
  Cc: linux-riscv, linux-kernel, Tong Tiangen

The asm/vdso.h will be included in vdso.lds.S in the next patch, the
following cleanup is needed to avoid syntax error:

 1.the declaration of sys_riscv_flush_icache() is moved into asm/syscall.h.
 2.the definition of struct vdso_data is moved into kernel/vdso.c.
 2.the definition of VDSO_SYMBOL is placed under "#ifndef __ASSEMBLY__".

Also remove the redundant linux/types.h include.

Signed-off-by: Tong Tiangen <tongtiangen@huawei.com>
---
 arch/riscv/include/asm/syscall.h  |  1 +
 arch/riscv/include/asm/vdso.h     | 10 ++--------
 arch/riscv/kernel/syscall_table.c |  1 -
 arch/riscv/kernel/vdso.c          |  5 ++++-
 4 files changed, 7 insertions(+), 10 deletions(-)

diff --git a/arch/riscv/include/asm/syscall.h b/arch/riscv/include/asm/syscall.h
index b933b1583c9f..34fbb3ea21d5 100644
--- a/arch/riscv/include/asm/syscall.h
+++ b/arch/riscv/include/asm/syscall.h
@@ -82,4 +82,5 @@ static inline int syscall_get_arch(struct task_struct *task)
 #endif
 }
 
+asmlinkage long sys_riscv_flush_icache(uintptr_t, uintptr_t, uintptr_t);
 #endif	/* _ASM_RISCV_SYSCALL_H */
diff --git a/arch/riscv/include/asm/vdso.h b/arch/riscv/include/asm/vdso.h
index 1453a2f563bc..c1651589dd9b 100644
--- a/arch/riscv/include/asm/vdso.h
+++ b/arch/riscv/include/asm/vdso.h
@@ -8,13 +8,7 @@
 #ifndef _ASM_RISCV_VDSO_H
 #define _ASM_RISCV_VDSO_H
 
-#include <linux/types.h>
-
-#ifndef CONFIG_GENERIC_TIME_VSYSCALL
-struct vdso_data {
-};
-#endif
-
+#ifndef __ASSEMBLY__
 /*
  * The VDSO symbols are mapped into Linux so we can just use regular symbol
  * addressing to get their offsets in userspace.  The symbols are mapped at an
@@ -29,6 +23,6 @@ struct vdso_data {
 	(void __user *)((unsigned long)(base) + __vdso_##name);			\
 })
 
-asmlinkage long sys_riscv_flush_icache(uintptr_t, uintptr_t, uintptr_t);
+#endif
 
 #endif /* _ASM_RISCV_VDSO_H */
diff --git a/arch/riscv/kernel/syscall_table.c b/arch/riscv/kernel/syscall_table.c
index a63c667c27b3..44b1420a2270 100644
--- a/arch/riscv/kernel/syscall_table.c
+++ b/arch/riscv/kernel/syscall_table.c
@@ -7,7 +7,6 @@
 #include <linux/linkage.h>
 #include <linux/syscalls.h>
 #include <asm-generic/syscalls.h>
-#include <asm/vdso.h>
 #include <asm/syscall.h>
 
 #undef __SYSCALL
diff --git a/arch/riscv/kernel/vdso.c b/arch/riscv/kernel/vdso.c
index 25a3b8849599..72e93d218335 100644
--- a/arch/riscv/kernel/vdso.c
+++ b/arch/riscv/kernel/vdso.c
@@ -12,10 +12,13 @@
 #include <linux/binfmts.h>
 #include <linux/err.h>
 #include <asm/page.h>
+#include <asm/vdso.h>
+
 #ifdef CONFIG_GENERIC_TIME_VSYSCALL
 #include <vdso/datapage.h>
 #else
-#include <asm/vdso.h>
+struct vdso_data {
+};
 #endif
 
 extern char vdso_start[], vdso_end[];
-- 
2.18.0.huawei.25


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH -next v2 2/3] riscv/vdso: Move vdso data page up front
  2021-08-20 12:50 [PATCH -next v2 0/3] riscv: Fix two vdso issue Tong Tiangen
  2021-08-20 12:50 ` [PATCH -next v2 1/3] riscv/vdso: Refactor asm/vdso.h Tong Tiangen
@ 2021-08-20 12:50 ` Tong Tiangen
  2021-08-20 12:50 ` [PATCH -next v2 3/3] riscv/vdso: make arch_setup_additional_pages wait for mmap_sem for write killable Tong Tiangen
  2021-08-23  2:02 ` [PATCH -next v2 0/3] riscv: Fix two vdso issue Kefeng Wang
  3 siblings, 0 replies; 5+ messages in thread
From: Tong Tiangen @ 2021-08-20 12:50 UTC (permalink / raw)
  To: Paul Walmsley, Palmer Dabbelt, Palmer Dabbelt, Albert Ou
  Cc: linux-riscv, linux-kernel, Tong Tiangen

As commit 601255ae3c98 ("arm64: vdso: move data page before code pages"), the
same issue exists on riscv, testcase is shown below, make sure that vdso.so is
bigger than page size,

  struct timespec tp;
  clock_gettime(5, &tp);
  printf("tv_sec: %ld, tv_nsec: %ld\n", tp.tv_sec, tp.tv_nsec);

without this patch, test result : tv_sec: 0, tv_nsec: 0
   with this patch, test result : tv_sec: 1629271537, tv_nsec: 748000000

Move the vdso data page in front of the VDSO area to fix the issue.

Fixes: ad5d1122b82fb ("riscv: use vDSO common flow to reduce the latency of the time-related functions")
Signed-off-by: Tong Tiangen <tongtiangen@huawei.com>
---
 arch/riscv/include/asm/vdso.h     |  2 ++
 arch/riscv/kernel/vdso.c          | 44 ++++++++++++++++++-------------
 arch/riscv/kernel/vdso/vdso.lds.S |  3 ++-
 3 files changed, 30 insertions(+), 19 deletions(-)

diff --git a/arch/riscv/include/asm/vdso.h b/arch/riscv/include/asm/vdso.h
index c1651589dd9b..55f513c51016 100644
--- a/arch/riscv/include/asm/vdso.h
+++ b/arch/riscv/include/asm/vdso.h
@@ -8,6 +8,8 @@
 #ifndef _ASM_RISCV_VDSO_H
 #define _ASM_RISCV_VDSO_H
 
+#define __VVAR_PAGES    1
+
 #ifndef __ASSEMBLY__
 /*
  * The VDSO symbols are mapped into Linux so we can just use regular symbol
diff --git a/arch/riscv/kernel/vdso.c b/arch/riscv/kernel/vdso.c
index 72e93d218335..e7bd92d8749b 100644
--- a/arch/riscv/kernel/vdso.c
+++ b/arch/riscv/kernel/vdso.c
@@ -23,6 +23,13 @@ struct vdso_data {
 
 extern char vdso_start[], vdso_end[];
 
+enum vvar_pages {
+	VVAR_DATA_PAGE_OFFSET,
+	VVAR_NR_PAGES,
+};
+
+#define VVAR_SIZE  (VVAR_NR_PAGES << PAGE_SHIFT)
+
 static unsigned int vdso_pages __ro_after_init;
 static struct page **vdso_pagelist __ro_after_init;
 
@@ -41,7 +48,7 @@ static int __init vdso_init(void)
 
 	vdso_pages = (vdso_end - vdso_start) >> PAGE_SHIFT;
 	vdso_pagelist =
-		kcalloc(vdso_pages + 1, sizeof(struct page *), GFP_KERNEL);
+		kcalloc(vdso_pages + VVAR_NR_PAGES, sizeof(struct page *), GFP_KERNEL);
 	if (unlikely(vdso_pagelist == NULL)) {
 		pr_err("vdso: pagelist allocation failed\n");
 		return -ENOMEM;
@@ -66,7 +73,9 @@ int arch_setup_additional_pages(struct linux_binprm *bprm,
 	unsigned long vdso_base, vdso_len;
 	int ret;
 
-	vdso_len = (vdso_pages + 1) << PAGE_SHIFT;
+	BUILD_BUG_ON(VVAR_NR_PAGES != __VVAR_PAGES);
+
+	vdso_len = (vdso_pages + VVAR_NR_PAGES) << PAGE_SHIFT;
 
 	mmap_write_lock(mm);
 	vdso_base = get_unmapped_area(NULL, 0, vdso_len, 0, 0);
@@ -75,29 +84,28 @@ int arch_setup_additional_pages(struct linux_binprm *bprm,
 		goto end;
 	}
 
-	/*
-	 * Put vDSO base into mm struct. We need to do this before calling
-	 * install_special_mapping or the perf counter mmap tracking code
-	 * will fail to recognise it as a vDSO (since arch_vma_name fails).
-	 */
-	mm->context.vdso = (void *)vdso_base;
+	mm->context.vdso = NULL;
+	ret = install_special_mapping(mm, vdso_base, VVAR_SIZE,
+		(VM_READ | VM_MAYREAD), &vdso_pagelist[vdso_pages]);
+	if (unlikely(ret))
+		goto end;
 
 	ret =
-	   install_special_mapping(mm, vdso_base, vdso_pages << PAGE_SHIFT,
+	   install_special_mapping(mm, vdso_base + VVAR_SIZE,
+		vdso_pages << PAGE_SHIFT,
 		(VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC),
 		vdso_pagelist);
 
-	if (unlikely(ret)) {
-		mm->context.vdso = NULL;
+	if (unlikely(ret))
 		goto end;
-	}
 
-	vdso_base += (vdso_pages << PAGE_SHIFT);
-	ret = install_special_mapping(mm, vdso_base, PAGE_SIZE,
-		(VM_READ | VM_MAYREAD), &vdso_pagelist[vdso_pages]);
+	/*
+	 * Put vDSO base into mm struct. We need to do this before calling
+	 * install_special_mapping or the perf counter mmap tracking code
+	 * will fail to recognise it as a vDSO (since arch_vma_name fails).
+	 */
+	mm->context.vdso = (void *)vdso_base + VVAR_SIZE;
 
-	if (unlikely(ret))
-		mm->context.vdso = NULL;
 end:
 	mmap_write_unlock(mm);
 	return ret;
@@ -108,7 +116,7 @@ const char *arch_vma_name(struct vm_area_struct *vma)
 	if (vma->vm_mm && (vma->vm_start == (long)vma->vm_mm->context.vdso))
 		return "[vdso]";
 	if (vma->vm_mm && (vma->vm_start ==
-			   (long)vma->vm_mm->context.vdso + PAGE_SIZE))
+			   (long)vma->vm_mm->context.vdso - VVAR_SIZE))
 		return "[vdso_data]";
 	return NULL;
 }
diff --git a/arch/riscv/kernel/vdso/vdso.lds.S b/arch/riscv/kernel/vdso/vdso.lds.S
index e6f558bca71b..e9111f700af0 100644
--- a/arch/riscv/kernel/vdso/vdso.lds.S
+++ b/arch/riscv/kernel/vdso/vdso.lds.S
@@ -3,12 +3,13 @@
  * Copyright (C) 2012 Regents of the University of California
  */
 #include <asm/page.h>
+#include <asm/vdso.h>
 
 OUTPUT_ARCH(riscv)
 
 SECTIONS
 {
-	PROVIDE(_vdso_data = . + PAGE_SIZE);
+	PROVIDE(_vdso_data = . - __VVAR_PAGES * PAGE_SIZE);
 	. = SIZEOF_HEADERS;
 
 	.hash		: { *(.hash) }			:text
-- 
2.18.0.huawei.25


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH -next v2 3/3] riscv/vdso: make arch_setup_additional_pages wait for mmap_sem for write killable
  2021-08-20 12:50 [PATCH -next v2 0/3] riscv: Fix two vdso issue Tong Tiangen
  2021-08-20 12:50 ` [PATCH -next v2 1/3] riscv/vdso: Refactor asm/vdso.h Tong Tiangen
  2021-08-20 12:50 ` [PATCH -next v2 2/3] riscv/vdso: Move vdso data page up front Tong Tiangen
@ 2021-08-20 12:50 ` Tong Tiangen
  2021-08-23  2:02 ` [PATCH -next v2 0/3] riscv: Fix two vdso issue Kefeng Wang
  3 siblings, 0 replies; 5+ messages in thread
From: Tong Tiangen @ 2021-08-20 12:50 UTC (permalink / raw)
  To: Paul Walmsley, Palmer Dabbelt, Palmer Dabbelt, Albert Ou
  Cc: linux-riscv, linux-kernel, Tong Tiangen

riscv architectures relying on mmap_sem for write in their
arch_setup_additional_pages. If the waiting task gets killed by the oom killer
it would block oom_reaper from asynchronous address space reclaim and reduce
the chances of timely OOM resolving.  Wait for the lock in the killable mode
and return with EINTR if the task got killed while waiting.

Signed-off-by: Tong Tiangen <tongtiangen@huawei.com>
---
 arch/riscv/kernel/vdso.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/riscv/kernel/vdso.c b/arch/riscv/kernel/vdso.c
index e7bd92d8749b..b70956d80408 100644
--- a/arch/riscv/kernel/vdso.c
+++ b/arch/riscv/kernel/vdso.c
@@ -77,7 +77,9 @@ int arch_setup_additional_pages(struct linux_binprm *bprm,
 
 	vdso_len = (vdso_pages + VVAR_NR_PAGES) << PAGE_SHIFT;
 
-	mmap_write_lock(mm);
+	if (mmap_write_lock_killable(mm))
+		return -EINTR;
+
 	vdso_base = get_unmapped_area(NULL, 0, vdso_len, 0, 0);
 	if (IS_ERR_VALUE(vdso_base)) {
 		ret = vdso_base;
-- 
2.18.0.huawei.25


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH -next v2 0/3] riscv: Fix two vdso issue
  2021-08-20 12:50 [PATCH -next v2 0/3] riscv: Fix two vdso issue Tong Tiangen
                   ` (2 preceding siblings ...)
  2021-08-20 12:50 ` [PATCH -next v2 3/3] riscv/vdso: make arch_setup_additional_pages wait for mmap_sem for write killable Tong Tiangen
@ 2021-08-23  2:02 ` Kefeng Wang
  3 siblings, 0 replies; 5+ messages in thread
From: Kefeng Wang @ 2021-08-23  2:02 UTC (permalink / raw)
  To: Tong Tiangen, Paul Walmsley, Palmer Dabbelt, Palmer Dabbelt, Albert Ou
  Cc: linux-riscv, linux-kernel


On 2021/8/20 20:50, Tong Tiangen wrote:
> v2->v1:
>   Add patch "Refactor asm/vdso.h" to avoid vdso.lds syntax error if
>   CONFIG_GENERIC_TIME_VSYSCALL=n.

This is better than v1.

>
> 1) Refactor the asm/vdso.h to avoid vdso.lds syntax error.
>
> 2) Move vdso data page up front
Move  vdso data page before code page could save the problem which the 
.text

section could be bigger than PAGE_SIZE.

> and introduce enum vvar_pages, To pave the
> way for the subsequent support of TIME_NS, the support of TIME_NS will be
> issued in the later patch.
This makes it easier to introduce new features TIME_NS.

>
> 3) In arch_setup_additional_pages(), make Wait for the lock in the
> killable mode and return with EINTR if the task got killed while waiting.
For series,

Reviewed-by: Kefeng Wang <wangkefeng.wang@huawei.com>
> Tong Tiangen (3):
>    riscv/vdso: Refactor asm/vdso.h
>    riscv/vdso: Move vdso data page up front
>    riscv/vdso: make arch_setup_additional_pages wait for mmap_sem for
>      write killable
>
>   arch/riscv/include/asm/syscall.h  |  1 +
>   arch/riscv/include/asm/vdso.h     | 10 ++----
>   arch/riscv/kernel/syscall_table.c |  1 -
>   arch/riscv/kernel/vdso.c          | 53 +++++++++++++++++++------------
>   arch/riscv/kernel/vdso/vdso.lds.S |  3 +-
>   5 files changed, 39 insertions(+), 29 deletions(-)
>

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2021-08-23  2:03 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-08-20 12:50 [PATCH -next v2 0/3] riscv: Fix two vdso issue Tong Tiangen
2021-08-20 12:50 ` [PATCH -next v2 1/3] riscv/vdso: Refactor asm/vdso.h Tong Tiangen
2021-08-20 12:50 ` [PATCH -next v2 2/3] riscv/vdso: Move vdso data page up front Tong Tiangen
2021-08-20 12:50 ` [PATCH -next v2 3/3] riscv/vdso: make arch_setup_additional_pages wait for mmap_sem for write killable Tong Tiangen
2021-08-23  2:02 ` [PATCH -next v2 0/3] riscv: Fix two vdso issue Kefeng Wang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).