diff mbox series

[RFC,3/6] mm, pgtable: Add ownership for the PTE table

Message ID 20220519183127.3909598-4-shiyn.lin@gmail.com (mailing list archive)
State New
Headers show
Series Introduce Copy-On-Write to Page Table | expand

Commit Message

Chih-En Lin May 19, 2022, 6:31 p.m. UTC
Introduce the ownership for the PTE table to prepare the following patch
of the Copy-On-Write (COW) page table. It uses the address of PMD index
to become the owner to identify which process can update its page table
state from the COW page table.

Signed-off-by: Chih-En Lin <shiyn.lin@gmail.com>
---
 include/linux/mm.h       |  1 +
 include/linux/mm_types.h |  1 +
 include/linux/pgtable.h  | 14 ++++++++++++++
 3 files changed, 16 insertions(+)

Comments

Christophe Leroy May 20, 2022, 2:15 p.m. UTC | #1
Le 19/05/2022 à 20:31, Chih-En Lin a écrit :
> Introduce the ownership for the PTE table to prepare the following patch
> of the Copy-On-Write (COW) page table. It uses the address of PMD index
> to become the owner to identify which process can update its page table
> state from the COW page table.
> 
> Signed-off-by: Chih-En Lin <shiyn.lin@gmail.com>
> ---
>   include/linux/mm.h       |  1 +
>   include/linux/mm_types.h |  1 +
>   include/linux/pgtable.h  | 14 ++++++++++++++
>   3 files changed, 16 insertions(+)
> 
> diff --git a/include/linux/mm.h b/include/linux/mm.h
> index 9f44254af8ce..221926a3d818 100644
> --- a/include/linux/mm.h
> +++ b/include/linux/mm.h
> @@ -2328,6 +2328,7 @@ static inline bool pgtable_pte_page_ctor(struct page *page)
>                  return false;
>          __SetPageTable(page);
>          inc_lruvec_page_state(page, NR_PAGETABLE);
> +       page->cow_pte_owner = NULL;
>          return true;
>   }
> 
> diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
> index 8834e38c06a4..5dcbd7f6c361 100644
> --- a/include/linux/mm_types.h
> +++ b/include/linux/mm_types.h
> @@ -221,6 +221,7 @@ struct page {
>   #ifdef LAST_CPUPID_NOT_IN_PAGE_FLAGS
>          int _last_cpupid;
>   #endif
> +       pmd_t *cow_pte_owner; /* cow pte: pmd */
>   } _struct_page_alignment;
> 
>   /**
> diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
> index f4f4077b97aa..faca57af332e 100644
> --- a/include/linux/pgtable.h
> +++ b/include/linux/pgtable.h
> @@ -590,6 +590,20 @@ static inline int pte_unused(pte_t pte)
>   }
>   #endif
> 
> +static inline bool set_cow_pte_owner(pmd_t *pmd, pmd_t *owner)
> +{
> +       struct page *page = pmd_page(*pmd);
> +
> +       smp_store_release(&page->cow_pte_owner, owner);
> +       return true;
> +}
> +
> +static inline bool cow_pte_owner_is_same(pmd_t *pmd, pmd_t *owner)
> +{
> +       return (smp_load_acquire(&pmd_page(*pmd)->cow_pte_owner) == owner) ?
> +               true : false;

The above seems uggly, the following should be equivalent :

	return smp_load_acquire(&pmd_page(*pmd)->cow_pte_owner) == owner;

> +}
> +
>   #ifndef pte_access_permitted
>   #define pte_access_permitted(pte, write) \
>          (pte_present(pte) && (!(write) || pte_write(pte)))
> --
> 2.36.1
>
Matthew Wilcox May 21, 2022, 4:02 a.m. UTC | #2
On Fri, May 20, 2022 at 02:31:24AM +0800, Chih-En Lin wrote:
> diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
> index 8834e38c06a4..5dcbd7f6c361 100644
> --- a/include/linux/mm_types.h
> +++ b/include/linux/mm_types.h
> @@ -221,6 +221,7 @@ struct page {
>  #ifdef LAST_CPUPID_NOT_IN_PAGE_FLAGS
>  	int _last_cpupid;
>  #endif
> +	pmd_t *cow_pte_owner; /* cow pte: pmd */

This is definitely the wrong place.  I think it could replace _pt_pad_1,
since it's a pointer to a PMD and so the bottom bit will definitely
be clear.
Chih-En Lin May 21, 2022, 4:03 a.m. UTC | #3
On Fri, May 20, 2022 at 02:15:12PM +0000, Christophe Leroy wrote:
> > +static inline bool cow_pte_owner_is_same(pmd_t *pmd, pmd_t *owner)
> > +{
> > +       return (smp_load_acquire(&pmd_page(*pmd)->cow_pte_owner) == owner) ?
> > +               true : false;

Why I wrote like this. ;-)

> 
> The above seems uggly, the following should be equivalent :
> 
> 	return smp_load_acquire(&pmd_page(*pmd)->cow_pte_owner) == owner;
> 

Thanks.
Chih-En Lin May 21, 2022, 5:01 a.m. UTC | #4
On Sat, May 21, 2022 at 05:02:43AM +0100, Matthew Wilcox wrote:
> On Fri, May 20, 2022 at 02:31:24AM +0800, Chih-En Lin wrote:
> > diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
> > index 8834e38c06a4..5dcbd7f6c361 100644
> > --- a/include/linux/mm_types.h
> > +++ b/include/linux/mm_types.h
> > @@ -221,6 +221,7 @@ struct page {
> >  #ifdef LAST_CPUPID_NOT_IN_PAGE_FLAGS
> >  	int _last_cpupid;
> >  #endif
> > +	pmd_t *cow_pte_owner; /* cow pte: pmd */
> 
> This is definitely the wrong place.  I think it could replace _pt_pad_1,
> since it's a pointer to a PMD and so the bottom bit will definitely
> be clear.
>

I will figure out how to use _pt_pad_1.
It seems relative to the compound page (or folio?).

Thanks.
diff mbox series

Patch

diff --git a/include/linux/mm.h b/include/linux/mm.h
index 9f44254af8ce..221926a3d818 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -2328,6 +2328,7 @@  static inline bool pgtable_pte_page_ctor(struct page *page)
 		return false;
 	__SetPageTable(page);
 	inc_lruvec_page_state(page, NR_PAGETABLE);
+	page->cow_pte_owner = NULL;
 	return true;
 }
 
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index 8834e38c06a4..5dcbd7f6c361 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -221,6 +221,7 @@  struct page {
 #ifdef LAST_CPUPID_NOT_IN_PAGE_FLAGS
 	int _last_cpupid;
 #endif
+	pmd_t *cow_pte_owner; /* cow pte: pmd */
 } _struct_page_alignment;
 
 /**
diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
index f4f4077b97aa..faca57af332e 100644
--- a/include/linux/pgtable.h
+++ b/include/linux/pgtable.h
@@ -590,6 +590,20 @@  static inline int pte_unused(pte_t pte)
 }
 #endif
 
+static inline bool set_cow_pte_owner(pmd_t *pmd, pmd_t *owner)
+{
+	struct page *page = pmd_page(*pmd);
+
+	smp_store_release(&page->cow_pte_owner, owner);
+	return true;
+}
+
+static inline bool cow_pte_owner_is_same(pmd_t *pmd, pmd_t *owner)
+{
+	return (smp_load_acquire(&pmd_page(*pmd)->cow_pte_owner) == owner) ?
+		true : false;
+}
+
 #ifndef pte_access_permitted
 #define pte_access_permitted(pte, write) \
 	(pte_present(pte) && (!(write) || pte_write(pte)))