2014-12-11 13:20:34

by Kirill A. Shutemov

[permalink] [raw]
Subject: [PATCH] mm: add fields for compound destructor and order into struct page

Currently, we use lru.next/lru.prev plus cast to access or set
destructor and order of compound page.

Let's replace it with explicit fields in struct page.

Signed-off-by: Kirill A. Shutemov <[email protected]>
---
include/linux/mm.h | 9 ++++-----
include/linux/mm_types.h | 8 ++++++++
2 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/include/linux/mm.h b/include/linux/mm.h
index 5bfd9b9756fa..a8de6fe11d0a 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -525,29 +525,28 @@ int split_free_page(struct page *page);
* prototype for that function and accessor functions.
* These are _only_ valid on the head of a PG_compound page.
*/
-typedef void compound_page_dtor(struct page *);

static inline void set_compound_page_dtor(struct page *page,
compound_page_dtor *dtor)
{
- page[1].lru.next = (void *)dtor;
+ page[1].compound_dtor = dtor;
}

static inline compound_page_dtor *get_compound_page_dtor(struct page *page)
{
- return (compound_page_dtor *)page[1].lru.next;
+ return page[1].compound_dtor;
}

static inline int compound_order(struct page *page)
{
if (!PageHead(page))
return 0;
- return (unsigned long)page[1].lru.prev;
+ return page[1].compound_order;
}

static inline void set_compound_order(struct page *page, unsigned long order)
{
- page[1].lru.prev = (void *)order;
+ page[1].compound_order = order;
}

#ifdef CONFIG_MMU
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index 03945eef1350..cbc71f32a53c 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -28,6 +28,8 @@ struct mem_cgroup;
IS_ENABLED(CONFIG_ARCH_ENABLE_SPLIT_PMD_PTLOCK))
#define ALLOC_SPLIT_PTLOCKS (SPINLOCK_SIZE > BITS_PER_LONG/8)

+typedef void compound_page_dtor(struct page *);
+
/*
* Each physical page in the system has a struct page associated with
* it to keep track of whatever it is we are using the page for at the
@@ -131,6 +133,12 @@ struct page {
struct rcu_head rcu_head; /* Used by SLAB
* when destroying via RCU
*/
+ /* First tail page of compound page */
+ struct {
+ compound_page_dtor *compound_dtor;
+ unsigned long compound_order;
+ };
+
#if defined(CONFIG_TRANSPARENT_HUGEPAGE) && USE_SPLIT_PMD_PTLOCKS
pgtable_t pmd_huge_pte; /* protected by page->ptl */
#endif
--
2.1.3


2014-12-11 13:56:44

by Jerome Marchand

[permalink] [raw]
Subject: Re: [PATCH] mm: add fields for compound destructor and order into struct page

On 12/11/2014 02:20 PM, Kirill A. Shutemov wrote:
> Currently, we use lru.next/lru.prev plus cast to access or set
> destructor and order of compound page.
>
> Let's replace it with explicit fields in struct page.

Thanks! That made everything much clearer: the complexity of page struct
should not be swept under the carpet.

>
> Signed-off-by: Kirill A. Shutemov <[email protected]>

Acked-by: Jerome Marchand <[email protected]>

> ---
> include/linux/mm.h | 9 ++++-----
> include/linux/mm_types.h | 8 ++++++++
> 2 files changed, 12 insertions(+), 5 deletions(-)
>
> diff --git a/include/linux/mm.h b/include/linux/mm.h
> index 5bfd9b9756fa..a8de6fe11d0a 100644
> --- a/include/linux/mm.h
> +++ b/include/linux/mm.h
> @@ -525,29 +525,28 @@ int split_free_page(struct page *page);
> * prototype for that function and accessor functions.
> * These are _only_ valid on the head of a PG_compound page.
> */
> -typedef void compound_page_dtor(struct page *);
>
> static inline void set_compound_page_dtor(struct page *page,
> compound_page_dtor *dtor)
> {
> - page[1].lru.next = (void *)dtor;
> + page[1].compound_dtor = dtor;
> }
>
> static inline compound_page_dtor *get_compound_page_dtor(struct page *page)
> {
> - return (compound_page_dtor *)page[1].lru.next;
> + return page[1].compound_dtor;
> }
>
> static inline int compound_order(struct page *page)
> {
> if (!PageHead(page))
> return 0;
> - return (unsigned long)page[1].lru.prev;
> + return page[1].compound_order;
> }
>
> static inline void set_compound_order(struct page *page, unsigned long order)
> {
> - page[1].lru.prev = (void *)order;
> + page[1].compound_order = order;
> }
>
> #ifdef CONFIG_MMU
> diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
> index 03945eef1350..cbc71f32a53c 100644
> --- a/include/linux/mm_types.h
> +++ b/include/linux/mm_types.h
> @@ -28,6 +28,8 @@ struct mem_cgroup;
> IS_ENABLED(CONFIG_ARCH_ENABLE_SPLIT_PMD_PTLOCK))
> #define ALLOC_SPLIT_PTLOCKS (SPINLOCK_SIZE > BITS_PER_LONG/8)
>
> +typedef void compound_page_dtor(struct page *);
> +
> /*
> * Each physical page in the system has a struct page associated with
> * it to keep track of whatever it is we are using the page for at the
> @@ -131,6 +133,12 @@ struct page {
> struct rcu_head rcu_head; /* Used by SLAB
> * when destroying via RCU
> */
> + /* First tail page of compound page */
> + struct {
> + compound_page_dtor *compound_dtor;
> + unsigned long compound_order;
> + };
> +
> #if defined(CONFIG_TRANSPARENT_HUGEPAGE) && USE_SPLIT_PMD_PTLOCKS
> pgtable_t pmd_huge_pte; /* protected by page->ptl */
> #endif
>



Attachments:
signature.asc (473.00 B)
OpenPGP digital signature
Subject: Re: [PATCH] mm: add fields for compound destructor and order into struct page

On Thu, 11 Dec 2014, Kirill A. Shutemov wrote:

> Currently, we use lru.next/lru.prev plus cast to access or set
> destructor and order of compound page.

Acked-by: Christoph Lameter <[email protected]>

2014-12-11 15:24:45

by Johannes Weiner

[permalink] [raw]
Subject: Re: [PATCH] mm: add fields for compound destructor and order into struct page

On Thu, Dec 11, 2014 at 03:20:27PM +0200, Kirill A. Shutemov wrote:
> Currently, we use lru.next/lru.prev plus cast to access or set
> destructor and order of compound page.
>
> Let's replace it with explicit fields in struct page.
>
> Signed-off-by: Kirill A. Shutemov <[email protected]>

Acked-by: Johannes Weiner <[email protected]>