From 82d34e97fc1f1e425ee5447e5c33e2febebef6ce Mon Sep 17 00:00:00 2001 From: Jack Diver Date: Fri, 4 Aug 2023 09:27:47 +0000 Subject: mali_kbase: platform: Batch MMU flushes after liveness update Test: Boot to home, gfx-bench sweep Bug: 294167925 (cherry picked from https://partner-android-review.googlesource.com/q/commit:3143995156d9372ca6af0be57aa29dd0ec14cce1) Merged-In: I4a122fe023b43c3763884fda99cfed17048a3eb0 Change-Id: I4a122fe023b43c3763884fda99cfed17048a3eb0 Signed-off-by: Jack Diver --- mali_kbase/platform/pixel/pixel_gpu_slc.c | 57 +++++++++++++++++++++++++++---- 1 file changed, 50 insertions(+), 7 deletions(-) diff --git a/mali_kbase/platform/pixel/pixel_gpu_slc.c b/mali_kbase/platform/pixel/pixel_gpu_slc.c index 152779d..eebdeb1 100644 --- a/mali_kbase/platform/pixel/pixel_gpu_slc.c +++ b/mali_kbase/platform/pixel/pixel_gpu_slc.c @@ -17,6 +17,11 @@ #include "mali_kbase_config_platform.h" #include "pixel_gpu_slc.h" +struct dirty_region { + u64 first_vpfn; + u64 last_vpfn; + u64 dirty_pgds; +}; /** * struct gpu_slc_liveness_update_info - Buffer info, and live ranges @@ -101,21 +106,33 @@ invalid: /** * gpu_slc_migrate_region - Add PBHA that will make the pages SLC cacheable * - * @kctx: The &struct kbase_context - * @reg: The gpu memory region migrate to an SLC cacheable memory group + * @kctx: The &struct kbase_context + * @reg: The gpu memory region migrate to an SLC cacheable memory group + * @dirty_reg: The &struct dirty_region containing the extent of the dirty page table entries */ -static void gpu_slc_migrate_region(struct kbase_context *kctx, struct kbase_va_region* reg) +static void gpu_slc_migrate_region(struct kbase_context *kctx, struct kbase_va_region *reg, struct dirty_region *dirty_reg) { int err; + u64 vpfn; + size_t page_nr; KBASE_DEBUG_ASSERT(kctx); KBASE_DEBUG_ASSERT(reg); - err = kbase_mmu_update_pages(kctx, reg->start_pfn, + vpfn = reg->start_pfn; + page_nr = kbase_reg_current_backed_size(reg); + + err = kbase_mmu_update_pages_no_flush(kctx->kbdev, &kctx->mmu, vpfn, kbase_get_gpu_phy_pages(reg), - kbase_reg_current_backed_size(reg), + page_nr, reg->flags, - MGM_SLC_GROUP_ID); + MGM_SLC_GROUP_ID, + &dirty_reg->dirty_pgds); + + /* Track the dirty region */ + dirty_reg->first_vpfn = min(dirty_reg->first_vpfn, vpfn); + dirty_reg->last_vpfn = max(dirty_reg->last_vpfn, vpfn + page_nr); + if (err) dev_warn(kctx->kbdev->dev, "pixel: failed to move region to SLC: %d", err); else @@ -123,6 +140,24 @@ static void gpu_slc_migrate_region(struct kbase_context *kctx, struct kbase_va_r reg->gpu_alloc->group_id = MGM_SLC_GROUP_ID; } +/** + * gpu_slc_flush_dirty_region - Perform an MMU flush for a dirty page region + * + * @kctx: The &struct kbase_context + * @dirty_reg: The &struct dirty_region containing the extent of the dirty page table entries + */ +static void gpu_slc_flush_dirty_region(struct kbase_context *kctx, struct dirty_region *dirty_reg) +{ + size_t const dirty_page_nr = + (dirty_reg->last_vpfn - min(dirty_reg->first_vpfn, dirty_reg->last_vpfn)); + + if (!dirty_page_nr) + return; + + kbase_mmu_flush_invalidate_update_pages( + kctx->kbdev, kctx, dirty_reg->first_vpfn, dirty_page_nr, dirty_reg->dirty_pgds); +} + /** * gpu_slc_resize_partition - Attempt to resize the GPU's SLC partition to meet demand. * @@ -168,6 +203,11 @@ static void gpu_slc_liveness_update(struct kbase_context* kctx, struct kbase_device* kbdev = kctx->kbdev; struct pixel_context *pc = kbdev->platform_context; struct pixel_platform_data *kctx_pd = kctx->platform_data; + struct dirty_region dirty_reg = { + .first_vpfn = U64_MAX, + .last_vpfn = 0, + .dirty_pgds = 0, + }; u64 current_usage = 0; u64 current_demand = 0; u64 free_space; @@ -210,7 +250,7 @@ static void gpu_slc_liveness_update(struct kbase_context* kctx, /* Check whether there's free space in the partition to store the buffer */ if (free_space >= current_usage + size) - gpu_slc_migrate_region(kctx, reg); + gpu_slc_migrate_region(kctx, reg, &dirty_reg); /* This may be true, even if the space calculation above returned false, * as a previous call to this function may have migrated the region. @@ -231,6 +271,9 @@ static void gpu_slc_liveness_update(struct kbase_context* kctx, break; } } + /* Perform single page table flush */ + gpu_slc_flush_dirty_region(kctx, &dirty_reg); + /* Indicates a missing live range end marker */ WARN_ON_ONCE(current_demand != 0 || current_usage != 0); -- cgit v1.2.3