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
11591159
11601160 /* user fence */
11611161 struct amdgpu_bo_list_entry uf_entry;
1162+
1163+ unsigned num_post_dep_syncobjs;
1164+ struct drm_syncobj **post_dep_syncobjs;
11621165 };
11631166
11641167 #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
2727 #include <linux/pagemap.h>
2828 #include <drm/drmP.h>
2929 #include <drm/amdgpu_drm.h>
30+#include <drm/drm_syncobj.h>
3031 #include "amdgpu.h"
3132 #include "amdgpu_trace.h"
3233
@@ -154,6 +155,8 @@ int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data) · 121 unmodified lines
154155 break;
155156
156157 case AMDGPU_CHUNK_ID_DEPENDENCIES:
158+ case AMDGPU_CHUNK_ID_SYNCOBJ_IN:
159+ case AMDGPU_CHUNK_ID_SYNCOBJ_OUT:
157160 break;
158161
159162 default:
@@ -682,6 +685,11 @@ static void amdgpu_cs_parser_fini(struct amdgpu_cs_parser *parser, int error, bo · 522 unmodified lines
682685 ttm_eu_backoff_reservation(&parser->ticket,
683686 &parser->validated);
684687 }
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+
685693 dma_fence_put(parser->fence);
686694
687695 if (parser->ctx)
@@ -971,6 +979,64 @@ static int amdgpu_cs_process_fence_dep(struct amdgpu_cs_parser *p, · 283 unmodified lines
971979 return 0;
972980 }
973981
982+static 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+
997+static 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+
1016+static 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+
9741040 static int amdgpu_cs_dependencies(struct amdgpu_device *adev,
9751041 struct amdgpu_cs_parser *p)
9761042 {
@@ -985,12 +1051,30 @@ static int amdgpu_cs_dependencies(struct amdgpu_device *adev, · 8 unmodified lines
9851051 r = amdgpu_cs_process_fence_dep(p, chunk);
9861052 if (r)
9871053 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;
9881062 }
9891063 }
9901064
9911065 return 0;
9921066 }
9931067
1068+static 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+
9941078 static int amdgpu_cs_submit(struct amdgpu_cs_parser *p,
9951079 union drm_amdgpu_cs *cs)
9961080 {
@@ -1011,6 +1095,9 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p, · 14 unmodified lines
10111095 job->owner = p->filp;
10121096 job->fence_ctx = entity->fence_context;
10131097 p->fence = dma_fence_get(&job->base.s_fence->finished);
1098+
1099+ amdgpu_cs_post_dependencies(p);
1100+
10141101 cs->out.handle = amdgpu_ctx_add_fence(p->ctx, ring, p->fence);
10151102 job->uf_sequence = cs->out.handle;
10161103 amdgpu_job_free_resources(job);
@@ -1018,7 +1105,6 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p, · 1 unmodified line
10181105
10191106 trace_amdgpu_cs_ioctl(job);
10201107 amd_sched_entity_push_job(&job->base);
1021−
10221108 return 0;
10231109 }
10241110
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c+1−1
@@ -782,7 +782,7 @@ static struct drm_driver kms_driver = { · 781 unmodified lines
782782 .driver_features =
783783 DRIVER_USE_AGP |
784784 DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM |
785− DRIVER_PRIME | DRIVER_RENDER | DRIVER_MODESET,
785+ DRIVER_PRIME | DRIVER_RENDER | DRIVER_MODESET | DRIVER_SYNCOBJ,
786786 .load = amdgpu_driver_load_kms,
787787 .open = amdgpu_driver_open_kms,
788788 .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
440440 #define AMDGPU_CHUNK_ID_IB 0x01
441441 #define AMDGPU_CHUNK_ID_FENCE 0x02
442442 #define AMDGPU_CHUNK_ID_DEPENDENCIES 0x03
443+#define AMDGPU_CHUNK_ID_SYNCOBJ_IN 0x04
444+#define AMDGPU_CHUNK_ID_SYNCOBJ_OUT 0x05
443445
444446 struct drm_amdgpu_cs_chunk {
445447 __u32 chunk_id;
@@ -507,6 +509,10 @@ struct drm_amdgpu_cs_chunk_fence { · 61 unmodified lines
507509 __u32 offset;
508510 };
509511
512+struct drm_amdgpu_cs_chunk_sem {
513+ __u32 handle;
514+};
515+
510516 struct drm_amdgpu_cs_chunk_data {
511517 union {
512518 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