| 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); |