Created
September 11, 2018 20:32
-
-
Save FurretUber/1dd834e7c5d04ea06dccdffe9e377600 to your computer and use it in GitHub Desktop.
Which lines?
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<i915_gem_do_execbuffer@/home/usuario/Downloads/linux-4.17.18/drivers/gpu/drm/i915/i915_gem_execbuffer.c:0> | |
0 i915_gem_do_execbuffer(struct drm_device *dev, | |
struct drm_file *file, | |
struct drm_i915_gem_execbuffer2 *args, | |
struct drm_i915_gem_exec_object2 *exec, | |
struct drm_syncobj **fences) | |
5 { | |
struct i915_execbuffer eb; | |
7 struct dma_fence *in_fence = NULL; | |
8 struct sync_file *out_fence = NULL; | |
9 int out_fence_fd = -1; | |
int err; | |
BUILD_BUG_ON(__EXEC_INTERNAL_FLAGS & ~__I915_EXEC_ILLEGAL_FLAGS); | |
BUILD_BUG_ON(__EXEC_OBJECT_INTERNAL_FLAGS & | |
~__EXEC_OBJECT_UNKNOWN_FLAGS); | |
16 eb.i915 = to_i915(dev); | |
17 eb.file = file; | |
18 eb.args = args; | |
19 if (DBG_FORCE_RELOC || !(args->flags & I915_EXEC_NO_RELOC)) | |
20 args->flags |= __EXEC_HAS_RELOC; | |
22 eb.exec = exec; | |
23 eb.vma = (struct i915_vma **)(exec + args->buffer_count + 1); | |
24 eb.vma[0] = NULL; | |
25 eb.flags = (unsigned int *)(eb.vma + args->buffer_count + 1); | |
27 eb.invalid_flags = __EXEC_OBJECT_UNKNOWN_FLAGS; | |
28 if (USES_FULL_PPGTT(eb.i915)) | |
29 eb.invalid_flags |= EXEC_OBJECT_NEEDS_GTT; | |
30 reloc_cache_init(&eb.reloc_cache, eb.i915); | |
32 eb.buffer_count = args->buffer_count; | |
33 eb.batch_start_offset = args->batch_start_offset; | |
34 eb.batch_len = args->batch_len; | |
36 eb.batch_flags = 0; | |
37 if (args->flags & I915_EXEC_SECURE) { | |
38 if (!drm_is_current_master(file) || !capable(CAP_SYS_ADMIN)) | |
39 return -EPERM; | |
41 eb.batch_flags |= I915_DISPATCH_SECURE; | |
} | |
43 if (args->flags & I915_EXEC_IS_PINNED) | |
44 eb.batch_flags |= I915_DISPATCH_PINNED; | |
46 eb.engine = eb_select_engine(eb.i915, file, args); | |
if (!eb.engine) | |
48 return -EINVAL; | |
50 if (args->flags & I915_EXEC_RESOURCE_STREAMER) { | |
51 if (!HAS_RESOURCE_STREAMER(eb.i915)) { | |
52 DRM_DEBUG("RS is only allowed for Haswell, Gen8 and above\n"); | |
53 return -EINVAL; | |
} | |
55 if (eb.engine->id != RCS) { | |
56 DRM_DEBUG("RS is not available on %s\n", | |
eb.engine->name); | |
58 return -EINVAL; | |
} | |
61 eb.batch_flags |= I915_DISPATCH_RS; | |
} | |
64 if (args->flags & I915_EXEC_FENCE_IN) { | |
65 in_fence = sync_file_get_fence(lower_32_bits(args->rsvd2)); | |
66 if (!in_fence) | |
67 return -EINVAL; | |
} | |
70 if (args->flags & I915_EXEC_FENCE_OUT) { | |
71 out_fence_fd = get_unused_fd_flags(O_CLOEXEC); | |
72 if (out_fence_fd < 0) { | |
err = out_fence_fd; | |
goto err_in_fence; | |
} | |
} | |
78 err = eb_create(&eb); | |
if (err) | |
goto err_out_fence; | |
GEM_BUG_ON(!eb.lut_size); | |
84 err = eb_select_context(&eb); | |
if (unlikely(err)) | |
goto err_destroy; | |
/* | |
* Take a local wakeref for preparing to dispatch the execbuf as | |
* we expect to access the hardware fairly frequently in the | |
* process. Upon first dispatch, we acquire another prolonged | |
* wakeref that we hold until the GPU has been idle for at least | |
* 100ms. | |
*/ | |
95 intel_runtime_pm_get(eb.i915); | |
97 err = i915_mutex_lock_interruptible(dev); | |
98 if (err) | |
goto err_rpm; | |
101 err = eb_relocate(&eb); | |
102 if (err) { | |
/* | |
* If the user expects the execobject.offset and | |
* reloc.presumed_offset to be an exact match, | |
* as for using NO_RELOC, then we cannot update | |
* the execobject.offset until we have completed | |
* relocation. | |
*/ | |
110 args->flags &= ~__EXEC_HAS_RELOC; | |
111 goto err_vma; | |
} | |
114 if (unlikely(*eb.batch->exec_flags & EXEC_OBJECT_WRITE)) { | |
115 DRM_DEBUG("Attempting to use self-modifying batch buffer\n"); | |
116 err = -EINVAL; | |
117 goto err_vma; | |
} | |
119 if (eb.batch_start_offset > eb.batch->size || | |
120 eb.batch_len > eb.batch->size - eb.batch_start_offset) { | |
121 DRM_DEBUG("Attempting to use out-of-bounds batch\n"); | |
122 err = -EINVAL; | |
123 goto err_vma; | |
} | |
126 if (eb_use_cmdparser(&eb)) { | |
struct i915_vma *vma; | |
129 vma = eb_parse(&eb, drm_is_current_master(file)); | |
130 if (IS_ERR(vma)) { | |
err = PTR_ERR(vma); | |
goto err_vma; | |
} | |
135 if (vma) { | |
/* | |
* Batch parsed and accepted: | |
* | |
* Set the DISPATCH_SECURE bit to remove the NON_SECURE | |
* bit from MI_BATCH_BUFFER_START commands issued in | |
* the dispatch_execbuffer implementations. We | |
* specifically don't want that set on batches the | |
* command parser has accepted. | |
*/ | |
145 eb.batch_flags |= I915_DISPATCH_SECURE; | |
146 eb.batch_start_offset = 0; | |
147 eb.batch = vma; | |
} | |
} | |
151 if (eb.batch_len == 0) | |
152 eb.batch_len = eb.batch->size - eb.batch_start_offset; | |
/* | |
* snb/ivb/vlv conflate the "batch in ppgtt" bit with the "non-secure | |
* batch" bit. Hence we need to pin secure batches into the global gtt. | |
* hsw should have this fixed, but bdw mucks it up again. */ | |
158 if (eb.batch_flags & I915_DISPATCH_SECURE) { | |
struct i915_vma *vma; | |
/* | |
* So on first glance it looks freaky that we pin the batch here | |
* outside of the reservation loop. But: | |
* - The batch is already pinned into the relevant ppgtt, so we | |
* already have the backing storage fully allocated. | |
* - No other BO uses the global gtt (well contexts, but meh), | |
* so we don't really have issues with multiple objects not | |
* fitting due to fragmentation. | |
* So this is actually safe. | |
*/ | |
171 vma = i915_gem_object_ggtt_pin(eb.batch->obj, NULL, 0, 0, 0); | |
172 if (IS_ERR(vma)) { | |
173 err = PTR_ERR(vma); | |
174 goto err_vma; | |
} | |
177 eb.batch = vma; | |
} | |
/* All GPU relocation batches must be submitted prior to the user rq */ | |
GEM_BUG_ON(eb.reloc_cache.rq); | |
/* Allocate a request for this batch buffer nice and early. */ | |
184 eb.request = i915_request_alloc(eb.engine, eb.ctx); | |
185 if (IS_ERR(eb.request)) { | |
186 err = PTR_ERR(eb.request); | |
187 goto err_batch_unpin; | |
} | |
190 if (in_fence) { | |
191 err = i915_request_await_dma_fence(eb.request, in_fence); | |
192 if (err < 0) | |
goto err_request; | |
} | |
196 if (fences) { | |
197 err = await_fence_array(&eb, fences); | |
if (err) | |
goto err_request; | |
} | |
202 if (out_fence_fd != -1) { | |
203 out_fence = sync_file_create(&eb.request->fence); | |
204 if (!out_fence) { | |
err = -ENOMEM; | |
goto err_request; | |
} | |
} | |
/* | |
* Whilst this request exists, batch_obj will be on the | |
* active_list, and so will hold the active reference. Only when this | |
* request is retired will the the batch_obj be moved onto the | |
* inactive_list and lose its active reference. Hence we do not need | |
* to explicitly hold another reference here. | |
*/ | |
217 eb.request->batch = eb.batch; | |
219 trace_i915_request_queue(eb.request, eb.batch_flags); | |
220 err = eb_submit(&eb); | |
err_request: | |
222 __i915_request_add(eb.request, err == 0); | |
223 add_to_client(eb.request, file); | |
225 if (fences) | |
226 signal_fence_array(&eb, fences); | |
228 if (out_fence) { | |
229 if (err == 0) { | |
230 fd_install(out_fence_fd, out_fence->file); | |
args->rsvd2 &= GENMASK_ULL(31, 0); /* keep in-fence */ | |
232 args->rsvd2 |= (u64)out_fence_fd << 32; | |
233 out_fence_fd = -1; | |
} else { | |
235 fput(out_fence->file); | |
} | |
} | |
239 err_batch_unpin: | |
240 if (eb.batch_flags & I915_DISPATCH_SECURE) | |
241 i915_vma_unpin(eb.batch); | |
err_vma: | |
243 if (eb.exec) | |
244 eb_release_vmas(&eb); | |
245 mutex_unlock(&dev->struct_mutex); | |
err_rpm: | |
247 intel_runtime_pm_put(eb.i915); | |
248 i915_gem_context_put(eb.ctx); | |
err_destroy: | |
250 eb_destroy(&eb); | |
err_out_fence: | |
252 if (out_fence_fd != -1) | |
253 put_unused_fd(out_fence_fd); | |
err_in_fence: | |
255 dma_fence_put(in_fence); | |
return err; | |
257 } | |
static size_t eb_element_size(void) | |
{ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment