amdgpu_ctx.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. /*
  2. * Copyright 2015 Advanced Micro Devices, Inc.
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a
  5. * copy of this software and associated documentation files (the "Software"),
  6. * to deal in the Software without restriction, including without limitation
  7. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8. * and/or sell copies of the Software, and to permit persons to whom the
  9. * Software is furnished to do so, subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice shall be included in
  12. * all copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  17. * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
  18. * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  19. * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  20. * OTHER DEALINGS IN THE SOFTWARE.
  21. *
  22. * Authors: monk liu <monk.liu@amd.com>
  23. */
  24. #include <drm/drmP.h>
  25. #include "amdgpu.h"
  26. static void amdgpu_ctx_do_release(struct kref *ref)
  27. {
  28. struct amdgpu_ctx *ctx;
  29. struct amdgpu_ctx_mgr *mgr;
  30. ctx = container_of(ref, struct amdgpu_ctx, refcount);
  31. mgr = &ctx->fpriv->ctx_mgr;
  32. idr_remove(&mgr->ctx_handles, ctx->id);
  33. kfree(ctx);
  34. }
  35. int amdgpu_ctx_alloc(struct amdgpu_device *adev, struct amdgpu_fpriv *fpriv, uint32_t *id, uint32_t flags)
  36. {
  37. int r;
  38. struct amdgpu_ctx *ctx;
  39. struct amdgpu_ctx_mgr *mgr = &fpriv->ctx_mgr;
  40. ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
  41. if (!ctx)
  42. return -ENOMEM;
  43. mutex_lock(&mgr->lock);
  44. r = idr_alloc(&mgr->ctx_handles, ctx, 0, 0, GFP_KERNEL);
  45. if (r < 0) {
  46. mutex_unlock(&mgr->lock);
  47. kfree(ctx);
  48. return r;
  49. }
  50. *id = (uint32_t)r;
  51. memset(ctx, 0, sizeof(*ctx));
  52. ctx->id = *id;
  53. ctx->fpriv = fpriv;
  54. kref_init(&ctx->refcount);
  55. mutex_unlock(&mgr->lock);
  56. return 0;
  57. }
  58. int amdgpu_ctx_free(struct amdgpu_device *adev, struct amdgpu_fpriv *fpriv, uint32_t id)
  59. {
  60. struct amdgpu_ctx *ctx;
  61. struct amdgpu_ctx_mgr *mgr = &fpriv->ctx_mgr;
  62. mutex_lock(&mgr->lock);
  63. ctx = idr_find(&mgr->ctx_handles, id);
  64. if (ctx) {
  65. kref_put(&ctx->refcount, amdgpu_ctx_do_release);
  66. mutex_unlock(&mgr->lock);
  67. return 0;
  68. }
  69. mutex_unlock(&mgr->lock);
  70. return -EINVAL;
  71. }
  72. int amdgpu_ctx_query(struct amdgpu_device *adev, struct amdgpu_fpriv *fpriv, uint32_t id, struct amdgpu_ctx_state *state)
  73. {
  74. struct amdgpu_ctx *ctx;
  75. struct amdgpu_ctx_mgr *mgr = &fpriv->ctx_mgr;
  76. mutex_lock(&mgr->lock);
  77. ctx = idr_find(&mgr->ctx_handles, id);
  78. if (ctx) {
  79. /* state should alter with CS activity */
  80. *state = ctx->state;
  81. mutex_unlock(&mgr->lock);
  82. return 0;
  83. }
  84. mutex_unlock(&mgr->lock);
  85. return -EINVAL;
  86. }
  87. void amdgpu_ctx_fini(struct amdgpu_fpriv *fpriv)
  88. {
  89. struct idr *idp;
  90. struct amdgpu_ctx *ctx;
  91. uint32_t id;
  92. struct amdgpu_ctx_mgr *mgr = &fpriv->ctx_mgr;
  93. idp = &mgr->ctx_handles;
  94. idr_for_each_entry(idp,ctx,id) {
  95. if (kref_put(&ctx->refcount, amdgpu_ctx_do_release) != 1)
  96. DRM_ERROR("ctx (id=%ul) is still alive\n",ctx->id);
  97. }
  98. mutex_destroy(&mgr->lock);
  99. }
  100. int amdgpu_ctx_ioctl(struct drm_device *dev, void *data,
  101. struct drm_file *filp)
  102. {
  103. int r;
  104. uint32_t id;
  105. uint32_t flags;
  106. struct amdgpu_ctx_state state;
  107. union drm_amdgpu_ctx *args = data;
  108. struct amdgpu_device *adev = dev->dev_private;
  109. struct amdgpu_fpriv *fpriv = filp->driver_priv;
  110. r = 0;
  111. id = args->in.ctx_id;
  112. flags = args->in.flags;
  113. switch (args->in.op) {
  114. case AMDGPU_CTX_OP_ALLOC_CTX:
  115. r = amdgpu_ctx_alloc(adev, fpriv, &id, flags);
  116. args->out.alloc.ctx_id = id;
  117. break;
  118. case AMDGPU_CTX_OP_FREE_CTX:
  119. r = amdgpu_ctx_free(adev, fpriv, id);
  120. break;
  121. case AMDGPU_CTX_OP_QUERY_STATE:
  122. r = amdgpu_ctx_query(adev, fpriv, id, &state);
  123. if (r == 0) {
  124. args->out.state.flags = state.flags;
  125. args->out.state.hangs = state.hangs;
  126. }
  127. break;
  128. default:
  129. return -EINVAL;
  130. }
  131. return r;
  132. }
  133. struct amdgpu_ctx *amdgpu_ctx_get(struct amdgpu_fpriv *fpriv, uint32_t id)
  134. {
  135. struct amdgpu_ctx *ctx;
  136. struct amdgpu_ctx_mgr *mgr = &fpriv->ctx_mgr;
  137. mutex_lock(&mgr->lock);
  138. ctx = idr_find(&mgr->ctx_handles, id);
  139. if (ctx)
  140. kref_get(&ctx->refcount);
  141. mutex_unlock(&mgr->lock);
  142. return ctx;
  143. }
  144. int amdgpu_ctx_put(struct amdgpu_ctx *ctx)
  145. {
  146. struct amdgpu_fpriv *fpriv;
  147. struct amdgpu_ctx_mgr *mgr;
  148. if (ctx == NULL)
  149. return -EINVAL;
  150. fpriv = ctx->fpriv;
  151. mgr = &fpriv->ctx_mgr;
  152. mutex_lock(&mgr->lock);
  153. kref_put(&ctx->refcount, amdgpu_ctx_do_release);
  154. mutex_unlock(&mgr->lock);
  155. return 0;
  156. }