[PATCH 2/3] powerpc/64s/radix: ioremap use ioremap_page_range
Christophe Leroy
christophe.leroy at c-s.fr
Wed Jun 19 22:49:37 AEST 2019
Le 19/06/2019 à 05:59, Nicholas Piggin a écrit :
> Christophe Leroy's on June 11, 2019 4:46 pm:
>>
>>
>> Le 10/06/2019 à 05:08, Nicholas Piggin a écrit :
[snip]
>>> diff --git a/arch/powerpc/mm/book3s64/radix_pgtable.c b/arch/powerpc/mm/book3s64/radix_pgtable.c
>>> index c9bcf428dd2b..db993bc1aef3 100644
>>> --- a/arch/powerpc/mm/book3s64/radix_pgtable.c
>>> +++ b/arch/powerpc/mm/book3s64/radix_pgtable.c
>>> @@ -11,6 +11,7 @@
>>>
>>> #define pr_fmt(fmt) "radix-mmu: " fmt
>>>
>>> +#include <linux/io.h>
>>> #include <linux/kernel.h>
>>> #include <linux/sched/mm.h>
>>> #include <linux/memblock.h>
>>> @@ -1122,3 +1123,23 @@ void radix__ptep_modify_prot_commit(struct vm_area_struct *vma,
>>>
>>> set_pte_at(mm, addr, ptep, pte);
>>> }
>>> +
>>> +int radix__ioremap_range(unsigned long ea, phys_addr_t pa, unsigned long size,
>>> + pgprot_t prot, int nid)
>>> +{
>>> + if (likely(slab_is_available())) {
>>> + int err = ioremap_page_range(ea, ea + size, pa, prot);
>>> + if (err)
>>> + unmap_kernel_range(ea, size);
>>> + return err;
>>> + } else {
>>> + unsigned long i;
>>> +
>>> + for (i = 0; i < size; i += PAGE_SIZE) {
>>> + int err = map_kernel_page(ea + i, pa + i, prot);
>>> + if (WARN_ON_ONCE(err)) /* Should clean up */
>>> + return err;
>>> + }
>>
>> Same loop again.
>>
>> What about not doing a radix specific function and just putting
>> something like below in the core ioremap_range() function ?
>>
>> if (likely(slab_is_available()) && radix_enabled()) {
>> int err = ioremap_page_range(ea, ea + size, pa, prot);
>>
>> if (err)
>> unmap_kernel_range(ea, size);
>> return err;
>> }
>>
>> Because I'm pretty sure will more and more use ioremap_page_range().
>
> Well I agree the duplication is not so nice, but it's convenient
> to see what is going on for each MMU type.
>
> There is a significant amount of churn that needs to be done in
> this layer so I prefer to make it a bit simpler despite duplication.
>
> I would like to remove the early ioremap or make it into its own
> function. Re-implement map_kernel_page with ioremap_page_range,
> allow page tables that don't use slab to avoid the early check,
> unbolt the hptes mapped in early boot, etc.
>
> I just wanted to escape out the 64s and hash/radix implementations
> completely until that settles.
I can understand the benefit in some situations but here I just can't.
And code duplication should be avoided as much as possible as it makes
code maintenance more difficult.
Here you have:
+static int ioremap_range(unsigned long ea, phys_addr_t pa, unsigned
long size, pgprot_t prot, int nid)
+{
+ unsigned long i;
+
+ for (i = 0; i < size; i += PAGE_SIZE) {
+ int err = map_kernel_page(ea + i, pa + i, prot);
+ if (err) {
+ if (slab_is_available())
+ unmap_kernel_range(ea, size);
+ else
+ WARN_ON_ONCE(1); /* Should clean up */
+ return err;
+ }
+ }
+
+ return 0;
+}
You now create a new one in another file, that is almost identical:
+int ioremap_range(unsigned long ea, phys_addr_t pa, unsigned long size,
pgprot_t prot, int nid)
+{
+ unsigned long i;
+
+ if (radix_enabled())
+ return radix__ioremap_range(ea, pa, size, prot, nid);
+
+ for (i = 0; i < size; i += PAGE_SIZE) {
+ int err = map_kernel_page(ea + i, pa + i, prot);
+ if (err) {
+ if (slab_is_available())
+ unmap_kernel_range(ea, size);
+ else
+ WARN_ON_ONCE(1); /* Should clean up */
+ return err;
+ }
+ }
+
+ return 0;
+}
Then you have to make the original one __weak.
Sorry I'm still having difficulties understanding what the benefit is.
radix_enabled() is defined for every platforms so could just add the
following on top of the existing ioremap_range() and voila.
+ if (radix_enabled())
+ return radix__ioremap_range(ea, pa, size, prot, nid);
And with that you wouldn't have the __weak stuff to handle.
>
>>> -static int ioremap_range(unsigned long ea, phys_addr_t pa, unsigned long size, pgprot_t prot, int nid)
>>> +int __weak ioremap_range(unsigned long ea, phys_addr_t pa, unsigned long size, pgprot_t prot, int nid)
>>
>> Hum. Weak functions remain in unused in vmlinux unless
>> CONFIG_LD_DEAD_CODE_DATA_ELIMINATION is selected.
>>
>> Also, they are some how dangerous because people might change them
>> without seeing that it is overridden for some particular configuration.
>
> Well you shouldn't assume that when you see a weak function, but
> what's the preferred alternative? A config option?
Yes you are right, nobody should assume that, but ...
But I think if the fonctions were really different, the preferred
alternative would be to move the original function into a file dedicated
to nohash64.
Christophe
More information about the Linuxppc-dev
mailing list