Skip to content

Commit

Permalink
xtensa: remove vma linked list walks
Browse files Browse the repository at this point in the history
Use the VMA iterator instead.  Since VMA can no longer be NULL in the
loop, then deal with out-of-memory outside the loop.  This means a
slightly longer run time in the failure case (-ENOMEM) - it will run to
the end of the VMAs before erroring instead of in the middle of the loop.

Link: https://lkml.kernel.org/r/20220906194824.2110408-37-Liam.Howlett@oracle.com
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Signed-off-by: Liam R. Howlett <Liam.Howlett@Oracle.com>
Reviewed-by: Davidlohr Bueso <dave@stgolabs.net>
Tested-by: Yu Zhao <yuzhao@google.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: David Hildenbrand <david@redhat.com>
Cc: David Howells <dhowells@redhat.com>
Cc: SeongJae Park <sj@kernel.org>
Cc: Sven Schnelle <svens@linux.ibm.com>
Cc: Vlastimil Babka <vbabka@suse.cz>
Cc: Will Deacon <will@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
  • Loading branch information
Matthew Wilcox (Oracle) authored and Andrew Morton committed Sep 27, 2022
1 parent a388462 commit 49c40fb
Showing 1 changed file with 12 additions and 6 deletions.
18 changes: 12 additions & 6 deletions arch/xtensa/kernel/syscall.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
unsigned long len, unsigned long pgoff, unsigned long flags)
{
struct vm_area_struct *vmm;
struct vma_iterator vmi;

if (flags & MAP_FIXED) {
/* We do not accept a shared mapping if it would violate
Expand All @@ -79,15 +80,20 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
else
addr = PAGE_ALIGN(addr);

for (vmm = find_vma(current->mm, addr); ; vmm = vmm->vm_next) {
/* At this point: (!vmm || addr < vmm->vm_end). */
if (TASK_SIZE - len < addr)
return -ENOMEM;
if (!vmm || addr + len <= vm_start_gap(vmm))
return addr;
vma_iter_init(&vmi, current->mm, addr);
for_each_vma(vmi, vmm) {
/* At this point: (addr < vmm->vm_end). */
if (addr + len <= vm_start_gap(vmm))
break;

addr = vmm->vm_end;
if (flags & MAP_SHARED)
addr = COLOUR_ALIGN(addr, pgoff);
}

if (TASK_SIZE - len < addr)
return -ENOMEM;

return addr;
}
#endif

0 comments on commit 49c40fb

Please sign in to comment.