Home | History | Annotate | Line # | Download | only in amdgpu
      1  1.8  riastrad /*	$NetBSD: amdgpu_ctx.c,v 1.8 2021/12/19 12:38:41 riastradh Exp $	*/
      2  1.1  riastrad 
      3  1.1  riastrad /*
      4  1.1  riastrad  * Copyright 2015 Advanced Micro Devices, Inc.
      5  1.1  riastrad  *
      6  1.1  riastrad  * Permission is hereby granted, free of charge, to any person obtaining a
      7  1.1  riastrad  * copy of this software and associated documentation files (the "Software"),
      8  1.1  riastrad  * to deal in the Software without restriction, including without limitation
      9  1.1  riastrad  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     10  1.1  riastrad  * and/or sell copies of the Software, and to permit persons to whom the
     11  1.1  riastrad  * Software is furnished to do so, subject to the following conditions:
     12  1.1  riastrad  *
     13  1.1  riastrad  * The above copyright notice and this permission notice shall be included in
     14  1.1  riastrad  * all copies or substantial portions of the Software.
     15  1.1  riastrad  *
     16  1.1  riastrad  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     17  1.1  riastrad  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     18  1.1  riastrad  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     19  1.1  riastrad  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
     20  1.1  riastrad  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     21  1.1  riastrad  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     22  1.1  riastrad  * OTHER DEALINGS IN THE SOFTWARE.
     23  1.1  riastrad  *
     24  1.1  riastrad  * Authors: monk liu <monk.liu (at) amd.com>
     25  1.1  riastrad  */
     26  1.1  riastrad 
     27  1.1  riastrad #include <sys/cdefs.h>
     28  1.8  riastrad __KERNEL_RCSID(0, "$NetBSD: amdgpu_ctx.c,v 1.8 2021/12/19 12:38:41 riastradh Exp $");
     29  1.1  riastrad 
     30  1.6  riastrad #include <drm/drm_auth.h>
     31  1.1  riastrad #include "amdgpu.h"
     32  1.6  riastrad #include "amdgpu_sched.h"
     33  1.6  riastrad #include "amdgpu_ras.h"
     34  1.1  riastrad 
     35  1.5  riastrad #include <linux/nbsd-namespace.h>
     36  1.6  riastrad #define to_amdgpu_ctx_entity(e)	\
     37  1.6  riastrad 	container_of((e), struct amdgpu_ctx_entity, entity)
     38  1.5  riastrad 
     39  1.6  riastrad const unsigned int amdgpu_ctx_num_entities[AMDGPU_HW_IP_NUM] = {
     40  1.6  riastrad 	[AMDGPU_HW_IP_GFX]	=	1,
     41  1.6  riastrad 	[AMDGPU_HW_IP_COMPUTE]	=	4,
     42  1.6  riastrad 	[AMDGPU_HW_IP_DMA]	=	2,
     43  1.6  riastrad 	[AMDGPU_HW_IP_UVD]	=	1,
     44  1.6  riastrad 	[AMDGPU_HW_IP_VCE]	=	1,
     45  1.6  riastrad 	[AMDGPU_HW_IP_UVD_ENC]	=	1,
     46  1.6  riastrad 	[AMDGPU_HW_IP_VCN_DEC]	=	1,
     47  1.6  riastrad 	[AMDGPU_HW_IP_VCN_ENC]	=	1,
     48  1.6  riastrad 	[AMDGPU_HW_IP_VCN_JPEG]	=	1,
     49  1.6  riastrad };
     50  1.6  riastrad 
     51  1.6  riastrad static int amdgpu_ctx_priority_permit(struct drm_file *filp,
     52  1.6  riastrad 				      enum drm_sched_priority priority)
     53  1.6  riastrad {
     54  1.6  riastrad 	if (priority < 0 || priority >= DRM_SCHED_PRIORITY_MAX)
     55  1.6  riastrad 		return -EINVAL;
     56  1.6  riastrad 
     57  1.6  riastrad 	/* NORMAL and below are accessible by everyone */
     58  1.6  riastrad 	if (priority <= DRM_SCHED_PRIORITY_NORMAL)
     59  1.6  riastrad 		return 0;
     60  1.6  riastrad 
     61  1.6  riastrad 	if (capable(CAP_SYS_NICE))
     62  1.6  riastrad 		return 0;
     63  1.6  riastrad 
     64  1.6  riastrad 	if (drm_is_current_master(filp))
     65  1.6  riastrad 		return 0;
     66  1.6  riastrad 
     67  1.6  riastrad 	return -EACCES;
     68  1.6  riastrad }
     69  1.6  riastrad 
     70  1.6  riastrad static int amdgpu_ctx_init_entity(struct amdgpu_ctx *ctx, const u32 hw_ip, const u32 ring)
     71  1.6  riastrad {
     72  1.6  riastrad 	struct amdgpu_device *adev = ctx->adev;
     73  1.6  riastrad 	struct amdgpu_ctx_entity *entity;
     74  1.6  riastrad 	struct drm_gpu_scheduler **scheds = NULL, *sched = NULL;
     75  1.6  riastrad 	unsigned num_scheds = 0;
     76  1.6  riastrad 	enum drm_sched_priority priority;
     77  1.6  riastrad 	int r;
     78  1.6  riastrad 
     79  1.6  riastrad 	entity = kcalloc(1, offsetof(typeof(*entity), fences[amdgpu_sched_jobs]),
     80  1.6  riastrad 			 GFP_KERNEL);
     81  1.6  riastrad 	if (!entity)
     82  1.6  riastrad 		return  -ENOMEM;
     83  1.6  riastrad 
     84  1.6  riastrad 	entity->sequence = 1;
     85  1.6  riastrad 	priority = (ctx->override_priority == DRM_SCHED_PRIORITY_UNSET) ?
     86  1.6  riastrad 				ctx->init_priority : ctx->override_priority;
     87  1.6  riastrad 	switch (hw_ip) {
     88  1.6  riastrad 		case AMDGPU_HW_IP_GFX:
     89  1.6  riastrad 			sched = &adev->gfx.gfx_ring[0].sched;
     90  1.6  riastrad 			scheds = &sched;
     91  1.6  riastrad 			num_scheds = 1;
     92  1.6  riastrad 			break;
     93  1.6  riastrad 		case AMDGPU_HW_IP_COMPUTE:
     94  1.6  riastrad 			scheds = adev->gfx.compute_sched;
     95  1.6  riastrad 			num_scheds = adev->gfx.num_compute_sched;
     96  1.6  riastrad 			break;
     97  1.6  riastrad 		case AMDGPU_HW_IP_DMA:
     98  1.6  riastrad 			scheds = adev->sdma.sdma_sched;
     99  1.6  riastrad 			num_scheds = adev->sdma.num_sdma_sched;
    100  1.6  riastrad 			break;
    101  1.6  riastrad 		case AMDGPU_HW_IP_UVD:
    102  1.6  riastrad 			sched = &adev->uvd.inst[0].ring.sched;
    103  1.6  riastrad 			scheds = &sched;
    104  1.6  riastrad 			num_scheds = 1;
    105  1.6  riastrad 			break;
    106  1.6  riastrad 		case AMDGPU_HW_IP_VCE:
    107  1.6  riastrad 			sched = &adev->vce.ring[0].sched;
    108  1.6  riastrad 			scheds = &sched;
    109  1.6  riastrad 			num_scheds = 1;
    110  1.6  riastrad 			break;
    111  1.6  riastrad 		case AMDGPU_HW_IP_UVD_ENC:
    112  1.6  riastrad 			sched = &adev->uvd.inst[0].ring_enc[0].sched;
    113  1.6  riastrad 			scheds = &sched;
    114  1.6  riastrad 			num_scheds = 1;
    115  1.6  riastrad 			break;
    116  1.6  riastrad 		case AMDGPU_HW_IP_VCN_DEC:
    117  1.6  riastrad 			scheds = adev->vcn.vcn_dec_sched;
    118  1.6  riastrad 			num_scheds =  adev->vcn.num_vcn_dec_sched;
    119  1.6  riastrad 			break;
    120  1.6  riastrad 		case AMDGPU_HW_IP_VCN_ENC:
    121  1.6  riastrad 			scheds = adev->vcn.vcn_enc_sched;
    122  1.6  riastrad 			num_scheds =  adev->vcn.num_vcn_enc_sched;
    123  1.6  riastrad 			break;
    124  1.6  riastrad 		case AMDGPU_HW_IP_VCN_JPEG:
    125  1.6  riastrad 			scheds = adev->jpeg.jpeg_sched;
    126  1.6  riastrad 			num_scheds =  adev->jpeg.num_jpeg_sched;
    127  1.6  riastrad 			break;
    128  1.6  riastrad 	}
    129  1.6  riastrad 
    130  1.6  riastrad 	r = drm_sched_entity_init(&entity->entity, priority, scheds, num_scheds,
    131  1.6  riastrad 				  &ctx->guilty);
    132  1.6  riastrad 	if (r)
    133  1.6  riastrad 		goto error_free_entity;
    134  1.6  riastrad 
    135  1.6  riastrad 	ctx->entities[hw_ip][ring] = entity;
    136  1.6  riastrad 	return 0;
    137  1.6  riastrad 
    138  1.6  riastrad error_free_entity:
    139  1.6  riastrad 	kfree(entity);
    140  1.6  riastrad 
    141  1.6  riastrad 	return r;
    142  1.6  riastrad }
    143  1.6  riastrad 
    144  1.6  riastrad static int amdgpu_ctx_init(struct amdgpu_device *adev,
    145  1.6  riastrad 			   enum drm_sched_priority priority,
    146  1.6  riastrad 			   struct drm_file *filp,
    147  1.6  riastrad 			   struct amdgpu_ctx *ctx)
    148  1.1  riastrad {
    149  1.1  riastrad 	int r;
    150  1.1  riastrad 
    151  1.6  riastrad 	r = amdgpu_ctx_priority_permit(filp, priority);
    152  1.6  riastrad 	if (r)
    153  1.6  riastrad 		return r;
    154  1.6  riastrad 
    155  1.1  riastrad 	memset(ctx, 0, sizeof(*ctx));
    156  1.6  riastrad 
    157  1.1  riastrad 	ctx->adev = adev;
    158  1.6  riastrad 
    159  1.1  riastrad 	kref_init(&ctx->refcount);
    160  1.1  riastrad 	spin_lock_init(&ctx->ring_lock);
    161  1.6  riastrad 	mutex_init(&ctx->lock);
    162  1.1  riastrad 
    163  1.6  riastrad 	ctx->reset_counter = atomic_read(&adev->gpu_reset_counter);
    164  1.6  riastrad 	ctx->reset_counter_query = ctx->reset_counter;
    165  1.6  riastrad 	ctx->vram_lost_counter = atomic_read(&adev->vram_lost_counter);
    166  1.6  riastrad 	ctx->init_priority = priority;
    167  1.6  riastrad 	ctx->override_priority = DRM_SCHED_PRIORITY_UNSET;
    168  1.1  riastrad 
    169  1.1  riastrad 	return 0;
    170  1.6  riastrad 
    171  1.1  riastrad }
    172  1.1  riastrad 
    173  1.6  riastrad static void amdgpu_ctx_fini_entity(struct amdgpu_ctx_entity *entity)
    174  1.1  riastrad {
    175  1.6  riastrad 
    176  1.6  riastrad 	int i;
    177  1.6  riastrad 
    178  1.6  riastrad 	if (!entity)
    179  1.6  riastrad 		return;
    180  1.6  riastrad 
    181  1.6  riastrad 	for (i = 0; i < amdgpu_sched_jobs; ++i)
    182  1.6  riastrad 		dma_fence_put(entity->fences[i]);
    183  1.6  riastrad 
    184  1.6  riastrad 	kfree(entity);
    185  1.6  riastrad }
    186  1.6  riastrad 
    187  1.6  riastrad static void amdgpu_ctx_fini(struct kref *ref)
    188  1.6  riastrad {
    189  1.6  riastrad 	struct amdgpu_ctx *ctx = container_of(ref, struct amdgpu_ctx, refcount);
    190  1.1  riastrad 	struct amdgpu_device *adev = ctx->adev;
    191  1.1  riastrad 	unsigned i, j;
    192  1.1  riastrad 
    193  1.1  riastrad 	if (!adev)
    194  1.1  riastrad 		return;
    195  1.1  riastrad 
    196  1.6  riastrad 	for (i = 0; i < AMDGPU_HW_IP_NUM; ++i) {
    197  1.6  riastrad 		for (j = 0; j < AMDGPU_MAX_ENTITY_NUM; ++j) {
    198  1.6  riastrad 			amdgpu_ctx_fini_entity(ctx->entities[i][j]);
    199  1.6  riastrad 			ctx->entities[i][j] = NULL;
    200  1.6  riastrad 		}
    201  1.6  riastrad 	}
    202  1.6  riastrad 
    203  1.6  riastrad 	mutex_destroy(&ctx->lock);
    204  1.7  riastrad 	spin_lock_destroy(&ctx->ring_lock);
    205  1.6  riastrad 	kfree(ctx);
    206  1.6  riastrad }
    207  1.6  riastrad 
    208  1.6  riastrad int amdgpu_ctx_get_entity(struct amdgpu_ctx *ctx, u32 hw_ip, u32 instance,
    209  1.6  riastrad 			  u32 ring, struct drm_sched_entity **entity)
    210  1.6  riastrad {
    211  1.6  riastrad 	int r;
    212  1.6  riastrad 
    213  1.6  riastrad 	if (hw_ip >= AMDGPU_HW_IP_NUM) {
    214  1.6  riastrad 		DRM_ERROR("unknown HW IP type: %d\n", hw_ip);
    215  1.6  riastrad 		return -EINVAL;
    216  1.6  riastrad 	}
    217  1.6  riastrad 
    218  1.6  riastrad 	/* Right now all IPs have only one instance - multiple rings. */
    219  1.6  riastrad 	if (instance != 0) {
    220  1.6  riastrad 		DRM_DEBUG("invalid ip instance: %d\n", instance);
    221  1.6  riastrad 		return -EINVAL;
    222  1.6  riastrad 	}
    223  1.6  riastrad 
    224  1.6  riastrad 	if (ring >= amdgpu_ctx_num_entities[hw_ip]) {
    225  1.6  riastrad 		DRM_DEBUG("invalid ring: %d %d\n", hw_ip, ring);
    226  1.6  riastrad 		return -EINVAL;
    227  1.6  riastrad 	}
    228  1.6  riastrad 
    229  1.6  riastrad 	if (ctx->entities[hw_ip][ring] == NULL) {
    230  1.6  riastrad 		r = amdgpu_ctx_init_entity(ctx, hw_ip, ring);
    231  1.6  riastrad 		if (r)
    232  1.6  riastrad 			return r;
    233  1.1  riastrad 	}
    234  1.6  riastrad 
    235  1.6  riastrad 	*entity = &ctx->entities[hw_ip][ring]->entity;
    236  1.6  riastrad 	return 0;
    237  1.1  riastrad }
    238  1.1  riastrad 
    239  1.1  riastrad static int amdgpu_ctx_alloc(struct amdgpu_device *adev,
    240  1.1  riastrad 			    struct amdgpu_fpriv *fpriv,
    241  1.6  riastrad 			    struct drm_file *filp,
    242  1.6  riastrad 			    enum drm_sched_priority priority,
    243  1.1  riastrad 			    uint32_t *id)
    244  1.1  riastrad {
    245  1.1  riastrad 	struct amdgpu_ctx_mgr *mgr = &fpriv->ctx_mgr;
    246  1.1  riastrad 	struct amdgpu_ctx *ctx;
    247  1.1  riastrad 	int r;
    248  1.1  riastrad 
    249  1.1  riastrad 	ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
    250  1.1  riastrad 	if (!ctx)
    251  1.1  riastrad 		return -ENOMEM;
    252  1.1  riastrad 
    253  1.4  riastrad 	idr_preload(GFP_KERNEL);
    254  1.1  riastrad 	mutex_lock(&mgr->lock);
    255  1.6  riastrad 	r = idr_alloc(&mgr->ctx_handles, ctx, 1, AMDGPU_VM_MAX_NUM_CTX, GFP_KERNEL);
    256  1.1  riastrad 	if (r < 0) {
    257  1.1  riastrad 		mutex_unlock(&mgr->lock);
    258  1.4  riastrad 		idr_preload_end();
    259  1.1  riastrad 		kfree(ctx);
    260  1.1  riastrad 		return r;
    261  1.1  riastrad 	}
    262  1.6  riastrad 
    263  1.1  riastrad 	*id = (uint32_t)r;
    264  1.6  riastrad 	r = amdgpu_ctx_init(adev, priority, filp, ctx);
    265  1.6  riastrad 	if (r) {
    266  1.6  riastrad 		idr_remove(&mgr->ctx_handles, *id);
    267  1.6  riastrad 		*id = 0;
    268  1.6  riastrad 		kfree(ctx);
    269  1.6  riastrad 	}
    270  1.1  riastrad 	mutex_unlock(&mgr->lock);
    271  1.4  riastrad 	idr_preload_end();
    272  1.1  riastrad 
    273  1.1  riastrad 	return r;
    274  1.1  riastrad }
    275  1.1  riastrad 
    276  1.1  riastrad static void amdgpu_ctx_do_release(struct kref *ref)
    277  1.1  riastrad {
    278  1.1  riastrad 	struct amdgpu_ctx *ctx;
    279  1.6  riastrad 	u32 i, j;
    280  1.1  riastrad 
    281  1.1  riastrad 	ctx = container_of(ref, struct amdgpu_ctx, refcount);
    282  1.6  riastrad 	for (i = 0; i < AMDGPU_HW_IP_NUM; ++i) {
    283  1.6  riastrad 		for (j = 0; j < amdgpu_ctx_num_entities[i]; ++j) {
    284  1.6  riastrad 			if (!ctx->entities[i][j])
    285  1.6  riastrad 				continue;
    286  1.1  riastrad 
    287  1.6  riastrad 			drm_sched_entity_destroy(&ctx->entities[i][j]->entity);
    288  1.6  riastrad 		}
    289  1.6  riastrad 	}
    290  1.1  riastrad 
    291  1.6  riastrad 	amdgpu_ctx_fini(ref);
    292  1.1  riastrad }
    293  1.1  riastrad 
    294  1.1  riastrad static int amdgpu_ctx_free(struct amdgpu_fpriv *fpriv, uint32_t id)
    295  1.1  riastrad {
    296  1.1  riastrad 	struct amdgpu_ctx_mgr *mgr = &fpriv->ctx_mgr;
    297  1.1  riastrad 	struct amdgpu_ctx *ctx;
    298  1.1  riastrad 
    299  1.1  riastrad 	mutex_lock(&mgr->lock);
    300  1.6  riastrad 	ctx = idr_remove(&mgr->ctx_handles, id);
    301  1.6  riastrad 	if (ctx)
    302  1.1  riastrad 		kref_put(&ctx->refcount, amdgpu_ctx_do_release);
    303  1.1  riastrad 	mutex_unlock(&mgr->lock);
    304  1.6  riastrad 	return ctx ? 0 : -EINVAL;
    305  1.1  riastrad }
    306  1.1  riastrad 
    307  1.1  riastrad static int amdgpu_ctx_query(struct amdgpu_device *adev,
    308  1.1  riastrad 			    struct amdgpu_fpriv *fpriv, uint32_t id,
    309  1.1  riastrad 			    union drm_amdgpu_ctx_out *out)
    310  1.1  riastrad {
    311  1.1  riastrad 	struct amdgpu_ctx *ctx;
    312  1.1  riastrad 	struct amdgpu_ctx_mgr *mgr;
    313  1.1  riastrad 	unsigned reset_counter;
    314  1.1  riastrad 
    315  1.1  riastrad 	if (!fpriv)
    316  1.1  riastrad 		return -EINVAL;
    317  1.1  riastrad 
    318  1.1  riastrad 	mgr = &fpriv->ctx_mgr;
    319  1.1  riastrad 	mutex_lock(&mgr->lock);
    320  1.1  riastrad 	ctx = idr_find(&mgr->ctx_handles, id);
    321  1.1  riastrad 	if (!ctx) {
    322  1.1  riastrad 		mutex_unlock(&mgr->lock);
    323  1.1  riastrad 		return -EINVAL;
    324  1.1  riastrad 	}
    325  1.1  riastrad 
    326  1.1  riastrad 	/* TODO: these two are always zero */
    327  1.1  riastrad 	out->state.flags = 0x0;
    328  1.1  riastrad 	out->state.hangs = 0x0;
    329  1.1  riastrad 
    330  1.1  riastrad 	/* determine if a GPU reset has occured since the last call */
    331  1.1  riastrad 	reset_counter = atomic_read(&adev->gpu_reset_counter);
    332  1.1  riastrad 	/* TODO: this should ideally return NO, GUILTY, or INNOCENT. */
    333  1.6  riastrad 	if (ctx->reset_counter_query == reset_counter)
    334  1.1  riastrad 		out->state.reset_status = AMDGPU_CTX_NO_RESET;
    335  1.1  riastrad 	else
    336  1.1  riastrad 		out->state.reset_status = AMDGPU_CTX_UNKNOWN_RESET;
    337  1.6  riastrad 	ctx->reset_counter_query = reset_counter;
    338  1.6  riastrad 
    339  1.6  riastrad 	mutex_unlock(&mgr->lock);
    340  1.6  riastrad 	return 0;
    341  1.6  riastrad }
    342  1.6  riastrad 
    343  1.6  riastrad static int amdgpu_ctx_query2(struct amdgpu_device *adev,
    344  1.6  riastrad 	struct amdgpu_fpriv *fpriv, uint32_t id,
    345  1.6  riastrad 	union drm_amdgpu_ctx_out *out)
    346  1.6  riastrad {
    347  1.6  riastrad 	struct amdgpu_ctx *ctx;
    348  1.6  riastrad 	struct amdgpu_ctx_mgr *mgr;
    349  1.6  riastrad 	unsigned long ras_counter;
    350  1.6  riastrad 
    351  1.6  riastrad 	if (!fpriv)
    352  1.6  riastrad 		return -EINVAL;
    353  1.6  riastrad 
    354  1.6  riastrad 	mgr = &fpriv->ctx_mgr;
    355  1.6  riastrad 	mutex_lock(&mgr->lock);
    356  1.6  riastrad 	ctx = idr_find(&mgr->ctx_handles, id);
    357  1.6  riastrad 	if (!ctx) {
    358  1.6  riastrad 		mutex_unlock(&mgr->lock);
    359  1.6  riastrad 		return -EINVAL;
    360  1.6  riastrad 	}
    361  1.6  riastrad 
    362  1.6  riastrad 	out->state.flags = 0x0;
    363  1.6  riastrad 	out->state.hangs = 0x0;
    364  1.6  riastrad 
    365  1.6  riastrad 	if (ctx->reset_counter != atomic_read(&adev->gpu_reset_counter))
    366  1.6  riastrad 		out->state.flags |= AMDGPU_CTX_QUERY2_FLAGS_RESET;
    367  1.6  riastrad 
    368  1.6  riastrad 	if (ctx->vram_lost_counter != atomic_read(&adev->vram_lost_counter))
    369  1.6  riastrad 		out->state.flags |= AMDGPU_CTX_QUERY2_FLAGS_VRAMLOST;
    370  1.6  riastrad 
    371  1.6  riastrad 	if (atomic_read(&ctx->guilty))
    372  1.6  riastrad 		out->state.flags |= AMDGPU_CTX_QUERY2_FLAGS_GUILTY;
    373  1.6  riastrad 
    374  1.6  riastrad 	/*query ue count*/
    375  1.6  riastrad 	ras_counter = amdgpu_ras_query_error_count(adev, false);
    376  1.6  riastrad 	/*ras counter is monotonic increasing*/
    377  1.6  riastrad 	if (ras_counter != ctx->ras_counter_ue) {
    378  1.6  riastrad 		out->state.flags |= AMDGPU_CTX_QUERY2_FLAGS_RAS_UE;
    379  1.6  riastrad 		ctx->ras_counter_ue = ras_counter;
    380  1.6  riastrad 	}
    381  1.6  riastrad 
    382  1.6  riastrad 	/*query ce count*/
    383  1.6  riastrad 	ras_counter = amdgpu_ras_query_error_count(adev, true);
    384  1.6  riastrad 	if (ras_counter != ctx->ras_counter_ce) {
    385  1.6  riastrad 		out->state.flags |= AMDGPU_CTX_QUERY2_FLAGS_RAS_CE;
    386  1.6  riastrad 		ctx->ras_counter_ce = ras_counter;
    387  1.6  riastrad 	}
    388  1.1  riastrad 
    389  1.1  riastrad 	mutex_unlock(&mgr->lock);
    390  1.1  riastrad 	return 0;
    391  1.1  riastrad }
    392  1.1  riastrad 
    393  1.1  riastrad int amdgpu_ctx_ioctl(struct drm_device *dev, void *data,
    394  1.1  riastrad 		     struct drm_file *filp)
    395  1.1  riastrad {
    396  1.1  riastrad 	int r;
    397  1.1  riastrad 	uint32_t id;
    398  1.6  riastrad 	enum drm_sched_priority priority;
    399  1.1  riastrad 
    400  1.1  riastrad 	union drm_amdgpu_ctx *args = data;
    401  1.1  riastrad 	struct amdgpu_device *adev = dev->dev_private;
    402  1.1  riastrad 	struct amdgpu_fpriv *fpriv = filp->driver_priv;
    403  1.1  riastrad 
    404  1.1  riastrad 	r = 0;
    405  1.1  riastrad 	id = args->in.ctx_id;
    406  1.6  riastrad 	priority = amdgpu_to_sched_priority(args->in.priority);
    407  1.6  riastrad 
    408  1.6  riastrad 	/* For backwards compatibility reasons, we need to accept
    409  1.6  riastrad 	 * ioctls with garbage in the priority field */
    410  1.6  riastrad 	if (priority == DRM_SCHED_PRIORITY_INVALID)
    411  1.6  riastrad 		priority = DRM_SCHED_PRIORITY_NORMAL;
    412  1.1  riastrad 
    413  1.1  riastrad 	switch (args->in.op) {
    414  1.6  riastrad 	case AMDGPU_CTX_OP_ALLOC_CTX:
    415  1.6  riastrad 		r = amdgpu_ctx_alloc(adev, fpriv, filp, priority, &id);
    416  1.6  riastrad 		args->out.alloc.ctx_id = id;
    417  1.6  riastrad 		break;
    418  1.6  riastrad 	case AMDGPU_CTX_OP_FREE_CTX:
    419  1.6  riastrad 		r = amdgpu_ctx_free(fpriv, id);
    420  1.6  riastrad 		break;
    421  1.6  riastrad 	case AMDGPU_CTX_OP_QUERY_STATE:
    422  1.6  riastrad 		r = amdgpu_ctx_query(adev, fpriv, id, &args->out);
    423  1.6  riastrad 		break;
    424  1.6  riastrad 	case AMDGPU_CTX_OP_QUERY_STATE2:
    425  1.6  riastrad 		r = amdgpu_ctx_query2(adev, fpriv, id, &args->out);
    426  1.6  riastrad 		break;
    427  1.6  riastrad 	default:
    428  1.6  riastrad 		return -EINVAL;
    429  1.1  riastrad 	}
    430  1.1  riastrad 
    431  1.1  riastrad 	return r;
    432  1.1  riastrad }
    433  1.1  riastrad 
    434  1.1  riastrad struct amdgpu_ctx *amdgpu_ctx_get(struct amdgpu_fpriv *fpriv, uint32_t id)
    435  1.1  riastrad {
    436  1.1  riastrad 	struct amdgpu_ctx *ctx;
    437  1.1  riastrad 	struct amdgpu_ctx_mgr *mgr;
    438  1.1  riastrad 
    439  1.1  riastrad 	if (!fpriv)
    440  1.1  riastrad 		return NULL;
    441  1.1  riastrad 
    442  1.1  riastrad 	mgr = &fpriv->ctx_mgr;
    443  1.1  riastrad 
    444  1.1  riastrad 	mutex_lock(&mgr->lock);
    445  1.1  riastrad 	ctx = idr_find(&mgr->ctx_handles, id);
    446  1.1  riastrad 	if (ctx)
    447  1.1  riastrad 		kref_get(&ctx->refcount);
    448  1.1  riastrad 	mutex_unlock(&mgr->lock);
    449  1.1  riastrad 	return ctx;
    450  1.1  riastrad }
    451  1.1  riastrad 
    452  1.1  riastrad int amdgpu_ctx_put(struct amdgpu_ctx *ctx)
    453  1.1  riastrad {
    454  1.1  riastrad 	if (ctx == NULL)
    455  1.1  riastrad 		return -EINVAL;
    456  1.1  riastrad 
    457  1.1  riastrad 	kref_put(&ctx->refcount, amdgpu_ctx_do_release);
    458  1.1  riastrad 	return 0;
    459  1.1  riastrad }
    460  1.1  riastrad 
    461  1.6  riastrad void amdgpu_ctx_add_fence(struct amdgpu_ctx *ctx,
    462  1.6  riastrad 			  struct drm_sched_entity *entity,
    463  1.6  riastrad 			  struct dma_fence *fence, uint64_t* handle)
    464  1.6  riastrad {
    465  1.6  riastrad 	struct amdgpu_ctx_entity *centity = to_amdgpu_ctx_entity(entity);
    466  1.8  riastrad 	uint64_t seq;
    467  1.6  riastrad 	struct dma_fence *other = NULL;
    468  1.1  riastrad 	unsigned idx = 0;
    469  1.1  riastrad 
    470  1.8  riastrad 	spin_lock(&ctx->ring_lock);
    471  1.8  riastrad 	seq = centity->sequence;
    472  1.6  riastrad 	idx = seq & (amdgpu_sched_jobs - 1);
    473  1.6  riastrad 	other = centity->fences[idx];
    474  1.6  riastrad 	if (other)
    475  1.6  riastrad 		BUG_ON(!dma_fence_is_signaled(other));
    476  1.1  riastrad 
    477  1.6  riastrad 	dma_fence_get(fence);
    478  1.6  riastrad 	centity->fences[idx] = fence;
    479  1.6  riastrad 	centity->sequence++;
    480  1.1  riastrad 	spin_unlock(&ctx->ring_lock);
    481  1.1  riastrad 
    482  1.6  riastrad 	dma_fence_put(other);
    483  1.6  riastrad 	if (handle)
    484  1.6  riastrad 		*handle = seq;
    485  1.1  riastrad }
    486  1.1  riastrad 
    487  1.6  riastrad struct dma_fence *amdgpu_ctx_get_fence(struct amdgpu_ctx *ctx,
    488  1.6  riastrad 				       struct drm_sched_entity *entity,
    489  1.6  riastrad 				       uint64_t seq)
    490  1.1  riastrad {
    491  1.6  riastrad 	struct amdgpu_ctx_entity *centity = to_amdgpu_ctx_entity(entity);
    492  1.6  riastrad 	struct dma_fence *fence;
    493  1.1  riastrad 
    494  1.1  riastrad 	spin_lock(&ctx->ring_lock);
    495  1.1  riastrad 
    496  1.6  riastrad 	if (seq == ~0ull)
    497  1.6  riastrad 		seq = centity->sequence - 1;
    498  1.6  riastrad 
    499  1.6  riastrad 	if (seq >= centity->sequence) {
    500  1.1  riastrad 		spin_unlock(&ctx->ring_lock);
    501  1.1  riastrad 		return ERR_PTR(-EINVAL);
    502  1.1  riastrad 	}
    503  1.1  riastrad 
    504  1.1  riastrad 
    505  1.6  riastrad 	if (seq + amdgpu_sched_jobs < centity->sequence) {
    506  1.1  riastrad 		spin_unlock(&ctx->ring_lock);
    507  1.1  riastrad 		return NULL;
    508  1.1  riastrad 	}
    509  1.1  riastrad 
    510  1.6  riastrad 	fence = dma_fence_get(centity->fences[seq & (amdgpu_sched_jobs - 1)]);
    511  1.1  riastrad 	spin_unlock(&ctx->ring_lock);
    512  1.1  riastrad 
    513  1.1  riastrad 	return fence;
    514  1.1  riastrad }
    515  1.1  riastrad 
    516  1.6  riastrad void amdgpu_ctx_priority_override(struct amdgpu_ctx *ctx,
    517  1.6  riastrad 				  enum drm_sched_priority priority)
    518  1.6  riastrad {
    519  1.6  riastrad 	enum drm_sched_priority ctx_prio;
    520  1.6  riastrad 	unsigned i, j;
    521  1.6  riastrad 
    522  1.6  riastrad 	ctx->override_priority = priority;
    523  1.6  riastrad 
    524  1.6  riastrad 	ctx_prio = (ctx->override_priority == DRM_SCHED_PRIORITY_UNSET) ?
    525  1.6  riastrad 			ctx->init_priority : ctx->override_priority;
    526  1.6  riastrad 	for (i = 0; i < AMDGPU_HW_IP_NUM; ++i) {
    527  1.6  riastrad 		for (j = 0; j < amdgpu_ctx_num_entities[i]; ++j) {
    528  1.6  riastrad 			struct drm_sched_entity *entity;
    529  1.6  riastrad 
    530  1.6  riastrad 			if (!ctx->entities[i][j])
    531  1.6  riastrad 				continue;
    532  1.6  riastrad 
    533  1.6  riastrad 			entity = &ctx->entities[i][j]->entity;
    534  1.6  riastrad 			drm_sched_entity_set_priority(entity, ctx_prio);
    535  1.6  riastrad 		}
    536  1.6  riastrad 	}
    537  1.6  riastrad }
    538  1.6  riastrad 
    539  1.6  riastrad int amdgpu_ctx_wait_prev_fence(struct amdgpu_ctx *ctx,
    540  1.6  riastrad 			       struct drm_sched_entity *entity)
    541  1.6  riastrad {
    542  1.6  riastrad 	struct amdgpu_ctx_entity *centity = to_amdgpu_ctx_entity(entity);
    543  1.6  riastrad 	struct dma_fence *other;
    544  1.6  riastrad 	unsigned idx;
    545  1.6  riastrad 	long r;
    546  1.6  riastrad 
    547  1.6  riastrad 	spin_lock(&ctx->ring_lock);
    548  1.6  riastrad 	idx = centity->sequence & (amdgpu_sched_jobs - 1);
    549  1.6  riastrad 	other = dma_fence_get(centity->fences[idx]);
    550  1.6  riastrad 	spin_unlock(&ctx->ring_lock);
    551  1.6  riastrad 
    552  1.6  riastrad 	if (!other)
    553  1.6  riastrad 		return 0;
    554  1.6  riastrad 
    555  1.6  riastrad 	r = dma_fence_wait(other, true);
    556  1.6  riastrad 	if (r < 0 && r != -ERESTARTSYS)
    557  1.6  riastrad 		DRM_ERROR("Error (%ld) waiting for fence!\n", r);
    558  1.6  riastrad 
    559  1.6  riastrad 	dma_fence_put(other);
    560  1.6  riastrad 	return r;
    561  1.6  riastrad }
    562  1.6  riastrad 
    563  1.1  riastrad void amdgpu_ctx_mgr_init(struct amdgpu_ctx_mgr *mgr)
    564  1.1  riastrad {
    565  1.1  riastrad 	mutex_init(&mgr->lock);
    566  1.1  riastrad 	idr_init(&mgr->ctx_handles);
    567  1.1  riastrad }
    568  1.1  riastrad 
    569  1.6  riastrad long amdgpu_ctx_mgr_entity_flush(struct amdgpu_ctx_mgr *mgr, long timeout)
    570  1.6  riastrad {
    571  1.6  riastrad 	struct amdgpu_ctx *ctx;
    572  1.6  riastrad 	struct idr *idp;
    573  1.6  riastrad 	uint32_t id, i, j;
    574  1.6  riastrad 
    575  1.6  riastrad 	idp = &mgr->ctx_handles;
    576  1.6  riastrad 
    577  1.6  riastrad 	mutex_lock(&mgr->lock);
    578  1.6  riastrad 	idr_for_each_entry(idp, ctx, id) {
    579  1.6  riastrad 		for (i = 0; i < AMDGPU_HW_IP_NUM; ++i) {
    580  1.6  riastrad 			for (j = 0; j < amdgpu_ctx_num_entities[i]; ++j) {
    581  1.6  riastrad 				struct drm_sched_entity *entity;
    582  1.6  riastrad 
    583  1.6  riastrad 				if (!ctx->entities[i][j])
    584  1.6  riastrad 					continue;
    585  1.6  riastrad 
    586  1.6  riastrad 				entity = &ctx->entities[i][j]->entity;
    587  1.6  riastrad 				timeout = drm_sched_entity_flush(entity, timeout);
    588  1.6  riastrad 			}
    589  1.6  riastrad 		}
    590  1.6  riastrad 	}
    591  1.6  riastrad 	mutex_unlock(&mgr->lock);
    592  1.6  riastrad 	return timeout;
    593  1.6  riastrad }
    594  1.6  riastrad 
    595  1.6  riastrad void amdgpu_ctx_mgr_entity_fini(struct amdgpu_ctx_mgr *mgr)
    596  1.6  riastrad {
    597  1.6  riastrad 	struct amdgpu_ctx *ctx;
    598  1.6  riastrad 	struct idr *idp;
    599  1.6  riastrad 	uint32_t id, i, j;
    600  1.6  riastrad 
    601  1.6  riastrad 	idp = &mgr->ctx_handles;
    602  1.6  riastrad 
    603  1.6  riastrad 	idr_for_each_entry(idp, ctx, id) {
    604  1.6  riastrad 		if (kref_read(&ctx->refcount) != 1) {
    605  1.6  riastrad 			DRM_ERROR("ctx %p is still alive\n", ctx);
    606  1.6  riastrad 			continue;
    607  1.6  riastrad 		}
    608  1.6  riastrad 
    609  1.6  riastrad 		for (i = 0; i < AMDGPU_HW_IP_NUM; ++i) {
    610  1.6  riastrad 			for (j = 0; j < amdgpu_ctx_num_entities[i]; ++j) {
    611  1.6  riastrad 				struct drm_sched_entity *entity;
    612  1.6  riastrad 
    613  1.6  riastrad 				if (!ctx->entities[i][j])
    614  1.6  riastrad 					continue;
    615  1.6  riastrad 
    616  1.6  riastrad 				entity = &ctx->entities[i][j]->entity;
    617  1.6  riastrad 				drm_sched_entity_fini(entity);
    618  1.6  riastrad 			}
    619  1.6  riastrad 		}
    620  1.6  riastrad 	}
    621  1.6  riastrad }
    622  1.6  riastrad 
    623  1.1  riastrad void amdgpu_ctx_mgr_fini(struct amdgpu_ctx_mgr *mgr)
    624  1.1  riastrad {
    625  1.1  riastrad 	struct amdgpu_ctx *ctx;
    626  1.1  riastrad 	struct idr *idp;
    627  1.1  riastrad 	uint32_t id;
    628  1.1  riastrad 
    629  1.6  riastrad 	amdgpu_ctx_mgr_entity_fini(mgr);
    630  1.6  riastrad 
    631  1.1  riastrad 	idp = &mgr->ctx_handles;
    632  1.1  riastrad 
    633  1.1  riastrad 	idr_for_each_entry(idp, ctx, id) {
    634  1.6  riastrad 		if (kref_put(&ctx->refcount, amdgpu_ctx_fini) != 1)
    635  1.1  riastrad 			DRM_ERROR("ctx %p is still alive\n", ctx);
    636  1.1  riastrad 	}
    637  1.1  riastrad 
    638  1.1  riastrad 	idr_destroy(&mgr->ctx_handles);
    639  1.1  riastrad 	mutex_destroy(&mgr->lock);
    640  1.1  riastrad }
    641  1.6  riastrad 
    642  1.6  riastrad void amdgpu_ctx_init_sched(struct amdgpu_device *adev)
    643  1.6  riastrad {
    644  1.6  riastrad 	int i, j;
    645  1.6  riastrad 
    646  1.6  riastrad 	for (i = 0; i < adev->gfx.num_gfx_rings; i++) {
    647  1.6  riastrad 		adev->gfx.gfx_sched[i] = &adev->gfx.gfx_ring[i].sched;
    648  1.6  riastrad 		adev->gfx.num_gfx_sched++;
    649  1.6  riastrad 	}
    650  1.6  riastrad 
    651  1.6  riastrad 	for (i = 0; i < adev->gfx.num_compute_rings; i++) {
    652  1.6  riastrad 		adev->gfx.compute_sched[i] = &adev->gfx.compute_ring[i].sched;
    653  1.6  riastrad 		adev->gfx.num_compute_sched++;
    654  1.6  riastrad 	}
    655  1.6  riastrad 
    656  1.6  riastrad 	for (i = 0; i < adev->sdma.num_instances; i++) {
    657  1.6  riastrad 		adev->sdma.sdma_sched[i] = &adev->sdma.instance[i].ring.sched;
    658  1.6  riastrad 		adev->sdma.num_sdma_sched++;
    659  1.6  riastrad 	}
    660  1.6  riastrad 
    661  1.6  riastrad 	for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
    662  1.6  riastrad 		if (adev->vcn.harvest_config & (1 << i))
    663  1.6  riastrad 			continue;
    664  1.6  riastrad 		adev->vcn.vcn_dec_sched[adev->vcn.num_vcn_dec_sched++] =
    665  1.6  riastrad 			&adev->vcn.inst[i].ring_dec.sched;
    666  1.6  riastrad 	}
    667  1.6  riastrad 
    668  1.6  riastrad 	for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
    669  1.6  riastrad 		if (adev->vcn.harvest_config & (1 << i))
    670  1.6  riastrad 			continue;
    671  1.6  riastrad 		for (j = 0; j < adev->vcn.num_enc_rings; ++j)
    672  1.6  riastrad 			adev->vcn.vcn_enc_sched[adev->vcn.num_vcn_enc_sched++] =
    673  1.6  riastrad 				&adev->vcn.inst[i].ring_enc[j].sched;
    674  1.6  riastrad 	}
    675  1.6  riastrad 
    676  1.6  riastrad 	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
    677  1.6  riastrad 		if (adev->jpeg.harvest_config & (1 << i))
    678  1.6  riastrad 			continue;
    679  1.6  riastrad 		adev->jpeg.jpeg_sched[adev->jpeg.num_jpeg_sched++] =
    680  1.6  riastrad 			&adev->jpeg.inst[i].ring_dec.sched;
    681  1.6  riastrad 	}
    682  1.6  riastrad }
    683