diff mbox series

[v17,01/23] mm: Add generic p?d_leaf() macros

Message ID 20191218162402.45610-2-steven.price@arm.com (mailing list archive)
State New, archived
Headers show
Series Generic page walk and ptdump | expand

Commit Message

Steven Price Dec. 18, 2019, 4:23 p.m. UTC
Exposing the pud/pgd levels of the page tables to walk_page_range() means
we may come across the exotic large mappings that come with large areas
of contiguous memory (such as the kernel's linear map).

For architectures that don't provide all p?d_leaf() macros, provide
generic do nothing default that are suitable where there cannot be leaf
pages at that level. Futher patches will add implementations for
individual architectures.

The name p?d_leaf() is chosen to minimize the confusion with existing
uses of "large" pages and "huge" pages which do not necessary mean that
the entry is a leaf (for example it may be a set of contiguous entries
that only take 1 TLB slot). For the purpose of walking the page tables
we don't need to know how it will be represented in the TLB, but we do
need to know for sure if it is a leaf of the tree.

Signed-off-by: Steven Price <steven.price@arm.com>
Acked-by: Mark Rutland <mark.rutland@arm.com>
---
 include/asm-generic/pgtable.h | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

Comments

Michael Ellerman Dec. 19, 2019, 11:43 a.m. UTC | #1
Steven Price <steven.price@arm.com> writes:
> Exposing the pud/pgd levels of the page tables to walk_page_range() means
> we may come across the exotic large mappings that come with large areas
> of contiguous memory (such as the kernel's linear map).
>
> For architectures that don't provide all p?d_leaf() macros, provide
> generic do nothing default that are suitable where there cannot be leaf
> pages at that level. Futher patches will add implementations for
> individual architectures.
>
> The name p?d_leaf() is chosen to minimize the confusion with existing
> uses of "large" pages and "huge" pages which do not necessary mean that
> the entry is a leaf (for example it may be a set of contiguous entries
> that only take 1 TLB slot). For the purpose of walking the page tables
> we don't need to know how it will be represented in the TLB, but we do
> need to know for sure if it is a leaf of the tree.
>
> Signed-off-by: Steven Price <steven.price@arm.com>
> Acked-by: Mark Rutland <mark.rutland@arm.com>
> ---
>  include/asm-generic/pgtable.h | 20 ++++++++++++++++++++
>  1 file changed, 20 insertions(+)
>
> diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h
> index 798ea36a0549..e2e2bef07dd2 100644
> --- a/include/asm-generic/pgtable.h
> +++ b/include/asm-generic/pgtable.h
> @@ -1238,4 +1238,24 @@ static inline bool arch_has_pfn_modify_check(void)
>  #define mm_pmd_folded(mm)	__is_defined(__PAGETABLE_PMD_FOLDED)
>  #endif
>  
> +/*
> + * p?d_leaf() - true if this entry is a final mapping to a physical address.
> + * This differs from p?d_huge() by the fact that they are always available (if
> + * the architecture supports large pages at the appropriate level) even
> + * if CONFIG_HUGETLB_PAGE is not defined.
> + * Only meaningful when called on a valid entry.
> + */
> +#ifndef pgd_leaf
> +#define pgd_leaf(x)	0
> +#endif
> +#ifndef p4d_leaf
> +#define p4d_leaf(x)	0
> +#endif
> +#ifndef pud_leaf
> +#define pud_leaf(x)	0
> +#endif
> +#ifndef pmd_leaf
> +#define pmd_leaf(x)	0
> +#endif

Any reason you made these #defines rather than static inlines?

cheers
Steven Price Dec. 20, 2019, 11:48 a.m. UTC | #2
On 19/12/2019 11:43, Michael Ellerman wrote:
> Steven Price <steven.price@arm.com> writes:
>> Exposing the pud/pgd levels of the page tables to walk_page_range() means
>> we may come across the exotic large mappings that come with large areas
>> of contiguous memory (such as the kernel's linear map).
>>
>> For architectures that don't provide all p?d_leaf() macros, provide
>> generic do nothing default that are suitable where there cannot be leaf
>> pages at that level. Futher patches will add implementations for
>> individual architectures.
>>
>> The name p?d_leaf() is chosen to minimize the confusion with existing
>> uses of "large" pages and "huge" pages which do not necessary mean that
>> the entry is a leaf (for example it may be a set of contiguous entries
>> that only take 1 TLB slot). For the purpose of walking the page tables
>> we don't need to know how it will be represented in the TLB, but we do
>> need to know for sure if it is a leaf of the tree.
>>
>> Signed-off-by: Steven Price <steven.price@arm.com>
>> Acked-by: Mark Rutland <mark.rutland@arm.com>
>> ---
>>  include/asm-generic/pgtable.h | 20 ++++++++++++++++++++
>>  1 file changed, 20 insertions(+)
>>
>> diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h
>> index 798ea36a0549..e2e2bef07dd2 100644
>> --- a/include/asm-generic/pgtable.h
>> +++ b/include/asm-generic/pgtable.h
>> @@ -1238,4 +1238,24 @@ static inline bool arch_has_pfn_modify_check(void)
>>  #define mm_pmd_folded(mm)	__is_defined(__PAGETABLE_PMD_FOLDED)
>>  #endif
>>  
>> +/*
>> + * p?d_leaf() - true if this entry is a final mapping to a physical address.
>> + * This differs from p?d_huge() by the fact that they are always available (if
>> + * the architecture supports large pages at the appropriate level) even
>> + * if CONFIG_HUGETLB_PAGE is not defined.
>> + * Only meaningful when called on a valid entry.
>> + */
>> +#ifndef pgd_leaf
>> +#define pgd_leaf(x)	0
>> +#endif
>> +#ifndef p4d_leaf
>> +#define p4d_leaf(x)	0
>> +#endif
>> +#ifndef pud_leaf
>> +#define pud_leaf(x)	0
>> +#endif
>> +#ifndef pmd_leaf
>> +#define pmd_leaf(x)	0
>> +#endif
> 
> Any reason you made these #defines rather than static inlines?

No strong reason - but these have to be #defines in the arch overrides
so the #ifndef works, so I was being consistent here. I guess a static
inline might avoid warnings although I haven't seen any.

Steve
Michael Ellerman Dec. 21, 2019, 10:35 a.m. UTC | #3
Steven Price <steven.price@arm.com> writes:
> On 19/12/2019 11:43, Michael Ellerman wrote:
>> Steven Price <steven.price@arm.com> writes:
>>> Exposing the pud/pgd levels of the page tables to walk_page_range() means
>>> we may come across the exotic large mappings that come with large areas
>>> of contiguous memory (such as the kernel's linear map).
>>>
>>> For architectures that don't provide all p?d_leaf() macros, provide
>>> generic do nothing default that are suitable where there cannot be leaf
>>> pages at that level. Futher patches will add implementations for
>>> individual architectures.
>>>
>>> The name p?d_leaf() is chosen to minimize the confusion with existing
>>> uses of "large" pages and "huge" pages which do not necessary mean that
>>> the entry is a leaf (for example it may be a set of contiguous entries
>>> that only take 1 TLB slot). For the purpose of walking the page tables
>>> we don't need to know how it will be represented in the TLB, but we do
>>> need to know for sure if it is a leaf of the tree.
>>>
>>> Signed-off-by: Steven Price <steven.price@arm.com>
>>> Acked-by: Mark Rutland <mark.rutland@arm.com>
>>> ---
>>>  include/asm-generic/pgtable.h | 20 ++++++++++++++++++++
>>>  1 file changed, 20 insertions(+)
>>>
>>> diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h
>>> index 798ea36a0549..e2e2bef07dd2 100644
>>> --- a/include/asm-generic/pgtable.h
>>> +++ b/include/asm-generic/pgtable.h
>>> @@ -1238,4 +1238,24 @@ static inline bool arch_has_pfn_modify_check(void)
>>>  #define mm_pmd_folded(mm)	__is_defined(__PAGETABLE_PMD_FOLDED)
>>>  #endif
>>>  
>>> +/*
>>> + * p?d_leaf() - true if this entry is a final mapping to a physical address.
>>> + * This differs from p?d_huge() by the fact that they are always available (if
>>> + * the architecture supports large pages at the appropriate level) even
>>> + * if CONFIG_HUGETLB_PAGE is not defined.
>>> + * Only meaningful when called on a valid entry.
>>> + */
>>> +#ifndef pgd_leaf
>>> +#define pgd_leaf(x)	0
>>> +#endif
>>> +#ifndef p4d_leaf
>>> +#define p4d_leaf(x)	0
>>> +#endif
>>> +#ifndef pud_leaf
>>> +#define pud_leaf(x)	0
>>> +#endif
>>> +#ifndef pmd_leaf
>>> +#define pmd_leaf(x)	0
>>> +#endif
>> 
>> Any reason you made these #defines rather than static inlines?
>
> No strong reason - but these have to be #defines in the arch overrides
> so the #ifndef works, so I was being consistent here.

We handle that usually just with eg:

static inline bool pgd_leaf(pgd_t pgd)
{
	...
}
#define pgd_leaf pgd_leaf

> I guess a static inline might avoid warnings although I haven't seen
> any.

If anything I'd expect it to cause warnings, for example if someone is
doing pgd_leaf(pmd), but that would be good to catch.

cheers
diff mbox series

Patch

diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h
index 798ea36a0549..e2e2bef07dd2 100644
--- a/include/asm-generic/pgtable.h
+++ b/include/asm-generic/pgtable.h
@@ -1238,4 +1238,24 @@  static inline bool arch_has_pfn_modify_check(void)
 #define mm_pmd_folded(mm)	__is_defined(__PAGETABLE_PMD_FOLDED)
 #endif
 
+/*
+ * p?d_leaf() - true if this entry is a final mapping to a physical address.
+ * This differs from p?d_huge() by the fact that they are always available (if
+ * the architecture supports large pages at the appropriate level) even
+ * if CONFIG_HUGETLB_PAGE is not defined.
+ * Only meaningful when called on a valid entry.
+ */
+#ifndef pgd_leaf
+#define pgd_leaf(x)	0
+#endif
+#ifndef p4d_leaf
+#define p4d_leaf(x)	0
+#endif
+#ifndef pud_leaf
+#define pud_leaf(x)	0
+#endif
+#ifndef pmd_leaf
+#define pmd_leaf(x)	0
+#endif
+
 #endif /* _ASM_GENERIC_PGTABLE_H */