forked from Minki/linux
drm/amdgpu: add kernel ctx support (v2)
v2: rebase against kfd changes Signed-off-by: Chunming Zhou <david1.zhou@amd.com> Acked-by: Christian K?nig <christian.koenig@amd.com> Reviewed-by: Jammy Zhou <Jammy.Zhou@amd.com>
This commit is contained in:
parent
4274f5d45c
commit
23ca0e4e47
@ -2065,6 +2065,9 @@ struct amdgpu_device {
|
|||||||
|
|
||||||
/* amdkfd interface */
|
/* amdkfd interface */
|
||||||
struct kfd_dev *kfd;
|
struct kfd_dev *kfd;
|
||||||
|
|
||||||
|
/* kernel conext for IB submission */
|
||||||
|
struct amdgpu_ctx *kernel_ctx;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool amdgpu_device_is_px(struct drm_device *dev);
|
bool amdgpu_device_is_px(struct drm_device *dev);
|
||||||
|
@ -48,33 +48,53 @@ static void amdgpu_ctx_do_release(struct kref *ref)
|
|||||||
kfree(ctx);
|
kfree(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
int amdgpu_ctx_alloc(struct amdgpu_device *adev, struct amdgpu_fpriv *fpriv,
|
static void amdgpu_ctx_init(struct amdgpu_device *adev,
|
||||||
uint32_t *id)
|
struct amdgpu_fpriv *fpriv,
|
||||||
|
struct amdgpu_ctx *ctx,
|
||||||
|
uint32_t id)
|
||||||
{
|
{
|
||||||
struct amdgpu_ctx *ctx;
|
int i;
|
||||||
struct amdgpu_ctx_mgr *mgr = &fpriv->ctx_mgr;
|
|
||||||
int i, j, r;
|
|
||||||
|
|
||||||
ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
|
|
||||||
if (!ctx)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
mutex_lock(&mgr->lock);
|
|
||||||
r = idr_alloc(&mgr->ctx_handles, ctx, 0, 0, GFP_KERNEL);
|
|
||||||
if (r < 0) {
|
|
||||||
mutex_unlock(&mgr->lock);
|
|
||||||
kfree(ctx);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
*id = (uint32_t)r;
|
|
||||||
|
|
||||||
memset(ctx, 0, sizeof(*ctx));
|
memset(ctx, 0, sizeof(*ctx));
|
||||||
ctx->adev = adev;
|
ctx->adev = adev;
|
||||||
kref_init(&ctx->refcount);
|
kref_init(&ctx->refcount);
|
||||||
spin_lock_init(&ctx->ring_lock);
|
spin_lock_init(&ctx->ring_lock);
|
||||||
for (i = 0; i < AMDGPU_MAX_RINGS; ++i)
|
for (i = 0; i < AMDGPU_MAX_RINGS; ++i)
|
||||||
ctx->rings[i].sequence = 1;
|
ctx->rings[i].sequence = 1;
|
||||||
mutex_unlock(&mgr->lock);
|
}
|
||||||
|
|
||||||
|
int amdgpu_ctx_alloc(struct amdgpu_device *adev, struct amdgpu_fpriv *fpriv,
|
||||||
|
uint32_t *id)
|
||||||
|
{
|
||||||
|
struct amdgpu_ctx *ctx;
|
||||||
|
int i, j, r;
|
||||||
|
|
||||||
|
ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
|
||||||
|
if (!ctx)
|
||||||
|
return -ENOMEM;
|
||||||
|
if (fpriv) {
|
||||||
|
struct amdgpu_ctx_mgr *mgr = &fpriv->ctx_mgr;
|
||||||
|
mutex_lock(&mgr->lock);
|
||||||
|
r = idr_alloc(&mgr->ctx_handles, ctx, 1, 0, GFP_KERNEL);
|
||||||
|
if (r < 0) {
|
||||||
|
mutex_unlock(&mgr->lock);
|
||||||
|
kfree(ctx);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
*id = (uint32_t)r;
|
||||||
|
amdgpu_ctx_init(adev, fpriv, ctx, *id);
|
||||||
|
mutex_unlock(&mgr->lock);
|
||||||
|
} else {
|
||||||
|
if (adev->kernel_ctx) {
|
||||||
|
DRM_ERROR("kernel cnotext has been created.\n");
|
||||||
|
kfree(ctx);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
*id = AMD_KERNEL_CONTEXT_ID;
|
||||||
|
amdgpu_ctx_init(adev, fpriv, ctx, *id);
|
||||||
|
|
||||||
|
adev->kernel_ctx = ctx;
|
||||||
|
}
|
||||||
|
|
||||||
if (amdgpu_enable_scheduler) {
|
if (amdgpu_enable_scheduler) {
|
||||||
/* create context entity for each ring */
|
/* create context entity for each ring */
|
||||||
for (i = 0; i < adev->num_rings; i++) {
|
for (i = 0; i < adev->num_rings; i++) {
|
||||||
@ -105,17 +125,23 @@ int amdgpu_ctx_alloc(struct amdgpu_device *adev, struct amdgpu_fpriv *fpriv,
|
|||||||
int amdgpu_ctx_free(struct amdgpu_device *adev, struct amdgpu_fpriv *fpriv, uint32_t id)
|
int amdgpu_ctx_free(struct amdgpu_device *adev, struct amdgpu_fpriv *fpriv, uint32_t id)
|
||||||
{
|
{
|
||||||
struct amdgpu_ctx *ctx;
|
struct amdgpu_ctx *ctx;
|
||||||
struct amdgpu_ctx_mgr *mgr = &fpriv->ctx_mgr;
|
|
||||||
|
|
||||||
mutex_lock(&mgr->lock);
|
if (fpriv) {
|
||||||
ctx = idr_find(&mgr->ctx_handles, id);
|
struct amdgpu_ctx_mgr *mgr = &fpriv->ctx_mgr;
|
||||||
if (ctx) {
|
mutex_lock(&mgr->lock);
|
||||||
idr_remove(&mgr->ctx_handles, id);
|
ctx = idr_find(&mgr->ctx_handles, id);
|
||||||
kref_put(&ctx->refcount, amdgpu_ctx_do_release);
|
if (ctx) {
|
||||||
|
idr_remove(&mgr->ctx_handles, id);
|
||||||
|
kref_put(&ctx->refcount, amdgpu_ctx_do_release);
|
||||||
|
mutex_unlock(&mgr->lock);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
mutex_unlock(&mgr->lock);
|
mutex_unlock(&mgr->lock);
|
||||||
|
} else {
|
||||||
|
ctx = adev->kernel_ctx;
|
||||||
|
kref_put(&ctx->refcount, amdgpu_ctx_do_release);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
mutex_unlock(&mgr->lock);
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,9 +150,13 @@ static int amdgpu_ctx_query(struct amdgpu_device *adev,
|
|||||||
union drm_amdgpu_ctx_out *out)
|
union drm_amdgpu_ctx_out *out)
|
||||||
{
|
{
|
||||||
struct amdgpu_ctx *ctx;
|
struct amdgpu_ctx *ctx;
|
||||||
struct amdgpu_ctx_mgr *mgr = &fpriv->ctx_mgr;
|
struct amdgpu_ctx_mgr *mgr;
|
||||||
unsigned reset_counter;
|
unsigned reset_counter;
|
||||||
|
|
||||||
|
if (!fpriv)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
mgr = &fpriv->ctx_mgr;
|
||||||
mutex_lock(&mgr->lock);
|
mutex_lock(&mgr->lock);
|
||||||
ctx = idr_find(&mgr->ctx_handles, id);
|
ctx = idr_find(&mgr->ctx_handles, id);
|
||||||
if (!ctx) {
|
if (!ctx) {
|
||||||
@ -202,7 +232,12 @@ int amdgpu_ctx_ioctl(struct drm_device *dev, void *data,
|
|||||||
struct amdgpu_ctx *amdgpu_ctx_get(struct amdgpu_fpriv *fpriv, uint32_t id)
|
struct amdgpu_ctx *amdgpu_ctx_get(struct amdgpu_fpriv *fpriv, uint32_t id)
|
||||||
{
|
{
|
||||||
struct amdgpu_ctx *ctx;
|
struct amdgpu_ctx *ctx;
|
||||||
struct amdgpu_ctx_mgr *mgr = &fpriv->ctx_mgr;
|
struct amdgpu_ctx_mgr *mgr;
|
||||||
|
|
||||||
|
if (!fpriv)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
mgr = &fpriv->ctx_mgr;
|
||||||
|
|
||||||
mutex_lock(&mgr->lock);
|
mutex_lock(&mgr->lock);
|
||||||
ctx = idr_find(&mgr->ctx_handles, id);
|
ctx = idr_find(&mgr->ctx_handles, id);
|
||||||
|
@ -1525,6 +1525,14 @@ int amdgpu_device_init(struct amdgpu_device *adev,
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!adev->kernel_ctx) {
|
||||||
|
uint32_t id = 0;
|
||||||
|
r = amdgpu_ctx_alloc(adev, NULL, &id);
|
||||||
|
if (r) {
|
||||||
|
dev_err(adev->dev, "failed to create kernel context (%d).\n", r);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
}
|
||||||
r = amdgpu_ib_ring_tests(adev);
|
r = amdgpu_ib_ring_tests(adev);
|
||||||
if (r)
|
if (r)
|
||||||
DRM_ERROR("ib ring test failed (%d).\n", r);
|
DRM_ERROR("ib ring test failed (%d).\n", r);
|
||||||
@ -1586,6 +1594,7 @@ void amdgpu_device_fini(struct amdgpu_device *adev)
|
|||||||
adev->shutdown = true;
|
adev->shutdown = true;
|
||||||
/* evict vram memory */
|
/* evict vram memory */
|
||||||
amdgpu_bo_evict_vram(adev);
|
amdgpu_bo_evict_vram(adev);
|
||||||
|
amdgpu_ctx_free(adev, NULL, 0);
|
||||||
amdgpu_ib_pool_fini(adev);
|
amdgpu_ib_pool_fini(adev);
|
||||||
amdgpu_fence_driver_fini(adev);
|
amdgpu_fence_driver_fini(adev);
|
||||||
amdgpu_fbdev_fini(adev);
|
amdgpu_fbdev_fini(adev);
|
||||||
|
Loading…
Reference in New Issue
Block a user