History

amdgpu: use drm sync objects for shared semaphores (v6)

This creates a new command submission chunk for amdgpu to add in and out sync objects around the submission. Sync objects are managed via the drm syncobj ioctls. The command submission interface is enhanced with two new chunks, one for syncobj pre submission dependencies, and one for post submission sync obj signalling, and just takes a list of handles for each. This is based on work originally done by David Zhou at AMD, with input from Christian Konig on what things should look like. In theory VkFences could be backed with sync objects and just get passed into the cs as syncobj handles as well. NOTE: this interface addition needs a version bump to expose it to userspace. TODO: update to dep_sync when rebasing onto amdgpu master. (with this - r-b from Christian) v1.1: keep file reference on import. v2: move to using syncobjs v2.1: change some APIs to just use p pointer. v3: make more robust against CS failures, we now add the wait sems but only remove them once the CS job has been submitted. v4: rewrite names of API and base on new syncobj code. v5: move post deps earlier, rename some apis v6: lookup post deps earlier, and just replace fences in post deps stage (Christian)

Dave Airlie committed 9 years ago

Commit 660e8551 parent 6f0308e4 files · +97 −2Browse files

Unified · Split

4 files
  1. drivers/gpu/drm/amd/amdgpu/amdgpu.h +3 −0
  2. drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +87 −1
  3. drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +1 −1
  4. include/uapi/drm/amdgpu_drm.h +6 −0
drivers/gpu/drm/amd/amdgpu/amdgpu.h+3−0
@@ -1159,6 +1159,9 @@ struct amdgpu_cs_parser { · 1158 unmodified lines
1159 1159
1160 /* user fence */1160 /* user fence */
1161 struct amdgpu_bo_list_entry uf_entry;1161 struct amdgpu_bo_list_entry uf_entry;
1162
1163 unsigned num_post_dep_syncobjs;
1164 struct drm_syncobj **post_dep_syncobjs;
1162};1165};
1163 1166
1164#define AMDGPU_PREAMBLE_IB_PRESENT (1 << 0) /* bit set means command submit involves a preamble IB */1167#define AMDGPU_PREAMBLE_IB_PRESENT (1 << 0) /* bit set means command submit involves a preamble IB */
drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c+87−1
@@ -27,6 +27,7 @@ · 26 unmodified lines
27#include <linux/pagemap.h>27#include <linux/pagemap.h>
28#include <drm/drmP.h>28#include <drm/drmP.h>
29#include <drm/amdgpu_drm.h>29#include <drm/amdgpu_drm.h>
30#include <drm/drm_syncobj.h>
30#include "amdgpu.h"31#include "amdgpu.h"
31#include "amdgpu_trace.h"32#include "amdgpu_trace.h"
32 33
@@ -154,6 +155,8 @@ int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data) · 121 unmodified lines
154 break;155 break;
155 156
156 case AMDGPU_CHUNK_ID_DEPENDENCIES:157 case AMDGPU_CHUNK_ID_DEPENDENCIES:
158 case AMDGPU_CHUNK_ID_SYNCOBJ_IN:
159 case AMDGPU_CHUNK_ID_SYNCOBJ_OUT:
157 break;160 break;
158 161
159 default:162 default:
@@ -682,6 +685,11 @@ static void amdgpu_cs_parser_fini(struct amdgpu_cs_parser *parser, int error, bo · 522 unmodified lines
682 ttm_eu_backoff_reservation(&parser->ticket,685 ttm_eu_backoff_reservation(&parser->ticket,
683 &parser->validated);686 &parser->validated);
684 }687 }
688
689 for (i = 0; i < parser->num_post_dep_syncobjs; i++)
690 drm_syncobj_put(parser->post_dep_syncobjs[i]);
691 kfree(parser->post_dep_syncobjs);
692
685 dma_fence_put(parser->fence);693 dma_fence_put(parser->fence);
686 694
687 if (parser->ctx)695 if (parser->ctx)
@@ -971,6 +979,64 @@ static int amdgpu_cs_process_fence_dep(struct amdgpu_cs_parser *p, · 283 unmodified lines
971 return 0;979 return 0;
972}980}
973 981
982static int amdgpu_syncobj_lookup_and_add_to_sync(struct amdgpu_cs_parser *p,
983 uint32_t handle)
984{
985 int r;
986 struct dma_fence *fence;
987 r = drm_syncobj_fence_get(p->filp, handle, &fence);
988 if (r)
989 return r;
990
991 r = amdgpu_sync_fence(p->adev, &p->job->sync, fence);
992 dma_fence_put(fence);
993
994 return r;
995}
996
997static int amdgpu_cs_process_syncobj_in_dep(struct amdgpu_cs_parser *p,
998 struct amdgpu_cs_chunk *chunk)
999{
1000 unsigned num_deps;
1001 int i, r;
1002 struct drm_amdgpu_cs_chunk_sem *deps;
1003
1004 deps = (struct drm_amdgpu_cs_chunk_sem *)chunk->kdata;
1005 num_deps = chunk->length_dw * 4 /
1006 sizeof(struct drm_amdgpu_cs_chunk_sem);
1007
1008 for (i = 0; i < num_deps; ++i) {
1009 r = amdgpu_syncobj_lookup_and_add_to_sync(p, deps[i].handle);
1010 if (r)
1011 return r;
1012 }
1013 return 0;
1014}
1015
1016static int amdgpu_cs_process_syncobj_out_dep(struct amdgpu_cs_parser *p,
1017 struct amdgpu_cs_chunk *chunk)
1018{
1019 unsigned num_deps;
1020 int i;
1021 struct drm_amdgpu_cs_chunk_sem *deps;
1022 deps = (struct drm_amdgpu_cs_chunk_sem *)chunk->kdata;
1023 num_deps = chunk->length_dw * 4 /
1024 sizeof(struct drm_amdgpu_cs_chunk_sem);
1025
1026 p->post_dep_syncobjs = kmalloc_array(num_deps,
1027 sizeof(struct drm_syncobj *),
1028 GFP_KERNEL);
1029 p->num_post_dep_syncobjs = 0;
1030
1031 for (i = 0; i < num_deps; ++i) {
1032 p->post_dep_syncobjs[i] = drm_syncobj_find(p->filp, deps[i].handle);
1033 if (!p->post_dep_syncobjs[i])
1034 return -EINVAL;
1035 p->num_post_dep_syncobjs++;
1036 }
1037 return 0;
1038}
1039
974static int amdgpu_cs_dependencies(struct amdgpu_device *adev,1040static int amdgpu_cs_dependencies(struct amdgpu_device *adev,
975 struct amdgpu_cs_parser *p)1041 struct amdgpu_cs_parser *p)
976{1042{
@@ -985,12 +1051,30 @@ static int amdgpu_cs_dependencies(struct amdgpu_device *adev, · 8 unmodified lines
985 r = amdgpu_cs_process_fence_dep(p, chunk);1051 r = amdgpu_cs_process_fence_dep(p, chunk);
986 if (r)1052 if (r)
987 return r;1053 return r;
1054 } else if (chunk->chunk_id == AMDGPU_CHUNK_ID_SYNCOBJ_IN) {
1055 r = amdgpu_cs_process_syncobj_in_dep(p, chunk);
1056 if (r)
1057 return r;
1058 } else if (chunk->chunk_id == AMDGPU_CHUNK_ID_SYNCOBJ_OUT) {
1059 r = amdgpu_cs_process_syncobj_out_dep(p, chunk);
1060 if (r)
1061 return r;
988 }1062 }
989 }1063 }
990 1064
991 return 0;1065 return 0;
992}1066}
993 1067
1068static void amdgpu_cs_post_dependencies(struct amdgpu_cs_parser *p)
1069{
1070 int i;
1071
1072 for (i = 0; i < p->num_post_dep_syncobjs; ++i) {
1073 drm_syncobj_replace_fence(p->filp, p->post_dep_syncobjs[i],
1074 p->fence);
1075 }
1076}
1077
994static int amdgpu_cs_submit(struct amdgpu_cs_parser *p,1078static int amdgpu_cs_submit(struct amdgpu_cs_parser *p,
995 union drm_amdgpu_cs *cs)1079 union drm_amdgpu_cs *cs)
996{1080{
@@ -1011,6 +1095,9 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p, · 14 unmodified lines
1011 job->owner = p->filp;1095 job->owner = p->filp;
1012 job->fence_ctx = entity->fence_context;1096 job->fence_ctx = entity->fence_context;
1013 p->fence = dma_fence_get(&job->base.s_fence->finished);1097 p->fence = dma_fence_get(&job->base.s_fence->finished);
1098
1099 amdgpu_cs_post_dependencies(p);
1100
1014 cs->out.handle = amdgpu_ctx_add_fence(p->ctx, ring, p->fence);1101 cs->out.handle = amdgpu_ctx_add_fence(p->ctx, ring, p->fence);
1015 job->uf_sequence = cs->out.handle;1102 job->uf_sequence = cs->out.handle;
1016 amdgpu_job_free_resources(job);1103 amdgpu_job_free_resources(job);
@@ -1018,7 +1105,6 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p, · 1 unmodified line
1018 1105
1019 trace_amdgpu_cs_ioctl(job);1106 trace_amdgpu_cs_ioctl(job);
1020 amd_sched_entity_push_job(&job->base);1107 amd_sched_entity_push_job(&job->base);
1021
1022 return 0;1108 return 0;
1023}1109}
1024 1110
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c+1−1
@@ -782,7 +782,7 @@ static struct drm_driver kms_driver = { · 781 unmodified lines
782 .driver_features =782 .driver_features =
783 DRIVER_USE_AGP |783 DRIVER_USE_AGP |
784 DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM |784 DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM |
785 DRIVER_PRIME | DRIVER_RENDER | DRIVER_MODESET,785 DRIVER_PRIME | DRIVER_RENDER | DRIVER_MODESET | DRIVER_SYNCOBJ,
786 .load = amdgpu_driver_load_kms,786 .load = amdgpu_driver_load_kms,
787 .open = amdgpu_driver_open_kms,787 .open = amdgpu_driver_open_kms,
788 .postclose = amdgpu_driver_postclose_kms,788 .postclose = amdgpu_driver_postclose_kms,
include/uapi/drm/amdgpu_drm.h+6−0
@@ -440,6 +440,8 @@ struct drm_amdgpu_gem_va { · 439 unmodified lines
440#define AMDGPU_CHUNK_ID_IB 0x01440#define AMDGPU_CHUNK_ID_IB 0x01
441#define AMDGPU_CHUNK_ID_FENCE 0x02441#define AMDGPU_CHUNK_ID_FENCE 0x02
442#define AMDGPU_CHUNK_ID_DEPENDENCIES 0x03442#define AMDGPU_CHUNK_ID_DEPENDENCIES 0x03
443#define AMDGPU_CHUNK_ID_SYNCOBJ_IN 0x04
444#define AMDGPU_CHUNK_ID_SYNCOBJ_OUT 0x05
443 445
444struct drm_amdgpu_cs_chunk {446struct drm_amdgpu_cs_chunk {
445 __u32 chunk_id;447 __u32 chunk_id;
@@ -507,6 +509,10 @@ struct drm_amdgpu_cs_chunk_fence { · 61 unmodified lines
507 __u32 offset;509 __u32 offset;
508};510};
509 511
512struct drm_amdgpu_cs_chunk_sem {
513 __u32 handle;
514};
515
510struct drm_amdgpu_cs_chunk_data {516struct drm_amdgpu_cs_chunk_data {
511 union {517 union {
512 struct drm_amdgpu_cs_chunk_ib ib_data;518 struct drm_amdgpu_cs_chunk_ib ib_data;

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t