[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <07fea205-ffb2-dc32-a56d-1cce51d5f931@csgroup.eu>
Date: Sat, 18 Sep 2021 10:47:13 +0200
From: Christophe Leroy <christophe.leroy@...roup.eu>
To: David Laight <David.Laight@...LAB.COM>,
Benjamin Herrenschmidt <benh@...nel.crashing.org>,
Paul Mackerras <paulus@...ba.org>,
Michael Ellerman <mpe@...erman.id.au>
Cc: "linuxppc-dev@...ts.ozlabs.org" <linuxppc-dev@...ts.ozlabs.org>,
"linux-kernel@...r.kernel.org" <linux-kernel@...r.kernel.org>
Subject: Re: [PATCH v2] powerpc/32: Don't use a struct based type for pte_t
Le 17/09/2021 à 16:32, David Laight a écrit :
> From: Christophe Leroy
>> Sent: 17 September 2021 14:58
>>
>> Long time ago we had a config item called STRICT_MM_TYPECHECKS
>> to build the kernel with pte_t defined as a structure in order
>> to perform additional build checks or build it with pte_t
>> defined as a simple type in order to get simpler generated code.
>>
> ...
>> diff --git a/arch/powerpc/include/asm/pgtable-types.h b/arch/powerpc/include/asm/pgtable-types.h
>> index d11b4c61d686..c60199fc6fa6 100644
>> --- a/arch/powerpc/include/asm/pgtable-types.h
>> +++ b/arch/powerpc/include/asm/pgtable-types.h
>> @@ -5,14 +5,26 @@
>> /* PTE level */
>> #if defined(CONFIG_PPC_8xx) && defined(CONFIG_PPC_16K_PAGES)
>> typedef struct { pte_basic_t pte, pte1, pte2, pte3; } pte_t;
>> -#else
>> +#elif defined(__CHECKER__) || !defined(CONFIG_PPC32)
>> typedef struct { pte_basic_t pte; } pte_t;
>> +#else
>> +typedef pte_basic_t pte_t;
>> #endif
>> +
>> +#if defined(__CHECKER__) || !defined(CONFIG_PPC32) || \
>> + (defined(CONFIG_PPC_8xx) && defined(CONFIG_PPC_16K_PAGES))
>> #define __pte(x) ((pte_t) { (x) })
>> static inline pte_basic_t pte_val(pte_t x)
>> {
>> return x.pte;
>> }
>> +#else
>> +#define __pte(x) ((pte_t)(x))
>> +static inline pte_basic_t pte_val(pte_t x)
>> +{
>> + return x;
>> +}
>> +#endif
>
> Would it be better to define:
> static inline pte_basic_*pte_basic(pte_t *x)
> {
> #if xxx
> return x;
> #else
> return &x->pte;
> #endif
> }
>
> Then pte_val(x) is always *pt_basic(x)
> and the casts like:
>
>> - pte_basic_t *entry = &ptep->pte;
>> + pte_basic_t *entry = (pte_basic_t *)ptep;
>
> can go away.
>
I don't like that idea too much, because it means going through a
pointer of something which is not in memory at the begining. Doing that
forces GCC to put the pte_t object on stack. And that's exactly the
purpose of this patch: avoid having to go via memory. Allthough recent
versions of GCC optimise it away at the end, I don't like it in principle.
And the only two places (pte_update() and set_huge_pte_at() where this
cast is required are really two places very special which deal with real
page tables. So IMHO it makes sense to explicitely show that what we use
is the address of the entry in the page table.
Christophe
Powered by blists - more mailing lists