https://bugs.freedesktop.org/show_bug.cgi?id=107328
Bug ID: 107328 Summary: radeon_gart_table_vram_pin takes 473 ms during ACPI S3 resume Product: DRI Version: DRI git Hardware: Other OS: All Status: NEW Severity: normal Priority: medium Component: DRM/Radeon Assignee: dri-devel@lists.freedesktop.org Reporter: pmenzel+bugs.freedesktop@molgen.mpg.de
Created attachment 140760 --> https://bugs.freedesktop.org/attachment.cgi?id=140760&action=edit Screenshot from HTML output of `sleepgraph.py` with `devicefilter: radeon` and `maxdepth: 20`
On a ASRock E350M1 with Linux 4.18-rc5+, profiling ACPI S3 suspend and resume time with `sleepgraph.py` from pm-graph [1], the radeon module over half a second to resume, which is also visible adding `initcall_debug` to the command line.
radeon @ 0000:00:01.0 {radeon} async_device (Total Suspend: 36.541 ms Total Resume: 687.797 ms)
evergreen_startup [radeon] (562.983 ms @ 403.615437) → radeon_gart_table_vram_pin [radeon] (473.376 ms @ 403.617537)
The function from `drivers/gpu/drm/radeon/radeon_gart.c` looks like below, and the problem is the for loop in the end.
/** * radeon_gart_table_vram_pin - pin gart page table in vram * * @rdev: radeon_device pointer * * Pin the GART page table in vram so it will not be moved * by the memory manager (pcie r4xx, r5xx+). These asics require the * gart table to be in video memory. * Returns 0 for success, error for failure. */ int radeon_gart_table_vram_pin(struct radeon_device *rdev) { uint64_t gpu_addr; int r;
r = radeon_bo_reserve(rdev->gart.robj, false); if (unlikely(r != 0)) return r; r = radeon_bo_pin(rdev->gart.robj, RADEON_GEM_DOMAIN_VRAM, &gpu_addr); if (r) { radeon_bo_unreserve(rdev->gart.robj); return r; } r = radeon_bo_kmap(rdev->gart.robj, &rdev->gart.ptr); if (r) radeon_bo_unpin(rdev->gart.robj); radeon_bo_unreserve(rdev->gart.robj); rdev->gart.table_addr = gpu_addr;
if (!r) { int i;
/* We might have dropped some GART table updates while it wasn't * mapped, restore all entries */ for (i = 0; i < rdev->gart.num_gpu_pages; i++) radeon_gart_set_page(rdev, i, rdev->gart.pages_entry[i]); mb(); radeon_gart_tlb_flush(rdev); }
return r; }
Is there a way to get rid of the for loop? Some memset equivalent?
[1]: https://github.com/01org/pm-graph