All of lore.kernel.org
 help / color / mirror / Atom feed
From: Michael Ellerman <mpe@ellerman.id.au>
To: Michal Hocko <mhocko@kernel.org>,
	Dan Williams <dan.j.williams@intel.com>
Cc: Jane Chu <jane.chu@oracle.com>,
	linux-nvdimm@lists.01.org,
	Benjamin Herrenschmidt <benh@kernel.crashing.org>,
	linux-mm@kvack.org, Paul Mackerras <paulus@samba.org>,
	akpm@linux-foundation.org
Subject: Re: [PATCH 1/2] mm, hugetlbfs: introduce ->pagesize() to vm_operations_struct
Date: Thu, 14 Dec 2017 00:07:01 +1100	[thread overview]
Message-ID: <87o9n2aia2.fsf@concordia.ellerman.id.au> (raw)
In-Reply-To: <20171210113715.GE20234@dhcp22.suse.cz>

Michal Hocko <mhocko@kernel.org> writes:

> On Thu 07-12-17 19:30:55, Dan Williams wrote:
>> When device-dax is operating in huge-page mode we want it to behave like
>> hugetlbfs and report the MMU page mapping size that is being enforced by
>> the vma. Similar to commit 31383c6865a5 "mm, hugetlbfs: introduce
>> ->split() to vm_operations_struct" it would be messy to teach
>> vma_mmu_pagesize() about device-dax page mapping sizes in the same
>> (hstate) way that hugetlbfs communicates this attribute.  Instead, these
>> patches introduce a new ->pagesize() vm operation.
>> 
>> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
>> Cc: Paul Mackerras <paulus@samba.org>
>> Cc: Michael Ellerman <mpe@ellerman.id.au>
>> Reported-by: Jane Chu <jane.chu@oracle.com>
>> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
>
> My build battery choked on the following
> In file included from drivers/infiniband/core/umem_odp.c:41:0:
> ./include/linux/hugetlb.h: In function 'vma_kernel_pagesize':
> ./include/linux/hugetlb.h:262:32: error: dereferencing pointer to incomplete type
>   if (vma->vm_ops && vma->vm_ops->pagesize)
>                                 ^
> ./include/linux/hugetlb.h:263:21: error: dereferencing pointer to incomplete type
>    return vma->vm_ops->pagesize(vma);
>
> I thought that adding #include <linux/mm.h> into linux/hugetlb.h would
> be sufficient but then it failed for powerpc defconfig which overrides
> vma_kernel_pagesize
> In file included from ./include/linux/hugetlb.h:452:0,
>                  from arch/powerpc/mm/hugetlbpage.c:14:
> ./arch/powerpc/include/asm/hugetlb.h:131:26: error: redefinition of 'vma_mmu_pagesize'
>  #define vma_mmu_pagesize vma_mmu_pagesize
>                           ^
> arch/powerpc/mm/hugetlbpage.c:563:15: note: in expansion of macro 'vma_mmu_pagesize'
>  unsigned long vma_mmu_pagesize(struct vm_area_struct *vma)
>                ^
> In file included from arch/powerpc/mm/hugetlbpage.c:14:0:
> ./include/linux/hugetlb.h:275:29: note: previous definition of 'vma_mmu_pagesize' was here
>  static inline unsigned long vma_mmu_pagesize(struct vm_area_struct *vma)
>
> So it looks this needs something more laborous.

This builds for me.

cheers


diff --git a/arch/powerpc/include/asm/hugetlb.h b/arch/powerpc/include/asm/hugetlb.h
index 14c9d44f355b..3cc6ca1bdaf2 100644
--- a/arch/powerpc/include/asm/hugetlb.h
+++ b/arch/powerpc/include/asm/hugetlb.h
@@ -123,6 +123,7 @@ void hugetlb_free_pgd_range(struct mmu_gather *tlb, unsigned long addr,
  * to override the version in mm/hugetlb.c
  */
 #define vma_mmu_pagesize vma_mmu_pagesize
+unsigned long vma_mmu_pagesize(struct vm_area_struct *vma);
 
 /*
  * If the arch doesn't supply something else, assume that hugepage
diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c
index a9b9083c5e49..c6a2e577e842 100644
--- a/arch/powerpc/mm/hugetlbpage.c
+++ b/arch/powerpc/mm/hugetlbpage.c
@@ -568,10 +568,7 @@ unsigned long vma_mmu_pagesize(struct vm_area_struct *vma)
 	if (!radix_enabled())
 		return 1UL << mmu_psize_to_shift(psize);
 #endif
-	if (!is_vm_hugetlb_page(vma))
-		return PAGE_SIZE;
-
-	return huge_page_size(hstate_vma(vma));
+	return vma_kernel_pagesize(vma);
 }
 
 static inline bool is_power_of_4(unsigned long x)
diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
index 6e3696c7b35a..fe7b74325856 100644
--- a/include/linux/hugetlb.h
+++ b/include/linux/hugetlb.h
@@ -394,10 +394,6 @@ static inline unsigned long huge_page_size(struct hstate *h)
 	return (unsigned long)PAGE_SIZE << h->order;
 }
 
-extern unsigned long vma_kernel_pagesize(struct vm_area_struct *vma);
-
-extern unsigned long vma_mmu_pagesize(struct vm_area_struct *vma);
-
 static inline unsigned long huge_page_mask(struct hstate *h)
 {
 	return h->mask;
@@ -430,6 +426,30 @@ static inline unsigned int blocks_per_huge_page(struct hstate *h)
 
 #include <asm/hugetlb.h>
 
+/*
+ * Return the size of the pages allocated when backing a VMA. In the majority
+ * cases this will be same size as used by the page table entries.
+ */
+static inline unsigned long vma_kernel_pagesize(struct vm_area_struct *vma)
+{
+	if (vma->vm_ops && vma->vm_ops->pagesize)
+		return vma->vm_ops->pagesize(vma);
+	return PAGE_SIZE;
+}
+
+/*
+ * Return the page size being used by the MMU to back a VMA. In the majority
+ * of cases, the page size used by the kernel matches the MMU size. On
+ * architectures where it differs, an architecture-specific version of this
+ * function is required.
+ */
+#ifndef vma_mmu_pagesize
+static inline unsigned long vma_mmu_pagesize(struct vm_area_struct *vma)
+{
+	return vma_kernel_pagesize(vma);
+}
+#endif
+
 #ifndef arch_make_huge_pte
 static inline pte_t arch_make_huge_pte(pte_t entry, struct vm_area_struct *vma,
 				       struct page *page, int writable)
@@ -533,8 +553,6 @@ struct hstate {};
 #define page_hstate(page) NULL
 #define huge_page_size(h) PAGE_SIZE
 #define huge_page_mask(h) PAGE_MASK
-#define vma_kernel_pagesize(v) PAGE_SIZE
-#define vma_mmu_pagesize(v) PAGE_SIZE
 #define huge_page_order(h) 0
 #define huge_page_shift(h) PAGE_SHIFT
 static inline bool hstate_is_gigantic(struct hstate *h)
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 7661156552d3..1933499f896d 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -383,6 +383,7 @@ struct vm_operations_struct {
 	int (*huge_fault)(struct vm_fault *vmf, enum page_entry_size pe_size);
 	void (*map_pages)(struct vm_fault *vmf,
 			pgoff_t start_pgoff, pgoff_t end_pgoff);
+	unsigned long (*pagesize)(struct vm_area_struct * area);
 
 	/* notification that a previously read-only page is about to become
 	 * writable, if an error is returned it will cause a SIGBUS */
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index 4137fb67cd79..7c1c45bb3d08 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -629,36 +629,6 @@ pgoff_t linear_hugepage_index(struct vm_area_struct *vma,
 }
 EXPORT_SYMBOL_GPL(linear_hugepage_index);
 
-/*
- * Return the size of the pages allocated when backing a VMA. In the majority
- * cases this will be same size as used by the page table entries.
- */
-unsigned long vma_kernel_pagesize(struct vm_area_struct *vma)
-{
-	struct hstate *hstate;
-
-	if (!is_vm_hugetlb_page(vma))
-		return PAGE_SIZE;
-
-	hstate = hstate_vma(vma);
-
-	return 1UL << huge_page_shift(hstate);
-}
-EXPORT_SYMBOL_GPL(vma_kernel_pagesize);
-
-/*
- * Return the page size being used by the MMU to back a VMA. In the majority
- * of cases, the page size used by the kernel matches the MMU size. On
- * architectures where it differs, an architecture-specific version of this
- * function is required.
- */
-#ifndef vma_mmu_pagesize
-unsigned long vma_mmu_pagesize(struct vm_area_struct *vma)
-{
-	return vma_kernel_pagesize(vma);
-}
-#endif
-
 /*
  * Flags for MAP_PRIVATE reservations.  These are stored in the bottom
  * bits of the reservation map pointer, which are always clear due to
@@ -3142,6 +3112,13 @@ static int hugetlb_vm_op_split(struct vm_area_struct *vma, unsigned long addr)
 	return 0;
 }
 
+static unsigned long hugetlb_vm_op_pagesize(struct vm_area_struct *vma)
+{
+	struct hstate *hstate = hstate_vma(vma);
+
+	return 1UL << huge_page_shift(hstate);
+}
+
 /*
  * We cannot handle pagefaults against hugetlb pages at all.  They cause
  * handle_mm_fault() to try to instantiate regular-sized pages in the
@@ -3159,6 +3136,7 @@ const struct vm_operations_struct hugetlb_vm_ops = {
 	.open = hugetlb_vm_op_open,
 	.close = hugetlb_vm_op_close,
 	.split = hugetlb_vm_op_split,
+	.pagesize = hugetlb_vm_op_pagesize,
 };
 
 static pte_t make_huge_pte(struct vm_area_struct *vma, struct page *page,

_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

WARNING: multiple messages have this Message-ID (diff)
From: Michael Ellerman <mpe@ellerman.id.au>
To: Michal Hocko <mhocko@kernel.org>,
	Dan Williams <dan.j.williams@intel.com>
Cc: akpm@linux-foundation.org, Jane Chu <jane.chu@oracle.com>,
	linux-nvdimm@lists.01.org,
	Benjamin Herrenschmidt <benh@kernel.crashing.org>,
	linux-mm@kvack.org, Paul Mackerras <paulus@samba.org>
Subject: Re: [PATCH 1/2] mm, hugetlbfs: introduce ->pagesize() to vm_operations_struct
Date: Thu, 14 Dec 2017 00:07:01 +1100	[thread overview]
Message-ID: <87o9n2aia2.fsf@concordia.ellerman.id.au> (raw)
In-Reply-To: <20171210113715.GE20234@dhcp22.suse.cz>

Michal Hocko <mhocko@kernel.org> writes:

> On Thu 07-12-17 19:30:55, Dan Williams wrote:
>> When device-dax is operating in huge-page mode we want it to behave like
>> hugetlbfs and report the MMU page mapping size that is being enforced by
>> the vma. Similar to commit 31383c6865a5 "mm, hugetlbfs: introduce
>> ->split() to vm_operations_struct" it would be messy to teach
>> vma_mmu_pagesize() about device-dax page mapping sizes in the same
>> (hstate) way that hugetlbfs communicates this attribute.  Instead, these
>> patches introduce a new ->pagesize() vm operation.
>> 
>> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
>> Cc: Paul Mackerras <paulus@samba.org>
>> Cc: Michael Ellerman <mpe@ellerman.id.au>
>> Reported-by: Jane Chu <jane.chu@oracle.com>
>> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
>
> My build battery choked on the following
> In file included from drivers/infiniband/core/umem_odp.c:41:0:
> ./include/linux/hugetlb.h: In function 'vma_kernel_pagesize':
> ./include/linux/hugetlb.h:262:32: error: dereferencing pointer to incomplete type
>   if (vma->vm_ops && vma->vm_ops->pagesize)
>                                 ^
> ./include/linux/hugetlb.h:263:21: error: dereferencing pointer to incomplete type
>    return vma->vm_ops->pagesize(vma);
>
> I thought that adding #include <linux/mm.h> into linux/hugetlb.h would
> be sufficient but then it failed for powerpc defconfig which overrides
> vma_kernel_pagesize
> In file included from ./include/linux/hugetlb.h:452:0,
>                  from arch/powerpc/mm/hugetlbpage.c:14:
> ./arch/powerpc/include/asm/hugetlb.h:131:26: error: redefinition of 'vma_mmu_pagesize'
>  #define vma_mmu_pagesize vma_mmu_pagesize
>                           ^
> arch/powerpc/mm/hugetlbpage.c:563:15: note: in expansion of macro 'vma_mmu_pagesize'
>  unsigned long vma_mmu_pagesize(struct vm_area_struct *vma)
>                ^
> In file included from arch/powerpc/mm/hugetlbpage.c:14:0:
> ./include/linux/hugetlb.h:275:29: note: previous definition of 'vma_mmu_pagesize' was here
>  static inline unsigned long vma_mmu_pagesize(struct vm_area_struct *vma)
>
> So it looks this needs something more laborous.

This builds for me.

cheers


diff --git a/arch/powerpc/include/asm/hugetlb.h b/arch/powerpc/include/asm/hugetlb.h
index 14c9d44f355b..3cc6ca1bdaf2 100644
--- a/arch/powerpc/include/asm/hugetlb.h
+++ b/arch/powerpc/include/asm/hugetlb.h
@@ -123,6 +123,7 @@ void hugetlb_free_pgd_range(struct mmu_gather *tlb, unsigned long addr,
  * to override the version in mm/hugetlb.c
  */
 #define vma_mmu_pagesize vma_mmu_pagesize
+unsigned long vma_mmu_pagesize(struct vm_area_struct *vma);
 
 /*
  * If the arch doesn't supply something else, assume that hugepage
diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c
index a9b9083c5e49..c6a2e577e842 100644
--- a/arch/powerpc/mm/hugetlbpage.c
+++ b/arch/powerpc/mm/hugetlbpage.c
@@ -568,10 +568,7 @@ unsigned long vma_mmu_pagesize(struct vm_area_struct *vma)
 	if (!radix_enabled())
 		return 1UL << mmu_psize_to_shift(psize);
 #endif
-	if (!is_vm_hugetlb_page(vma))
-		return PAGE_SIZE;
-
-	return huge_page_size(hstate_vma(vma));
+	return vma_kernel_pagesize(vma);
 }
 
 static inline bool is_power_of_4(unsigned long x)
diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
index 6e3696c7b35a..fe7b74325856 100644
--- a/include/linux/hugetlb.h
+++ b/include/linux/hugetlb.h
@@ -394,10 +394,6 @@ static inline unsigned long huge_page_size(struct hstate *h)
 	return (unsigned long)PAGE_SIZE << h->order;
 }
 
-extern unsigned long vma_kernel_pagesize(struct vm_area_struct *vma);
-
-extern unsigned long vma_mmu_pagesize(struct vm_area_struct *vma);
-
 static inline unsigned long huge_page_mask(struct hstate *h)
 {
 	return h->mask;
@@ -430,6 +426,30 @@ static inline unsigned int blocks_per_huge_page(struct hstate *h)
 
 #include <asm/hugetlb.h>
 
+/*
+ * Return the size of the pages allocated when backing a VMA. In the majority
+ * cases this will be same size as used by the page table entries.
+ */
+static inline unsigned long vma_kernel_pagesize(struct vm_area_struct *vma)
+{
+	if (vma->vm_ops && vma->vm_ops->pagesize)
+		return vma->vm_ops->pagesize(vma);
+	return PAGE_SIZE;
+}
+
+/*
+ * Return the page size being used by the MMU to back a VMA. In the majority
+ * of cases, the page size used by the kernel matches the MMU size. On
+ * architectures where it differs, an architecture-specific version of this
+ * function is required.
+ */
+#ifndef vma_mmu_pagesize
+static inline unsigned long vma_mmu_pagesize(struct vm_area_struct *vma)
+{
+	return vma_kernel_pagesize(vma);
+}
+#endif
+
 #ifndef arch_make_huge_pte
 static inline pte_t arch_make_huge_pte(pte_t entry, struct vm_area_struct *vma,
 				       struct page *page, int writable)
@@ -533,8 +553,6 @@ struct hstate {};
 #define page_hstate(page) NULL
 #define huge_page_size(h) PAGE_SIZE
 #define huge_page_mask(h) PAGE_MASK
-#define vma_kernel_pagesize(v) PAGE_SIZE
-#define vma_mmu_pagesize(v) PAGE_SIZE
 #define huge_page_order(h) 0
 #define huge_page_shift(h) PAGE_SHIFT
 static inline bool hstate_is_gigantic(struct hstate *h)
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 7661156552d3..1933499f896d 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -383,6 +383,7 @@ struct vm_operations_struct {
 	int (*huge_fault)(struct vm_fault *vmf, enum page_entry_size pe_size);
 	void (*map_pages)(struct vm_fault *vmf,
 			pgoff_t start_pgoff, pgoff_t end_pgoff);
+	unsigned long (*pagesize)(struct vm_area_struct * area);
 
 	/* notification that a previously read-only page is about to become
 	 * writable, if an error is returned it will cause a SIGBUS */
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index 4137fb67cd79..7c1c45bb3d08 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -629,36 +629,6 @@ pgoff_t linear_hugepage_index(struct vm_area_struct *vma,
 }
 EXPORT_SYMBOL_GPL(linear_hugepage_index);
 
-/*
- * Return the size of the pages allocated when backing a VMA. In the majority
- * cases this will be same size as used by the page table entries.
- */
-unsigned long vma_kernel_pagesize(struct vm_area_struct *vma)
-{
-	struct hstate *hstate;
-
-	if (!is_vm_hugetlb_page(vma))
-		return PAGE_SIZE;
-
-	hstate = hstate_vma(vma);
-
-	return 1UL << huge_page_shift(hstate);
-}
-EXPORT_SYMBOL_GPL(vma_kernel_pagesize);
-
-/*
- * Return the page size being used by the MMU to back a VMA. In the majority
- * of cases, the page size used by the kernel matches the MMU size. On
- * architectures where it differs, an architecture-specific version of this
- * function is required.
- */
-#ifndef vma_mmu_pagesize
-unsigned long vma_mmu_pagesize(struct vm_area_struct *vma)
-{
-	return vma_kernel_pagesize(vma);
-}
-#endif
-
 /*
  * Flags for MAP_PRIVATE reservations.  These are stored in the bottom
  * bits of the reservation map pointer, which are always clear due to
@@ -3142,6 +3112,13 @@ static int hugetlb_vm_op_split(struct vm_area_struct *vma, unsigned long addr)
 	return 0;
 }
 
+static unsigned long hugetlb_vm_op_pagesize(struct vm_area_struct *vma)
+{
+	struct hstate *hstate = hstate_vma(vma);
+
+	return 1UL << huge_page_shift(hstate);
+}
+
 /*
  * We cannot handle pagefaults against hugetlb pages at all.  They cause
  * handle_mm_fault() to try to instantiate regular-sized pages in the
@@ -3159,6 +3136,7 @@ const struct vm_operations_struct hugetlb_vm_ops = {
 	.open = hugetlb_vm_op_open,
 	.close = hugetlb_vm_op_close,
 	.split = hugetlb_vm_op_split,
+	.pagesize = hugetlb_vm_op_pagesize,
 };
 
 static pte_t make_huge_pte(struct vm_area_struct *vma, struct page *page,

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

  reply	other threads:[~2017-12-13 13:02 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-12-08  3:30 [PATCH 0/2] mm, smaps: MMUPageSize for device-dax Dan Williams
2017-12-08  3:30 ` Dan Williams
2017-12-08  3:30 ` [PATCH 1/2] mm, hugetlbfs: introduce ->pagesize() to vm_operations_struct Dan Williams
2017-12-08  3:30   ` Dan Williams
2017-12-10 11:37   ` Michal Hocko
2017-12-10 11:37     ` Michal Hocko
2017-12-13 13:07     ` Michael Ellerman [this message]
2017-12-13 13:07       ` Michael Ellerman
2017-12-08  3:31 ` [PATCH 2/2] device-dax: implement ->pagesize() for smaps to report MMUPageSize Dan Williams
2017-12-08  3:31   ` Dan Williams

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87o9n2aia2.fsf@concordia.ellerman.id.au \
    --to=mpe@ellerman.id.au \
    --cc=akpm@linux-foundation.org \
    --cc=benh@kernel.crashing.org \
    --cc=dan.j.williams@intel.com \
    --cc=jane.chu@oracle.com \
    --cc=linux-mm@kvack.org \
    --cc=linux-nvdimm@lists.01.org \
    --cc=mhocko@kernel.org \
    --cc=paulus@samba.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.