blob: b85866bd76dff665c33d6a3eeb5269da4a564b61 [file] [log] [blame]
From 7219e9da91414749738a87aced21df1aa91eaa5d Mon Sep 17 00:00:00 2001
From: Raffaele Aquilone <raffaele.aquilone@arm.com>
Date: Wed, 21 Feb 2024 11:03:37 +0000
Subject: [PATCH] GPUCORE-41458 Unpin pages when last reference to phy alloc is released
Imported USER_BUFFER handles allow user space to take additional
CPU mappings, and therefore take more than one reference to the
physical allocation of an imported handle.
As a consequence, when an imported USER_BUFFER handle is destroyed
it cannot just unpin the physical pages and move to the EMPTY
state, because user space might be holding some references to the
physical allocation. The imported handle now stops at the PINNED
state in such situations.
TI2: 1130098 (DDK precommit)
TI2: 1130172 (Base memory and defect tests)
TI2: 1130095 (GPUCORE Compute tests)
Change-Id: I870daf98cd0d8c38a62ad8c0136cb964bf87aa0d
---
diff --git a/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mem.c b/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mem.c
index 9dc49aa..7470a94 100644
--- a/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mem.c
+++ b/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mem.c
@@ -531,15 +531,20 @@
switch (alloc->imported.user_buf.state) {
case KBASE_USER_BUF_STATE_GPU_MAPPED: {
alloc->imported.user_buf.current_mapping_usage_count = 0;
- kbase_user_buf_from_gpu_mapped_to_empty(kctx, reg);
+ kbase_mem_phy_alloc_ref_read(alloc) ?
+ kbase_user_buf_from_gpu_mapped_to_pinned(kctx, reg) :
+ kbase_user_buf_from_gpu_mapped_to_empty(kctx, reg);
break;
}
case KBASE_USER_BUF_STATE_DMA_MAPPED: {
- kbase_user_buf_from_dma_mapped_to_empty(kctx, reg);
+ kbase_mem_phy_alloc_ref_read(alloc) ?
+ kbase_user_buf_from_dma_mapped_to_pinned(kctx, reg) :
+ kbase_user_buf_from_dma_mapped_to_empty(kctx, reg);
break;
}
case KBASE_USER_BUF_STATE_PINNED: {
- kbase_user_buf_from_pinned_to_empty(kctx, reg);
+ if (!kbase_mem_phy_alloc_ref_read(alloc))
+ kbase_user_buf_from_pinned_to_empty(kctx, reg);
break;
}
case KBASE_USER_BUF_STATE_EMPTY: {
diff --git a/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mem.h b/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mem.h
index 78803a2..2219f27 100644
--- a/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mem.h
+++ b/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mem.h
@@ -589,6 +589,11 @@
void kbase_mem_halt(struct kbase_device *kbdev);
void kbase_mem_term(struct kbase_device *kbdev);
+static inline unsigned int kbase_mem_phy_alloc_ref_read(struct kbase_mem_phy_alloc *alloc)
+{
+ return kref_read(&alloc->kref);
+}
+
static inline struct kbase_mem_phy_alloc *kbase_mem_phy_alloc_get(struct kbase_mem_phy_alloc *alloc)
{
kref_get(&alloc->kref);