diff mbox series

[1/3] riscv: Introduce huge page support for 32/64bit kernel

Message ID 20181210062146.24951-2-aghiti@upmem.com (mailing list archive)
State New, archived
Headers show
Series Hugetlbfs support for riscv | expand

Commit Message

Alexandre Ghiti Dec. 10, 2018, 6:21 a.m. UTC
This patch implements both 4MB huge page support for 32bit kernel
and 2MB/1GB huge pages support for 64bit kernel.

Signed-off-by: Alexandre Ghiti <aghiti@upmem.com>
---
 arch/riscv/Kconfig               |  7 +++++++
 arch/riscv/include/asm/hugetlb.h | 22 ++++++++++++++++++++++
 arch/riscv/include/asm/page.h    | 10 ++++++++++
 arch/riscv/include/asm/pgtable.h |  6 +++++-
 arch/riscv/mm/Makefile           |  2 ++
 arch/riscv/mm/hugetlbpage.c      | 36 ++++++++++++++++++++++++++++++++++++
 6 files changed, 82 insertions(+), 1 deletion(-)
 create mode 100644 arch/riscv/include/asm/hugetlb.h
 create mode 100644 arch/riscv/mm/hugetlbpage.c

Comments

Paul Walmsley Jan. 11, 2019, 6:18 a.m. UTC | #1
Hello Alexandre,

On Mon, 10 Dec 2018, Alexandre Ghiti wrote:

> This patch implements both 4MB huge page support for 32bit kernel
> and 2MB/1GB huge pages support for 64bit kernel.
> 
> Signed-off-by: Alexandre Ghiti <aghiti@upmem.com>

This patch introduces a few minor checkpatch and strict checkpatch 
warnings, when tested against both v4.20 and v5.0-rc1 checkpatch versions.  
Could you fix those?  The other two patches in the series look OK from 
that point of view.


- Paul
Alexandre Ghiti Jan. 11, 2019, 1:58 p.m. UTC | #2
On 01/11/2019 07:18 AM, Paul Walmsley wrote:
> Hello Alexandre,
>
> On Mon, 10 Dec 2018, Alexandre Ghiti wrote:
>
>> This patch implements both 4MB huge page support for 32bit kernel
>> and 2MB/1GB huge pages support for 64bit kernel.
>>
>> Signed-off-by: Alexandre Ghiti <aghiti@upmem.com>
> This patch introduces a few minor checkpatch and strict checkpatch
> warnings, when tested against both v4.20 and v5.0-rc1 checkpatch versions.
> Could you fix those?  The other two patches in the series look OK from
> that point of view.

Yes, I had noted those warnings:

- the SPDX warning is weird, in all *.c files, the script seems to 
accept only
   "// SPDX-License-Identifier: GPL-2.0" and not "/* 
SPDX-License-Identifier: GPL-2.0 */".
   But on *.h files, this the contrary, maybe I missed something, I am going
   to take a look at the script spdxcheck.py.
   Note that kernel/ftrace.c and kernel/perf_event.c raise the same 
strange warning.

- I'll change the "printk(KERN_ERR" into a pr_err.

- I'll ignore the last warning regarding the new file.

Thanks for your feedback Paul,

Alex

>
>
> - Paul
>
> _______________________________________________
> linux-riscv mailing list
> linux-riscv@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-riscv
Christoph Hellwig Jan. 15, 2019, 4:11 p.m. UTC | #3
> +#ifdef CONFIG_ARCH_HAS_GIGANTIC_PAGE
> +static inline bool gigantic_page_supported(void) { return true; }

Can you move each brace and the return statement to an line of its
own?  Just to keep the code a little easier to read.

> +int pud_huge(pud_t pud)
> +{
> +	return pud_present(pud)
> +		&& (pud_val(pud) & (_PAGE_READ | _PAGE_WRITE | _PAGE_EXEC));
> +}
> +
> +int pmd_huge(pmd_t pmd)
> +{
> +	return pmd_present(pmd)
> +		&& (pmd_val(pmd) & (_PAGE_READ | _PAGE_WRITE | _PAGE_EXEC));
> +}

Kinda sad that we can't easily have these as inline functions, but not
really your fault.  Note that the && should move to the first line
of the multi-line statement.

> +#if defined(CONFIG_64BIT)
> +	} else if (ps == PUD_SIZE) {
> +		hugetlb_add_hstate(PUD_SHIFT - PAGE_SHIFT);
> +#endif

I think this could be:

	} else if (IS_ENABLED(CONFIG_64BIT) && ps == PUD_SIZE) {
		hugetlb_add_hstate(PUD_SHIFT - PAGE_SHIFT);
Alexandre Ghiti Jan. 15, 2019, 6:52 p.m. UTC | #4
On 1/15/19 4:11 PM, Christoph Hellwig wrote:
>> +#ifdef CONFIG_ARCH_HAS_GIGANTIC_PAGE
>> +static inline bool gigantic_page_supported(void) { return true; }
> Can you move each brace and the return statement to an line of its
> own?  Just to keep the code a little easier to read.
>
>> +int pud_huge(pud_t pud)
>> +{
>> +	return pud_present(pud)
>> +		&& (pud_val(pud) & (_PAGE_READ | _PAGE_WRITE | _PAGE_EXEC));
>> +}
>> +
>> +int pmd_huge(pmd_t pmd)
>> +{
>> +	return pmd_present(pmd)
>> +		&& (pmd_val(pmd) & (_PAGE_READ | _PAGE_WRITE | _PAGE_EXEC));
>> +}
> Kinda sad that we can't easily have these as inline functions, but not
> really your fault.  Note that the && should move to the first line
> of the multi-line statement.
>
>> +#if defined(CONFIG_64BIT)
>> +	} else if (ps == PUD_SIZE) {
>> +		hugetlb_add_hstate(PUD_SHIFT - PAGE_SHIFT);
>> +#endif
> I think this could be:
>
> 	} else if (IS_ENABLED(CONFIG_64BIT) && ps == PUD_SIZE) {
> 		hugetlb_add_hstate(PUD_SHIFT - PAGE_SHIFT);
>
Thanks Christoph, I will send a new version with your modifications.


>
> _______________________________________________
> linux-riscv mailing list
> linux-riscv@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-riscv
diff mbox series

Patch

diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 55da93f4e818..7bb21533d927 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -57,6 +57,12 @@  config PAGE_OFFSET
 	default 0xffffffff80000000 if 64BIT && MAXPHYSMEM_2GB
 	default 0xffffffe000000000 if 64BIT && MAXPHYSMEM_128GB
 
+config ARCH_WANT_GENERAL_HUGETLB
+	def_bool y
+
+config SYS_SUPPORTS_HUGETLBFS
+	def_bool y
+
 config STACKTRACE_SUPPORT
 	def_bool y
 
@@ -118,6 +124,7 @@  config ARCH_RV64I
 	select HAVE_DYNAMIC_FTRACE
 	select HAVE_DYNAMIC_FTRACE_WITH_REGS
 	select SWIOTLB
+	select ARCH_HAS_GIGANTIC_PAGE if (MEMORY_ISOLATION && COMPACTION) || CMA
 
 endchoice
 
diff --git a/arch/riscv/include/asm/hugetlb.h b/arch/riscv/include/asm/hugetlb.h
new file mode 100644
index 000000000000..b7d88cf4e315
--- /dev/null
+++ b/arch/riscv/include/asm/hugetlb.h
@@ -0,0 +1,22 @@ 
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_RISCV_HUGETLB_H
+#define _ASM_RISCV_HUGETLB_H
+
+#include <asm-generic/hugetlb.h>
+#include <asm/page.h>
+
+static inline int is_hugepage_only_range(struct mm_struct *mm,
+					 unsigned long addr,
+					 unsigned long len) {
+	return 0;
+}
+
+static inline void arch_clear_hugepage_flags(struct page *page)
+{
+}
+
+#ifdef CONFIG_ARCH_HAS_GIGANTIC_PAGE
+static inline bool gigantic_page_supported(void) { return true; }
+#endif
+
+#endif /* _ASM_RISCV_HUGETLB_H */
diff --git a/arch/riscv/include/asm/page.h b/arch/riscv/include/asm/page.h
index 06cfbb3aacbb..ceaa73b82b25 100644
--- a/arch/riscv/include/asm/page.h
+++ b/arch/riscv/include/asm/page.h
@@ -24,6 +24,16 @@ 
 #define PAGE_SIZE	(_AC(1, UL) << PAGE_SHIFT)
 #define PAGE_MASK	(~(PAGE_SIZE - 1))
 
+#ifdef CONFIG_64BIT
+#define HUGE_MAX_HSTATE		2
+#else
+#define HUGE_MAX_HSTATE		1
+#endif
+#define HPAGE_SHIFT		PMD_SHIFT
+#define HPAGE_SIZE		(_AC(1, UL) << HPAGE_SHIFT)
+#define HPAGE_MASK              (~(HPAGE_SIZE - 1))
+#define HUGETLB_PAGE_ORDER      (HPAGE_SHIFT - PAGE_SHIFT)
+
 /*
  * PAGE_OFFSET -- the first address of the first page of memory.
  * When not using MMU this corresponds to the first free page in
diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h
index 16301966d65b..50ea3d6e7de7 100644
--- a/arch/riscv/include/asm/pgtable.h
+++ b/arch/riscv/include/asm/pgtable.h
@@ -121,7 +121,6 @@  static inline void pmd_clear(pmd_t *pmdp)
 	set_pmd(pmdp, __pmd(0));
 }
 
-
 static inline pgd_t pfn_pgd(unsigned long pfn, pgprot_t prot)
 {
 	return __pgd((pfn << _PAGE_PFN_SHIFT) | pgprot_val(prot));
@@ -258,6 +257,11 @@  static inline pte_t pte_mkspecial(pte_t pte)
 	return __pte(pte_val(pte) | _PAGE_SPECIAL);
 }
 
+static inline pte_t pte_mkhuge(pte_t pte)
+{
+	return pte;
+}
+
 /* Modify page protection bits */
 static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
 {
diff --git a/arch/riscv/mm/Makefile b/arch/riscv/mm/Makefile
index eb22ab49b3e0..eeadb130d7cf 100644
--- a/arch/riscv/mm/Makefile
+++ b/arch/riscv/mm/Makefile
@@ -3,3 +3,5 @@  obj-y += fault.o
 obj-y += extable.o
 obj-y += ioremap.o
 obj-y += cacheflush.o
+
+obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
diff --git a/arch/riscv/mm/hugetlbpage.c b/arch/riscv/mm/hugetlbpage.c
new file mode 100644
index 000000000000..7bac8b22d486
--- /dev/null
+++ b/arch/riscv/mm/hugetlbpage.c
@@ -0,0 +1,36 @@ 
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <linux/hugetlb.h>
+#include <linux/err.h>
+
+int pud_huge(pud_t pud)
+{
+	return pud_present(pud)
+		&& (pud_val(pud) & (_PAGE_READ | _PAGE_WRITE | _PAGE_EXEC));
+}
+
+int pmd_huge(pmd_t pmd)
+{
+	return pmd_present(pmd)
+		&& (pmd_val(pmd) & (_PAGE_READ | _PAGE_WRITE | _PAGE_EXEC));
+}
+
+static __init int setup_hugepagesz(char *opt)
+{
+	unsigned long ps = memparse(opt, &opt);
+
+	if (ps == HPAGE_SIZE) {
+		hugetlb_add_hstate(HPAGE_SHIFT - PAGE_SHIFT);
+#if defined(CONFIG_64BIT)
+	} else if (ps == PUD_SIZE) {
+		hugetlb_add_hstate(PUD_SHIFT - PAGE_SHIFT);
+#endif
+	} else {
+		hugetlb_bad_size();
+		printk(KERN_ERR "hugepagesz: Unsupported page size %lu M\n",
+			ps >> 20);
+		return 0;
+	}
+
+	return 1;
+}
+__setup("hugepagesz=", setup_hugepagesz);