We can skip children resources when the parent resource does not cover the range. This should help vmf_insert_* users on x86, such as several DRM drivers. On my AMD Ryzen 5 7520C, when streaming data from cpu memory into amdgpu bo, the throughput goes from 5.1GB/s to 6.6GB/s. perf report says 34.69%--__do_fault 34.60%--amdgpu_gem_fault 34.00%--ttm_bo_vm_fault_reserved 32.95%--vmf_insert_pfn_prot 25.89%--track_pfn_insert 24.35%--lookup_memtype 21.77%--pat_pagerange_is_ram 20.80%--walk_system_ram_range 17.42%--find_next_iomem_res before this change, and 26.67%--__do_fault 26.57%--amdgpu_gem_fault 25.83%--ttm_bo_vm_fault_reserved 24.40%--vmf_insert_pfn_prot 14.30%--track_pfn_insert 12.20%--lookup_memtype 9.34%--pat_pagerange_is_ram 8.22%--walk_system_ram_range 5.09%--find_next_iomem_res after. Signed-off-by: Chia-I Wu <olvaffe@xxxxxxxxx> --- kernel/resource.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/kernel/resource.c b/kernel/resource.c index fcbca39dbc450..19b84b4f9a577 100644 --- a/kernel/resource.c +++ b/kernel/resource.c @@ -326,6 +326,7 @@ static int find_next_iomem_res(resource_size_t start, resource_size_t end, unsigned long flags, unsigned long desc, struct resource *res) { + bool skip_children = false; struct resource *p; if (!res) @@ -336,7 +337,7 @@ static int find_next_iomem_res(resource_size_t start, resource_size_t end, read_lock(&resource_lock); - for_each_resource(&iomem_resource, p, false) { + for_each_resource(&iomem_resource, p, skip_children) { /* If we passed the resource we are looking for, stop */ if (p->start > end) { p = NULL; @@ -344,8 +345,11 @@ static int find_next_iomem_res(resource_size_t start, resource_size_t end, } /* Skip until we find a range that matches what we look for */ - if (p->end < start) + if (p->end < start) { + skip_children = true; continue; + } + skip_children = false; if ((p->flags & flags) != flags) continue; -- 2.45.1.288.g0e0cd299f1-goog