diff options
Diffstat (limited to 'dvalin/kernel/drivers/gpu/arm/midgard/tl/backend/mali_kbase_timeline_csf.c')
-rw-r--r-- | dvalin/kernel/drivers/gpu/arm/midgard/tl/backend/mali_kbase_timeline_csf.c | 171 |
1 files changed, 171 insertions, 0 deletions
diff --git a/dvalin/kernel/drivers/gpu/arm/midgard/tl/backend/mali_kbase_timeline_csf.c b/dvalin/kernel/drivers/gpu/arm/midgard/tl/backend/mali_kbase_timeline_csf.c new file mode 100644 index 0000000..a2868da --- /dev/null +++ b/dvalin/kernel/drivers/gpu/arm/midgard/tl/backend/mali_kbase_timeline_csf.c @@ -0,0 +1,171 @@ +// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note +/* + * + * (C) COPYRIGHT 2019-2021 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the + * GNU General Public License version 2 as published by the Free Software + * Foundation, and any use by you of this program is subject to the terms + * of such GNU license. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you can access it online at + * http://www.gnu.org/licenses/gpl-2.0.html. + * + */ + +#include <tl/mali_kbase_tracepoints.h> +#include <tl/mali_kbase_timeline.h> +#include <tl/mali_kbase_timeline_priv.h> + +#include <mali_kbase.h> + +void kbase_create_timeline_objects(struct kbase_device *kbdev) +{ + unsigned int as_nr; + unsigned int slot_i; + struct kbase_context *kctx; + struct kbase_timeline *timeline = kbdev->timeline; + struct kbase_tlstream *summary = + &kbdev->timeline->streams[TL_STREAM_TYPE_OBJ_SUMMARY]; + + /* Summarize the Address Space objects. */ + for (as_nr = 0; as_nr < kbdev->nr_hw_address_spaces; as_nr++) + __kbase_tlstream_tl_new_as(summary, &kbdev->as[as_nr], as_nr); + + /* Create Legacy GPU object to track in AOM for dumping */ + __kbase_tlstream_tl_new_gpu(summary, + kbdev, + kbdev->gpu_props.props.raw_props.gpu_id, + kbdev->gpu_props.num_cores); + + + for (as_nr = 0; as_nr < kbdev->nr_hw_address_spaces; as_nr++) + __kbase_tlstream_tl_lifelink_as_gpu(summary, + &kbdev->as[as_nr], + kbdev); + + /* Trace the creation of a new kbase device and set its properties. */ + __kbase_tlstream_tl_kbase_new_device(summary, + kbdev->gpu_props.props.raw_props.gpu_id, + kbdev->gpu_props.num_cores, kbdev->csf.global_iface.group_num, + kbdev->nr_hw_address_spaces); + + /* Lock the context list, to ensure no changes to the list are made + * while we're summarizing the contexts and their contents. + */ + mutex_lock(&timeline->tl_kctx_list_lock); + + /* Hold the scheduler lock while we emit the current state + * We also need to continue holding the lock until after the first body + * stream tracepoints are emitted to ensure we don't change the + * scheduler until after then + */ + mutex_lock(&kbdev->csf.scheduler.lock); + + for (slot_i = 0; slot_i < kbdev->csf.global_iface.group_num; slot_i++) { + + struct kbase_queue_group *group = + kbdev->csf.scheduler.csg_slots[slot_i].resident_group; + + if (group) + __kbase_tlstream_tl_kbase_device_program_csg(summary, + kbdev->gpu_props.props.raw_props.gpu_id, + group->handle, slot_i); + } + + /* Reset body stream buffers while holding the kctx lock. + * As we are holding the lock, we can guarantee that no kctx creation or + * deletion tracepoints can be fired from outside of this function by + * some other thread. + */ + kbase_timeline_streams_body_reset(timeline); + + mutex_unlock(&kbdev->csf.scheduler.lock); + + /* For each context in the device... */ + list_for_each_entry(kctx, &timeline->tl_kctx_list, tl_kctx_list_node) { + size_t i; + struct kbase_tlstream *body = + &timeline->streams[TL_STREAM_TYPE_OBJ]; + + /* Lock the context's KCPU queues, to ensure no KCPU-queue + * related actions can occur in this context from now on. + */ + mutex_lock(&kctx->csf.kcpu_queues.lock); + + /* Acquire the MMU lock, to ensure we don't get a concurrent + * address space assignment while summarizing this context's + * address space. + */ + mutex_lock(&kbdev->mmu_hw_mutex); + + /* Trace the context itself into the body stream, not the + * summary stream. + * We place this in the body to ensure it is ordered after any + * other tracepoints related to the contents of the context that + * might have been fired before acquiring all of the per-context + * locks. + * This ensures that those tracepoints will not actually affect + * the object model state, as they reference a context that + * hasn't been traced yet. They may, however, cause benign + * errors to be emitted. + */ + __kbase_tlstream_tl_kbase_new_ctx(body, kctx->id, + kbdev->gpu_props.props.raw_props.gpu_id); + + /* Also trace with the legacy AOM tracepoint for dumping */ + __kbase_tlstream_tl_new_ctx(body, + kctx, + kctx->id, + (u32)(kctx->tgid)); + + /* Trace the currently assigned address space */ + if (kctx->as_nr != KBASEP_AS_NR_INVALID) + __kbase_tlstream_tl_kbase_ctx_assign_as(body, kctx->id, + kctx->as_nr); + + + /* Trace all KCPU queues in the context into the body stream. + * As we acquired the KCPU lock after resetting the body stream, + * it's possible that some KCPU-related events for this context + * occurred between that reset and now. + * These will cause errors to be emitted when parsing the + * timeline, but they will not affect the correctness of the + * object model. + */ + for (i = 0; i < KBASEP_MAX_KCPU_QUEUES; i++) { + const struct kbase_kcpu_command_queue *kcpu_queue = + kctx->csf.kcpu_queues.array[i]; + + if (kcpu_queue) + __kbase_tlstream_tl_kbase_new_kcpuqueue( + body, kcpu_queue, kcpu_queue->kctx->id, + kcpu_queue->num_pending_cmds); + } + + mutex_unlock(&kbdev->mmu_hw_mutex); + mutex_unlock(&kctx->csf.kcpu_queues.lock); + + /* Now that all per-context locks for this context have been + * released, any per-context tracepoints that are fired from + * any other threads will go into the body stream after + * everything that was just summarised into the body stream in + * this iteration of the loop, so will start to correctly update + * the object model state. + */ + } + + mutex_unlock(&timeline->tl_kctx_list_lock); + + /* Static object are placed into summary packet that needs to be + * transmitted first. Flush all streams to make it available to + * user space. + */ + kbase_timeline_streams_flush(timeline); +} |