From 0ca862d2bb89bcd6c64b7151a6860d85e4861464 Mon Sep 17 00:00:00 2001 From: Harshdeep Dhatt Date: Thu, 9 Jan 2020 09:00:10 -0800 Subject: [PATCH] msm: kgsl: Skip the intersecting vma If we intersect with an existing vma, we check against the same vma multiple times which causes huge latency during mmap. So check against an existing vma just once and move on. Change-Id: Ib7975493d137f29db7ce01fc1d0ac7d88b9405e2 Signed-off-by: Harshdeep Dhatt --- drivers/gpu/msm/kgsl.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c index 8a265cc019f1..26f50a79dc68 100644 --- a/drivers/gpu/msm/kgsl.c +++ b/drivers/gpu/msm/kgsl.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2008-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2008-2020, The Linux Foundation. All rights reserved. */ #include @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -4519,10 +4520,6 @@ static unsigned long set_svm_area(struct file *file, struct kgsl_process_private *private = dev_priv->process_priv; unsigned long ret; - /* Make sure there isn't a vma conflict in the chosen range */ - if (find_vma_intersection(current->mm, addr, addr + len - 1)) - return -ENOMEM; - /* * Do additoinal constraints checking on the address. Passing MAP_FIXED * ensures that the address we want gets checked @@ -4547,6 +4544,7 @@ static unsigned long get_svm_unmapped_area(struct file *file, unsigned long align = get_align(entry); unsigned long ret, iova; u64 start = 0, end = 0; + struct vm_area_struct *vma; if (flags & MAP_FIXED) { /* Even fixed addresses need to obey alignment */ @@ -4575,9 +4573,14 @@ static unsigned long get_svm_unmapped_area(struct file *file, len, align); while (!IS_ERR_VALUE(iova)) { - ret = set_svm_area(file, entry, iova, len, flags); - if (!IS_ERR_VALUE(ret)) - return ret; + vma = find_vma_intersection(current->mm, iova, iova + len - 1); + if (vma) { + iova = vma->vm_start; + } else { + ret = set_svm_area(file, entry, iova, len, flags); + if (!IS_ERR_VALUE(ret)) + return ret; + } iova = kgsl_mmu_find_svm_region(private->pagetable, start, iova - 1, len, align);