linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH -next 0/2] riscv: Fix two vdso issue
@ 2021-08-19  3:06 Tong Tiangen
  2021-08-19  3:06 ` [PATCH -next 1/2] riscv/vdso: Move vdso data page up front Tong Tiangen
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Tong Tiangen @ 2021-08-19  3:06 UTC (permalink / raw)
  To: Paul Walmsley, Palmer Dabbelt, Palmer Dabbelt, Albert Ou
  Cc: linux-riscv, linux-kernel, Tong Tiangen

1) 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.

2) 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 (2):
  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  |  2 ++
 arch/riscv/include/asm/vdso.h     |  4 +--
 arch/riscv/kernel/vdso.c          | 51 ++++++++++++++++++-------------
 arch/riscv/kernel/vdso/vdso.lds.S |  3 +-
 4 files changed, 36 insertions(+), 24 deletions(-)

-- 
2.18.0.huawei.25


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

* [PATCH -next 1/2] riscv/vdso: Move vdso data page up front
  2021-08-19  3:06 [PATCH -next 0/2] riscv: Fix two vdso issue Tong Tiangen
@ 2021-08-19  3:06 ` Tong Tiangen
  2021-08-19  9:43   ` kernel test robot
  2021-08-19  3:06 ` [PATCH -next 2/2] riscv/vdso: make arch_setup_additional_pages wait for mmap_sem for write killable Tong Tiangen
  2021-08-19  5:24 ` [PATCH -next 0/2] riscv: Fix two vdso issue Kefeng Wang
  2 siblings, 1 reply; 5+ messages in thread
From: Tong Tiangen @ 2021-08-19  3:06 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.

In this patch, I moved the declaration of sys_riscv_flush_icache from asm/vdso.h
to asm/syscall.h, the reason is asm/vdso.h is included in vdso.lds.S, If the
declaration is placed here, This will introduce syntax error.

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/syscall.h  |  2 ++
 arch/riscv/include/asm/vdso.h     |  4 +--
 arch/riscv/kernel/vdso.c          | 47 ++++++++++++++++++-------------
 arch/riscv/kernel/vdso/vdso.lds.S |  3 +-
 4 files changed, 33 insertions(+), 23 deletions(-)

diff --git a/arch/riscv/include/asm/syscall.h b/arch/riscv/include/asm/syscall.h
index b933b1583c9f..50704bd5ca3e 100644
--- a/arch/riscv/include/asm/syscall.h
+++ b/arch/riscv/include/asm/syscall.h
@@ -82,4 +82,6 @@ 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..564741266580 100644
--- a/arch/riscv/include/asm/vdso.h
+++ b/arch/riscv/include/asm/vdso.h
@@ -10,6 +10,8 @@
 
 #include <linux/types.h>
 
+#define __VVAR_PAGES    1
+
 #ifndef CONFIG_GENERIC_TIME_VSYSCALL
 struct vdso_data {
 };
@@ -29,6 +31,4 @@ struct vdso_data {
 	(void __user *)((unsigned long)(base) + __vdso_##name);			\
 })
 
-asmlinkage long sys_riscv_flush_icache(uintptr_t, uintptr_t, uintptr_t);
-
 #endif /* _ASM_RISCV_VDSO_H */
diff --git a/arch/riscv/kernel/vdso.c b/arch/riscv/kernel/vdso.c
index 25a3b8849599..5fecd5529eff 100644
--- a/arch/riscv/kernel/vdso.c
+++ b/arch/riscv/kernel/vdso.c
@@ -14,12 +14,18 @@
 #include <asm/page.h>
 #ifdef CONFIG_GENERIC_TIME_VSYSCALL
 #include <vdso/datapage.h>
-#else
-#include <asm/vdso.h>
 #endif
+#include <asm/vdso.h>
 
 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;
 
@@ -38,7 +44,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;
@@ -63,7 +69,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);
@@ -72,29 +80,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;
@@ -105,7 +112,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 2/2] riscv/vdso: make arch_setup_additional_pages wait for mmap_sem for write killable
  2021-08-19  3:06 [PATCH -next 0/2] riscv: Fix two vdso issue Tong Tiangen
  2021-08-19  3:06 ` [PATCH -next 1/2] riscv/vdso: Move vdso data page up front Tong Tiangen
@ 2021-08-19  3:06 ` Tong Tiangen
  2021-08-19  5:24 ` [PATCH -next 0/2] riscv: Fix two vdso issue Kefeng Wang
  2 siblings, 0 replies; 5+ messages in thread
From: Tong Tiangen @ 2021-08-19  3:06 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 5fecd5529eff..54629c11c639 100644
--- a/arch/riscv/kernel/vdso.c
+++ b/arch/riscv/kernel/vdso.c
@@ -73,7 +73,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 0/2] riscv: Fix two vdso issue
  2021-08-19  3:06 [PATCH -next 0/2] riscv: Fix two vdso issue Tong Tiangen
  2021-08-19  3:06 ` [PATCH -next 1/2] riscv/vdso: Move vdso data page up front Tong Tiangen
  2021-08-19  3:06 ` [PATCH -next 2/2] riscv/vdso: make arch_setup_additional_pages wait for mmap_sem for write killable Tong Tiangen
@ 2021-08-19  5:24 ` Kefeng Wang
  2 siblings, 0 replies; 5+ messages in thread
From: Kefeng Wang @ 2021-08-19  5:24 UTC (permalink / raw)
  To: Tong Tiangen, Paul Walmsley, Palmer Dabbelt, Palmer Dabbelt, Albert Ou
  Cc: linux-riscv, linux-kernel

On 2021/8/19 11:06, Tong Tiangen wrote:
> 1) 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.
>
> 2) 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 (2):
>    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  |  2 ++
>   arch/riscv/include/asm/vdso.h     |  4 +--
>   arch/riscv/kernel/vdso.c          | 51 ++++++++++++++++++-------------
>   arch/riscv/kernel/vdso/vdso.lds.S |  3 +-
>   4 files changed, 36 insertions(+), 24 deletions(-)
>

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

* Re: [PATCH -next 1/2] riscv/vdso: Move vdso data page up front
  2021-08-19  3:06 ` [PATCH -next 1/2] riscv/vdso: Move vdso data page up front Tong Tiangen
@ 2021-08-19  9:43   ` kernel test robot
  0 siblings, 0 replies; 5+ messages in thread
From: kernel test robot @ 2021-08-19  9:43 UTC (permalink / raw)
  To: Tong Tiangen, Paul Walmsley, Palmer Dabbelt, Albert Ou
  Cc: kbuild-all, linux-riscv, linux-kernel, Tong Tiangen

[-- Attachment #1: Type: text/plain, Size: 1381 bytes --]

Hi Tong,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on next-20210818]

url:    https://github.com/0day-ci/linux/commits/Tong-Tiangen/riscv-Fix-two-vdso-issue/20210819-105917
base:    f26c3abc432a2026ba9ee7767061a1f88aead6ec
config: riscv-randconfig-r042-20210819 (attached as .config)
compiler: riscv32-linux-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/f2561fc9ba0ac1f90464a354588b26c5f99b2992
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Tong-Tiangen/riscv-Fix-two-vdso-issue/20210819-105917
        git checkout f2561fc9ba0ac1f90464a354588b26c5f99b2992
        # save the attached .config to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=riscv SHELL=/bin/bash

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

>> riscv32-linux-objcopy: 'arch/riscv/kernel/vdso/vdso.so.dbg': No such file

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 33719 bytes --]

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

end of thread, other threads:[~2021-08-19  9:44 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-08-19  3:06 [PATCH -next 0/2] riscv: Fix two vdso issue Tong Tiangen
2021-08-19  3:06 ` [PATCH -next 1/2] riscv/vdso: Move vdso data page up front Tong Tiangen
2021-08-19  9:43   ` kernel test robot
2021-08-19  3:06 ` [PATCH -next 2/2] riscv/vdso: make arch_setup_additional_pages wait for mmap_sem for write killable Tong Tiangen
2021-08-19  5:24 ` [PATCH -next 0/2] 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).