summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJack Diver <diverj@google.com>2023-08-04 09:27:47 +0000
committerJack Diver <diverj@google.com>2023-08-22 09:52:21 +0000
commit82d34e97fc1f1e425ee5447e5c33e2febebef6ce (patch)
treec45cb1c14c81b0b0069f2ed530b42e8c5a429aaa
parentea8e91921ea617dcdad9cee5b113cf0089a0eed0 (diff)
downloadgpu-82d34e97fc1f1e425ee5447e5c33e2febebef6ce.tar.gz
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 <diverj@google.com>
-rw-r--r--mali_kbase/platform/pixel/pixel_gpu_slc.c57
1 files 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
@@ -124,6 +141,24 @@ static void gpu_slc_migrate_region(struct kbase_context *kctx, struct kbase_va_r
}
/**
+ * 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.
*
* @kbdev: The &struct kbase_device for the GPU.
@@ -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);