[1/3] mm: document zone device struct page reserved fields
diff mbox series

Message ID 20190717001446.12351-2-rcampbell@nvidia.com
State New
Headers show
Series
  • mm/hmm: fixes for device private page migration
Related show

Commit Message

Ralph Campbell July 17, 2019, 12:14 a.m. UTC
Struct page for ZONE_DEVICE private pages uses the reserved fields when
anonymous pages are migrated to device private memory. This is so
the page->mapping and page->index fields are preserved and the page can
be migrated back to system memory.
Document this in comments so it is more clear.

Signed-off-by: Ralph Campbell <rcampbell@nvidia.com>
Cc: Matthew Wilcox <mawilcox@microsoft.com>
Cc: Vlastimil Babka <vbabka@suse.cz>
Cc: Christoph Lameter <cl@linux.com>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Jérôme Glisse <jglisse@redhat.com>
Cc: "Kirill A . Shutemov" <kirill.shutemov@linux.intel.com>
Cc: Lai Jiangshan <jiangshanlai@gmail.com>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Pekka Enberg <penberg@kernel.org>
Cc: Randy Dunlap <rdunlap@infradead.org>
Cc: Andrey Ryabinin <aryabinin@virtuozzo.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Jason Gunthorpe <jgg@mellanox.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
---
 include/linux/mm_types.h | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

Comments

John Hubbard July 17, 2019, 1:20 a.m. UTC | #1
On 7/16/19 5:14 PM, Ralph Campbell wrote:
> Struct page for ZONE_DEVICE private pages uses the reserved fields when
> anonymous pages are migrated to device private memory. This is so
> the page->mapping and page->index fields are preserved and the page can
> be migrated back to system memory.
> Document this in comments so it is more clear.
> 
> Signed-off-by: Ralph Campbell <rcampbell@nvidia.com>
> Cc: Matthew Wilcox <mawilcox@microsoft.com>
> Cc: Vlastimil Babka <vbabka@suse.cz>
> Cc: Christoph Lameter <cl@linux.com>
> Cc: Dave Hansen <dave.hansen@linux.intel.com>
> Cc: Jérôme Glisse <jglisse@redhat.com>
> Cc: "Kirill A . Shutemov" <kirill.shutemov@linux.intel.com>
> Cc: Lai Jiangshan <jiangshanlai@gmail.com>
> Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
> Cc: Pekka Enberg <penberg@kernel.org>
> Cc: Randy Dunlap <rdunlap@infradead.org>
> Cc: Andrey Ryabinin <aryabinin@virtuozzo.com>
> Cc: Christoph Hellwig <hch@lst.de>
> Cc: Jason Gunthorpe <jgg@mellanox.com>
> Cc: Andrew Morton <akpm@linux-foundation.org>
> Cc: Linus Torvalds <torvalds@linux-foundation.org>
> ---
>  include/linux/mm_types.h | 9 ++++++++-
>  1 file changed, 8 insertions(+), 1 deletion(-)
> 
> diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
> index 3a37a89eb7a7..d6ea74e20306 100644
> --- a/include/linux/mm_types.h
> +++ b/include/linux/mm_types.h
> @@ -159,7 +159,14 @@ struct page {
>  			/** @pgmap: Points to the hosting device page map. */
>  			struct dev_pagemap *pgmap;
>  			void *zone_device_data;
> -			unsigned long _zd_pad_1;	/* uses mapping */
> +			/*
> +			 * The following fields are used to hold the source
> +			 * page anonymous mapping information while it is
> +			 * migrated to device memory. See migrate_page().
> +			 */
> +			unsigned long _zd_pad_1;	/* aliases mapping */
> +			unsigned long _zd_pad_2;	/* aliases index */
> +			unsigned long _zd_pad_3;	/* aliases private */

Actually, I do think this helps. It's hard to document these fields, and
the ZONE_DEVICE pages have a really complicated situation during migration
to a device. 

Additionally, I'm not sure, but should we go even further, and do this on the 
other side of the alias:

diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index d6ea74e20306..c5ce5989d8a8 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -83,7 +83,12 @@ struct page {
                         * by the page owner.
                         */
                        struct list_head lru;
-                       /* See page-flags.h for PAGE_MAPPING_FLAGS */
+                       /*
+                        * See page-flags.h for PAGE_MAPPING_FLAGS.
+                        *
+                        * Also: the next three fields (mapping, index and
+                        * private) are all used by ZONE_DEVICE pages.
+                        */
                        struct address_space *mapping;
                        pgoff_t index;          /* Our offset within mapping. */
                        /**

?

Either way, you can add:

    Reviewed-by: John Hubbard <jhubbard@nvidia.com>


thanks,
Christoph Hellwig July 17, 2019, 4:22 a.m. UTC | #2
On Tue, Jul 16, 2019 at 06:20:23PM -0700, John Hubbard wrote:
> > -			unsigned long _zd_pad_1;	/* uses mapping */
> > +			/*
> > +			 * The following fields are used to hold the source
> > +			 * page anonymous mapping information while it is
> > +			 * migrated to device memory. See migrate_page().
> > +			 */
> > +			unsigned long _zd_pad_1;	/* aliases mapping */
> > +			unsigned long _zd_pad_2;	/* aliases index */
> > +			unsigned long _zd_pad_3;	/* aliases private */
> 
> Actually, I do think this helps. It's hard to document these fields, and
> the ZONE_DEVICE pages have a really complicated situation during migration
> to a device. 
> 
> Additionally, I'm not sure, but should we go even further, and do this on the 
> other side of the alias:

The _zd_pad_* field obviously are NOT used anywhere in the source tree.
So these comments are very misleading.  If we still keep
using ->mapping, ->index and ->private we really should clean up the
definition of struct page to make that obvious instead of trying to
doctor around it using comments.
John Hubbard July 17, 2019, 4:31 a.m. UTC | #3
On 7/16/19 9:22 PM, Christoph Hellwig wrote:
> On Tue, Jul 16, 2019 at 06:20:23PM -0700, John Hubbard wrote:
>>> -			unsigned long _zd_pad_1;	/* uses mapping */
>>> +			/*
>>> +			 * The following fields are used to hold the source
>>> +			 * page anonymous mapping information while it is
>>> +			 * migrated to device memory. See migrate_page().
>>> +			 */
>>> +			unsigned long _zd_pad_1;	/* aliases mapping */
>>> +			unsigned long _zd_pad_2;	/* aliases index */
>>> +			unsigned long _zd_pad_3;	/* aliases private */
>>
>> Actually, I do think this helps. It's hard to document these fields, and
>> the ZONE_DEVICE pages have a really complicated situation during migration
>> to a device. 
>>
>> Additionally, I'm not sure, but should we go even further, and do this on the 
>> other side of the alias:
> 
> The _zd_pad_* field obviously are NOT used anywhere in the source tree.
> So these comments are very misleading.  If we still keep
> using ->mapping, ->index and ->private we really should clean up the
> definition of struct page to make that obvious instead of trying to
> doctor around it using comments.
> 

OK, so just delete all the _zd_pad_* fields? Works for me. It's misleading to
calling something padding, if it's actually unavailable because it's used
in the other union, so deleting would be even better than commenting.

In that case, it would still be nice to have this new snippet, right?:

diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index d6ea74e20306..c5ce5989d8a8 100644

--- a/include/linux/mm_types.h

+++ b/include/linux/mm_types.h

@@ -83,7 +83,12 @@

 struct page {

                         * by the page owner. 
                         */ 
                        struct list_head lru; 
-                       /* See page-flags.h for PAGE_MAPPING_FLAGS */ 
+                       /* 
+                        * See page-flags.h for PAGE_MAPPING_FLAGS. 
+                        * 
+                        * Also: the next three fields (mapping, index and 
+                        * private) are all used by ZONE_DEVICE pages. 
+                        */ 
                        struct address_space *mapping; 
                        pgoff_t index;          /* Our offset within mapping. */ 
                        /** 

thanks,
Christoph Hellwig July 17, 2019, 4:38 a.m. UTC | #4
On Tue, Jul 16, 2019 at 09:31:33PM -0700, John Hubbard wrote:
> OK, so just delete all the _zd_pad_* fields? Works for me. It's misleading to
> calling something padding, if it's actually unavailable because it's used
> in the other union, so deleting would be even better than commenting.
> 
> In that case, it would still be nice to have this new snippet, right?:

I hope willy can chime in a bit on his thoughts about how the union in
struct page should look like.  The padding at the end of the sub-structs
certainly looks pointless, and other places don't use it either.  But if
we are using the other fields it almost seems to me like we only want to
union the lru field in the first sub-struct instead of overlaying most
of it.
Ralph Campbell July 17, 2019, 5:50 p.m. UTC | #5
On 7/16/19 9:38 PM, Christoph Hellwig wrote:
> On Tue, Jul 16, 2019 at 09:31:33PM -0700, John Hubbard wrote:
>> OK, so just delete all the _zd_pad_* fields? Works for me. It's misleading to
>> calling something padding, if it's actually unavailable because it's used
>> in the other union, so deleting would be even better than commenting.
>>
>> In that case, it would still be nice to have this new snippet, right?:
> 
> I hope willy can chime in a bit on his thoughts about how the union in
> struct page should look like.  The padding at the end of the sub-structs
> certainly looks pointless, and other places don't use it either.  But if
> we are using the other fields it almost seems to me like we only want to
> union the lru field in the first sub-struct instead of overlaying most
> of it.
>

I like this approach.
I'll work on an updated patch that makes "struct list_head lru" part
of a union with the ZONE_DEVICE struct without the padding and update
the comments and change log.

I will also wait a day or two for others to add their comments.

Patch
diff mbox series

diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index 3a37a89eb7a7..d6ea74e20306 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -159,7 +159,14 @@  struct page {
 			/** @pgmap: Points to the hosting device page map. */
 			struct dev_pagemap *pgmap;
 			void *zone_device_data;
-			unsigned long _zd_pad_1;	/* uses mapping */
+			/*
+			 * The following fields are used to hold the source
+			 * page anonymous mapping information while it is
+			 * migrated to device memory. See migrate_page().
+			 */
+			unsigned long _zd_pad_1;	/* aliases mapping */
+			unsigned long _zd_pad_2;	/* aliases index */
+			unsigned long _zd_pad_3;	/* aliases private */
 		};
 
 		/** @rcu_head: You can use this to free a page by RCU. */