diff options
author | Jack Diver <diverj@google.com> | 2023-11-22 17:15:57 +0000 |
---|---|---|
committer | Jack Diver <diverj@google.com> | 2024-02-28 14:58:40 +0000 |
commit | dec457352147d282921e0ae81ce3a7154e80c64e (patch) | |
tree | bc73b052f3106dec85934102ab7aa1d6000d75cd | |
parent | ef62a44e1e80286433fae8918996eb57647ba84c (diff) | |
download | gpu-dec457352147d282921e0ae81ce3a7154e80c64e.tar.gz |
mali_pixel: Periodically read ACPM GPU signal
Use ACPM GPU signal to make enable/disable decisions for the SLC
partition.
Currently, the signal is sampled during scheduling tick.
Bug: 313458962
Test: gfxbench
Change-Id: Ife0adedf6006daaf17062a0f555d126c1fd45465
Signed-off-by: Jack Diver <diverj@google.com>
-rw-r--r-- | common/include/uapi/gpu/arm/midgard/platform/pixel/pixel_memory_group_manager.h | 2 | ||||
-rw-r--r-- | mali_kbase/backend/gpu/mali_kbase_js_backend.c | 3 | ||||
-rw-r--r-- | mali_kbase/csf/mali_kbase_csf_scheduler.c | 4 | ||||
-rw-r--r-- | mali_kbase/mali_kbase_config.c | 9 | ||||
-rw-r--r-- | mali_kbase/mali_kbase_config.h | 18 | ||||
-rw-r--r-- | mali_kbase/platform/pixel/pixel_gpu.c | 1 | ||||
-rw-r--r-- | mali_kbase/platform/pixel/pixel_gpu_slc.c | 10 | ||||
-rw-r--r-- | mali_kbase/platform/pixel/pixel_gpu_slc.h | 4 | ||||
-rw-r--r-- | mali_pixel/memory_group_manager.c | 8 | ||||
-rw-r--r-- | mali_pixel/pixel_slc.c | 45 | ||||
-rw-r--r-- | mali_pixel/pixel_slc.h | 8 |
11 files changed, 111 insertions, 1 deletions
diff --git a/common/include/uapi/gpu/arm/midgard/platform/pixel/pixel_memory_group_manager.h b/common/include/uapi/gpu/arm/midgard/platform/pixel/pixel_memory_group_manager.h index d410f7b..2a27f4f 100644 --- a/common/include/uapi/gpu/arm/midgard/platform/pixel/pixel_memory_group_manager.h +++ b/common/include/uapi/gpu/arm/midgard/platform/pixel/pixel_memory_group_manager.h @@ -7,6 +7,8 @@ #ifndef _UAPI_PIXEL_MEMORY_GROUP_MANAGER_H_ #define _UAPI_PIXEL_MEMORY_GROUP_MANAGER_H_ +void pixel_mgm_slc_update_signal(struct memory_group_manager_device* mgm_dev, u64 signal); + void pixel_mgm_slc_inc_refcount(struct memory_group_manager_device* mgm_dev); void pixel_mgm_slc_dec_refcount(struct memory_group_manager_device* mgm_dev); diff --git a/mali_kbase/backend/gpu/mali_kbase_js_backend.c b/mali_kbase/backend/gpu/mali_kbase_js_backend.c index be72c4a..304737f 100644 --- a/mali_kbase/backend/gpu/mali_kbase_js_backend.c +++ b/mali_kbase/backend/gpu/mali_kbase_js_backend.c @@ -244,6 +244,9 @@ static enum hrtimer_restart timer_callback(struct hrtimer *timer) spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags); + /* Inform platform of scheduling event */ + kbasep_platform_event_tick_tock(kbdev); + return HRTIMER_NORESTART; } diff --git a/mali_kbase/csf/mali_kbase_csf_scheduler.c b/mali_kbase/csf/mali_kbase_csf_scheduler.c index 8ead416..9e47a1e 100644 --- a/mali_kbase/csf/mali_kbase_csf_scheduler.c +++ b/mali_kbase/csf/mali_kbase_csf_scheduler.c @@ -43,6 +43,7 @@ #include <mali_kbase_gpu_metrics.h> #include <csf/mali_kbase_csf_trace_buffer.h> #endif /* CONFIG_MALI_TRACE_POWER_GPU_WORK_PERIOD */ +#include <uapi/gpu/arm/midgard/platform/pixel/pixel_memory_group_manager.h> /* Value to indicate that a queue group is not groups_to_schedule list */ #define KBASEP_GROUP_PREPARED_SEQ_NUM_INVALID (U32_MAX) @@ -6685,6 +6686,9 @@ static int kbase_csf_scheduler_kthread(void *data) dev_dbg(kbdev->dev, "Waking up for event after a scheduling iteration."); wake_up_all(&kbdev->csf.event_wait); + + /* Inform platform of scheduling event */ + kbasep_platform_event_tick_tock(kbdev); } /* Wait for the other thread, that signaled the exit, to call kthread_stop() */ diff --git a/mali_kbase/mali_kbase_config.c b/mali_kbase/mali_kbase_config.c index 72080a7..669e1c3 100644 --- a/mali_kbase/mali_kbase_config.c +++ b/mali_kbase/mali_kbase_config.c @@ -119,6 +119,15 @@ void kbasep_platform_event_work_end(void *param) platform_funcs_p->platform_handler_work_end_func(param); } +void kbasep_platform_event_tick_tock(struct kbase_device *kbdev) +{ + struct kbase_platform_funcs_conf *platform_funcs_p; + + platform_funcs_p = (struct kbase_platform_funcs_conf*)PLATFORM_FUNCS; + if (platform_funcs_p && platform_funcs_p->platform_handler_tick_tock) + platform_funcs_p->platform_handler_tick_tock(kbdev); +} + int kbasep_platform_fw_config_init(struct kbase_device *kbdev) { struct kbase_platform_funcs_conf *platform_funcs_p; diff --git a/mali_kbase/mali_kbase_config.h b/mali_kbase/mali_kbase_config.h index 7f6d3ed..549c170 100644 --- a/mali_kbase/mali_kbase_config.h +++ b/mali_kbase/mali_kbase_config.h @@ -138,6 +138,14 @@ struct kbase_platform_funcs_conf { */ void (*platform_handler_context_idle)(struct kbase_context *kctx); /** + * platform_handler_tick_tock - Platform specific callback when a scheduler tick/tock occurs. + * + * @kbdev: kbase_device pointer + * + * Context: Process context + */ + void (*platform_handler_tick_tock)(struct kbase_device *kbdev); + /** * platform_handler_work_begin_func - Platform specific handler whose * function changes depending on the * backend used. @@ -634,6 +642,16 @@ void kbasep_platform_event_work_begin(void *param); void kbasep_platform_event_work_end(void *param); /** + * kbasep_platform_tick_tock - Platform specific callback when a scheduler tick/tock occurs. + * + * @kbdev: kbase_device pointer + * + * Function calls a platform defined routine if specified in the configuration attributes. + * + */ +void kbasep_platform_event_tick_tock(struct kbase_device *kbdev); + +/** * kbasep_platform_fw_config_init - Platform specific callback to configure FW * * @kbdev - kbase_device pointer diff --git a/mali_kbase/platform/pixel/pixel_gpu.c b/mali_kbase/platform/pixel/pixel_gpu.c index 5ac8807..1ae6db6 100644 --- a/mali_kbase/platform/pixel/pixel_gpu.c +++ b/mali_kbase/platform/pixel/pixel_gpu.c @@ -328,6 +328,7 @@ struct kbase_platform_funcs_conf platform_funcs = { #endif /* CONFIG_MALI_MIDGARD_DVFS */ .platform_handler_context_active = &gpu_slc_kctx_active, .platform_handler_context_idle = &gpu_slc_kctx_idle, + .platform_handler_tick_tock = &gpu_slc_tick_tock, .platform_fw_cfg_init_func = &gpu_fw_cfg_init, .platform_handler_core_dump_func = &gpu_sscd_dump, }; diff --git a/mali_kbase/platform/pixel/pixel_gpu_slc.c b/mali_kbase/platform/pixel/pixel_gpu_slc.c index e8aae75..cf330af 100644 --- a/mali_kbase/platform/pixel/pixel_gpu_slc.c +++ b/mali_kbase/platform/pixel/pixel_gpu_slc.c @@ -126,6 +126,16 @@ void gpu_slc_kctx_idle(struct kbase_context *kctx) } /** + * gpu_slc_tick_tock() - Called when a GPU scheduling kick occurs + * + * @kbdev: The &struct kbase_device for the GPU. + */ +void gpu_slc_tick_tock(struct kbase_device *kbdev) +{ + pixel_mgm_slc_update_signal(kbdev->mgm_dev, 0); +} + +/** * gpu_slc_init - Initialize the SLC context for the GPU * * @kbdev: The &struct kbase_device for the GPU. diff --git a/mali_kbase/platform/pixel/pixel_gpu_slc.h b/mali_kbase/platform/pixel/pixel_gpu_slc.h index 82d0779..cca2af9 100644 --- a/mali_kbase/platform/pixel/pixel_gpu_slc.h +++ b/mali_kbase/platform/pixel/pixel_gpu_slc.h @@ -22,6 +22,8 @@ void gpu_slc_kctx_term(struct kbase_context *kctx); void gpu_slc_kctx_active(struct kbase_context *kctx); void gpu_slc_kctx_idle(struct kbase_context *kctx); + +void gpu_slc_tick_tock(struct kbase_device *kbdev); #else static int __maybe_unused gpu_pixel_handle_buffer_liveness_update_ioctl(struct kbase_context* kctx, struct kbase_ioctl_buffer_liveness_update* update) @@ -40,6 +42,8 @@ static void __maybe_unused gpu_slc_kctx_term(struct kbase_context* kctx) { (void static void __maybe_unused gpu_slc_kctx_active(struct kbase_context *kctx) { (void)kctx; } static void __maybe_unused gpu_slc_kctx_idle(struct kbase_context *kctx) { (void)kctx; } + +static void __maybe_unused gpu_slc_tick_tock(struct kbase_device *kbdev) { (void)kbdev; } #endif /* CONFIG_MALI_PIXEL_GPU_SLC */ #endif /* _PIXEL_GPU_SLC_H_ */ diff --git a/mali_pixel/memory_group_manager.c b/mali_pixel/memory_group_manager.c index bc596bb..e85c4d2 100644 --- a/mali_pixel/memory_group_manager.c +++ b/mali_pixel/memory_group_manager.c @@ -533,6 +533,14 @@ static vm_fault_t mgm_vmf_insert_pfn_prot( return fault; } +void pixel_mgm_slc_update_signal(struct memory_group_manager_device* mgm_dev, u64 signal) +{ + struct mgm_groups *const data = mgm_dev->data; + + slc_update_signal(&data->slc_data, signal); +} +EXPORT_SYMBOL_GPL(pixel_mgm_slc_update_signal); + void pixel_mgm_slc_inc_refcount(struct memory_group_manager_device* mgm_dev) { struct mgm_groups *const data = mgm_dev->data; diff --git a/mali_pixel/pixel_slc.c b/mali_pixel/pixel_slc.c index 78f1b74..f06d495 100644 --- a/mali_pixel/pixel_slc.c +++ b/mali_pixel/pixel_slc.c @@ -6,11 +6,13 @@ */ #include <linux/atomic.h> +#include <linux/io.h> #include <linux/of.h> #include <linux/platform_device.h> #include <linux/slab.h> #include <linux/dev_printk.h> /* Pixel integration includes */ +#include <soc/google/acpm_ipc_ctrl.h> #include "pixel_slc.h" @@ -38,6 +40,7 @@ #define PBHA_BIT_MASK (0xf) #define PARTITION_DISABLE_HYSTERESIS (msecs_to_jiffies(100)) +#define PARTITION_ENABLE_THRESHOLD (7) /** @@ -53,7 +56,7 @@ static bool partition_required(struct slc_partition *pt) { lockdep_assert_held(&pt->lock); - return atomic_read(&pt->refcount); + return atomic_read(&pt->refcount) && (pt->signal >= PARTITION_ENABLE_THRESHOLD); } /** @@ -225,6 +228,29 @@ void slc_dec_refcount(struct slc_data *data) } } +void slc_update_signal(struct slc_data *data, u64 signal) +{ + struct slc_partition *pt = &data->partition; + unsigned long flags; + + spin_lock_irqsave(&pt->lock, flags); + + /* Use ACPM signal when available */ + if (data->signal) + pt->signal = ioread64((u64 __iomem*)data->signal); + else + pt->signal = signal; + + if (partition_required(pt)) + /* Enable the partition immediately if it's required */ + enable_partition(data, pt); + else + /* Lazily disable the partition if it's no longer required */ + queue_disable_worker(data); + + spin_unlock_irqrestore(&pt->lock, flags); +} + /** * init_partition - Register and initialize a partition with the SLC driver. * @@ -264,6 +290,7 @@ static int init_partition(struct slc_data *data, struct slc_partition *pt, u32 i .pbha = pbha, .enabled = false, .refcount = ATOMIC_INIT(0), + .signal = 0, }; spin_lock_init(&pt->lock); @@ -316,6 +343,22 @@ int slc_init_data(struct slc_data *data, struct device* dev) goto err_exit; } + if (IS_ENABLED(PIXEL_GPU_SLC_ACPM_SIGNAL)) { + u32 size; + + /* Obtain a handle to the ACPM provided GPU partition signal */ + if ((ret = acpm_ipc_get_buffer("GPU_SIGNAL", &data->signal, &size))) { + dev_err(data->dev, "failed to retrieve SLC GPU signal: %d", ret); + goto err_exit; + } + + /* Validate the signal buffer size */ + if (size != sizeof(u64)) { + dev_err(data->dev, "SLC GPU signal size incorrect: %d", size); + goto err_exit; + } + } + if ((ret = init_partition(data, &data->partition, 0))) goto pt_init_err_exit; diff --git a/mali_pixel/pixel_slc.h b/mali_pixel/pixel_slc.h index bcaf1ff..1ac3da4 100644 --- a/mali_pixel/pixel_slc.h +++ b/mali_pixel/pixel_slc.h @@ -51,6 +51,9 @@ struct slc_partition { /** @lock: Lock protecting enable/disable ops on this partition */ spinlock_t lock; + + /** @signal: Partition enable/disable signal from SLC governor */ + u64 signal; }; /** @@ -68,6 +71,9 @@ struct slc_data { /** @disable_work: Work item used to queue lazy SLC partition disable ops. */ struct delayed_work disable_work; + + /** @signal: Partition enable/disable signal from SLC governor. */ + char __iomem *signal; }; int slc_init_data(struct slc_data *data, struct device* dev); @@ -82,4 +88,6 @@ void slc_inc_refcount(struct slc_data *data); void slc_dec_refcount(struct slc_data *data); +void slc_update_signal(struct slc_data *data, u64 signal); + #endif /* _PIXEL_SLC_H_ */ |