On 28.09.20 14:33, Richard Weinberger via Xenomai wrote: > It is not obvious why cobalt_machine.prefault is needed > and why only for ARM. > One would expect that mlockall() would do it too. > > Signed-off-by: Richard Weinberger <[email protected]> > --- > Note: I think we can make mach_arm_prefault() a no-op on arm64 > if cpu_has_hw_af() returns true. > But I need to test it first. B-) > --- > kernel/cobalt/arch/arm/machine.c | 5 +++++ > kernel/cobalt/arch/arm64/machine.c | 5 +++++ > kernel/cobalt/rtdm/drvlib.c | 13 +++++++++++++ > 3 files changed, 23 insertions(+) > > diff --git a/kernel/cobalt/arch/arm/machine.c > b/kernel/cobalt/arch/arm/machine.c > index 721567182f49..be56b2b84e2e 100644 > --- a/kernel/cobalt/arch/arm/machine.c > +++ b/kernel/cobalt/arch/arm/machine.c > @@ -35,6 +35,11 @@ static void mach_arm_prefault(struct vm_area_struct *vma) > flags = (vma->vm_flags & VM_MAYWRITE) ? FAULT_FLAG_WRITE : 0; > for (addr = vma->vm_start; > addr != vma->vm_end; addr += PAGE_SIZE) > + /* > + * Explicitly mark pages dirty such that future writes > + * won't trigger a page fault due to PTE dirty bit > + * emulation. > + */ > #if LINUX_VERSION_CODE < KERNEL_VERSION(4,8,0) > handle_mm_fault(vma->vm_mm, vma, addr, flags); > #else > diff --git a/kernel/cobalt/arch/arm64/machine.c > b/kernel/cobalt/arch/arm64/machine.c > index cb2867492360..f820e63624ec 100644 > --- a/kernel/cobalt/arch/arm64/machine.c > +++ b/kernel/cobalt/arch/arm64/machine.c > @@ -35,6 +35,11 @@ static void mach_arm_prefault(struct vm_area_struct *vma) > flags = (vma->vm_flags & VM_MAYWRITE) ? FAULT_FLAG_WRITE : 0; > for (addr = vma->vm_start; > addr != vma->vm_end; addr += PAGE_SIZE) > + /* > + * Explicitly mark pages dirty such that future writes > + * won't trigger a page fault due to PTE dirty bit > + * emulation. > + */ > #if LINUX_VERSION_CODE < KERNEL_VERSION(4,8,0) > handle_mm_fault(vma->vm_mm, vma, addr, flags); > #else > diff --git a/kernel/cobalt/rtdm/drvlib.c b/kernel/cobalt/rtdm/drvlib.c > index 5778ad559ced..674292d89b71 100644 > --- a/kernel/cobalt/rtdm/drvlib.c > +++ b/kernel/cobalt/rtdm/drvlib.c > @@ -1695,6 +1695,19 @@ static int mmap_kmem_helper(struct vm_area_struct > *vma, void *va) > } > } > > + /* > + * Extra prefaulting is needed for two reasons on ARMv8 (and older): > + * > + * 1. ARM does not have a dirty PTE flag in hardware, upon first write > + * a page fault exception happens and Linux marks the page as dirty. > + * On x86 this is not the case and therefore the prefault handler can > + * be NULL. > + * > + * 2. __mm_populate() (via mlock/all()) does not dirty MAP_SHARED > + * memory mappings, this would trigger a lot of IO due to write back. > + * As of today, __mm_populate() cannot distinguish between MAP_SHARED > + * with and without possible write back. > + */ > if (cobalt_machine.prefault) > cobalt_machine.prefault(vma); > #endif >
Sounds reasonable to me, but I'm not deep into that. Will merge unless someone in CC suggest something different. Thanks, Jan -- Siemens AG, Corporate Technology, CT RDA IOT SES-DE Corporate Competence Center Embedded Linux
