cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

msm_ringbuffer.c (3160B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Copyright (C) 2013 Red Hat
      4 * Author: Rob Clark <robdclark@gmail.com>
      5 */
      6
      7#include "msm_ringbuffer.h"
      8#include "msm_gpu.h"
      9
     10static uint num_hw_submissions = 8;
     11MODULE_PARM_DESC(num_hw_submissions, "The max # of jobs to write into ringbuffer (default 8)");
     12module_param(num_hw_submissions, uint, 0600);
     13
     14static struct dma_fence *msm_job_run(struct drm_sched_job *job)
     15{
     16	struct msm_gem_submit *submit = to_msm_submit(job);
     17	struct msm_fence_context *fctx = submit->ring->fctx;
     18	struct msm_gpu *gpu = submit->gpu;
     19	int i;
     20
     21	submit->hw_fence = msm_fence_alloc(fctx);
     22
     23	for (i = 0; i < submit->nr_bos; i++) {
     24		struct drm_gem_object *obj = &submit->bos[i].obj->base;
     25
     26		msm_gem_lock(obj);
     27		msm_gem_unpin_vma_fenced(submit->bos[i].vma, fctx);
     28		submit->bos[i].flags &= ~BO_VMA_PINNED;
     29		msm_gem_unlock(obj);
     30	}
     31
     32	pm_runtime_get_sync(&gpu->pdev->dev);
     33
     34	/* TODO move submit path over to using a per-ring lock.. */
     35	mutex_lock(&gpu->lock);
     36
     37	msm_gpu_submit(gpu, submit);
     38
     39	mutex_unlock(&gpu->lock);
     40
     41	pm_runtime_put(&gpu->pdev->dev);
     42
     43	return dma_fence_get(submit->hw_fence);
     44}
     45
     46static void msm_job_free(struct drm_sched_job *job)
     47{
     48	struct msm_gem_submit *submit = to_msm_submit(job);
     49
     50	drm_sched_job_cleanup(job);
     51	msm_gem_submit_put(submit);
     52}
     53
     54static const struct drm_sched_backend_ops msm_sched_ops = {
     55	.run_job = msm_job_run,
     56	.free_job = msm_job_free
     57};
     58
     59struct msm_ringbuffer *msm_ringbuffer_new(struct msm_gpu *gpu, int id,
     60		void *memptrs, uint64_t memptrs_iova)
     61{
     62	struct msm_ringbuffer *ring;
     63	long sched_timeout;
     64	char name[32];
     65	int ret;
     66
     67	/* We assume everwhere that MSM_GPU_RINGBUFFER_SZ is a power of 2 */
     68	BUILD_BUG_ON(!is_power_of_2(MSM_GPU_RINGBUFFER_SZ));
     69
     70	ring = kzalloc(sizeof(*ring), GFP_KERNEL);
     71	if (!ring) {
     72		ret = -ENOMEM;
     73		goto fail;
     74	}
     75
     76	ring->gpu = gpu;
     77	ring->id = id;
     78
     79	ring->start = msm_gem_kernel_new(gpu->dev, MSM_GPU_RINGBUFFER_SZ,
     80		check_apriv(gpu, MSM_BO_WC | MSM_BO_GPU_READONLY),
     81		gpu->aspace, &ring->bo, &ring->iova);
     82
     83	if (IS_ERR(ring->start)) {
     84		ret = PTR_ERR(ring->start);
     85		ring->start = NULL;
     86		goto fail;
     87	}
     88
     89	msm_gem_object_set_name(ring->bo, "ring%d", id);
     90
     91	ring->end   = ring->start + (MSM_GPU_RINGBUFFER_SZ >> 2);
     92	ring->next  = ring->start;
     93	ring->cur   = ring->start;
     94
     95	ring->memptrs = memptrs;
     96	ring->memptrs_iova = memptrs_iova;
     97
     98	 /* currently managing hangcheck ourselves: */
     99	sched_timeout = MAX_SCHEDULE_TIMEOUT;
    100
    101	ret = drm_sched_init(&ring->sched, &msm_sched_ops,
    102			num_hw_submissions, 0, sched_timeout,
    103			NULL, NULL, to_msm_bo(ring->bo)->name, gpu->dev->dev);
    104	if (ret) {
    105		goto fail;
    106	}
    107
    108	INIT_LIST_HEAD(&ring->submits);
    109	spin_lock_init(&ring->submit_lock);
    110	spin_lock_init(&ring->preempt_lock);
    111
    112	snprintf(name, sizeof(name), "gpu-ring-%d", ring->id);
    113
    114	ring->fctx = msm_fence_context_alloc(gpu->dev, &ring->memptrs->fence, name);
    115
    116	return ring;
    117
    118fail:
    119	msm_ringbuffer_destroy(ring);
    120	return ERR_PTR(ret);
    121}
    122
    123void msm_ringbuffer_destroy(struct msm_ringbuffer *ring)
    124{
    125	if (IS_ERR_OR_NULL(ring))
    126		return;
    127
    128	drm_sched_fini(&ring->sched);
    129
    130	msm_fence_context_free(ring->fctx);
    131
    132	msm_gem_kernel_put(ring->bo, ring->gpu->aspace);
    133
    134	kfree(ring);
    135}