@@ -3101,7 +3101,7 @@ static inline void i915_gem_object_unpin_map(struct drm_i915_gem_object *obj)
int __must_check i915_mutex_lock_interruptible(struct drm_device *dev);
int i915_gem_object_sync(struct drm_i915_gem_object *obj,
struct intel_engine_cs *to,
- struct drm_i915_gem_request **to_req);
+ struct drm_i915_gem_request **to_req, bool to_batch);
void i915_vma_move_to_active(struct i915_vma *vma,
struct drm_i915_gem_request *req);
int i915_gem_dumb_create(struct drm_file *file_priv,
@@ -3658,7 +3658,7 @@ static int
__i915_gem_object_sync(struct drm_i915_gem_object *obj,
struct intel_engine_cs *to,
struct drm_i915_gem_request *from_req,
- struct drm_i915_gem_request **to_req)
+ struct drm_i915_gem_request **to_req, bool to_batch)
{
struct intel_engine_cs *from;
int ret;
@@ -3670,6 +3670,14 @@ __i915_gem_object_sync(struct drm_i915_gem_object *obj,
if (i915_gem_request_completed(from_req))
return 0;
+ /*
+ * The scheduler will manage inter-ring object dependencies
+ * as long as both to and from requests are scheduler managed
+ * (i.e. batch buffers).
+ */
+ if (to_batch && i915_scheduler_is_request_batch_buffer(from_req))
+ return 0;
+
if (!i915_semaphore_is_enabled(obj->base.dev)) {
struct drm_i915_private *i915 = to_i915(obj->base.dev);
uint32_t flags;
@@ -3728,6 +3736,8 @@ __i915_gem_object_sync(struct drm_i915_gem_object *obj,
* @to_req: request we wish to use the object for. See below.
* This will be allocated and returned if a request is
* required but not passed in.
+ * @to_batch: is the sync request on behalf of batch buffer submission?
+ * If so then the scheduler can (potentially) manage the synchronisation.
*
* This code is meant to abstract object synchronization with the GPU.
* Calling with NULL implies synchronizing the object with the CPU
@@ -3758,7 +3768,7 @@ __i915_gem_object_sync(struct drm_i915_gem_object *obj,
int
i915_gem_object_sync(struct drm_i915_gem_object *obj,
struct intel_engine_cs *to,
- struct drm_i915_gem_request **to_req)
+ struct drm_i915_gem_request **to_req, bool to_batch)
{
const bool readonly = obj->base.pending_write_domain == 0;
struct drm_i915_gem_request *req[I915_NUM_ENGINES];
@@ -3780,7 +3790,7 @@ i915_gem_object_sync(struct drm_i915_gem_object *obj,
req[n++] = obj->last_read_req[i];
}
for (i = 0; i < n; i++) {
- ret = __i915_gem_object_sync(obj, to, req[i], to_req);
+ ret = __i915_gem_object_sync(obj, to, req[i], to_req, to_batch);
if (ret)
return ret;
}
@@ -954,7 +954,7 @@ i915_gem_execbuffer_move_to_gpu(struct drm_i915_gem_request *req,
struct drm_i915_gem_object *obj = vma->obj;
if (obj->active & other_rings) {
- ret = i915_gem_object_sync(obj, req->engine, &req);
+ ret = i915_gem_object_sync(obj, req->engine, &req, true);
if (ret)
return ret;
}
@@ -1344,6 +1344,25 @@ bool i915_scheduler_is_mutex_required(struct drm_i915_gem_request *req)
}
/**
+ * i915_scheduler_is_request_batch_buffer - is this request related to a
+ * batch buffer object?
+ * @req: request to be queried
+ *
+ * Returns true if the given request is for a batch buffer. False means it
+ * is for something else - page flip, context initialisation, etc.
+ */
+bool i915_scheduler_is_request_batch_buffer(struct drm_i915_gem_request *req)
+{
+ if (req->scheduler_qe == NULL)
+ return false;
+
+ if (req->scheduler_qe->params.batch_obj == NULL)
+ return false;
+
+ return true;
+}
+
+/**
* i915_scheduler_closefile - notify the scheduler that a DRM file handle
* has been closed.
* @dev: DRM device
@@ -151,6 +151,7 @@ int i915_scheduler_flush(struct intel_engine_cs *engine, bool is_locked);
int i915_scheduler_flush_stamp(struct intel_engine_cs *engine,
unsigned long stamp, bool is_locked);
bool i915_scheduler_is_mutex_required(struct drm_i915_gem_request *req);
+bool i915_scheduler_is_request_batch_buffer(struct drm_i915_gem_request *req);
int i915_scheduler_query_stats(struct intel_engine_cs *engine,
struct i915_scheduler_stats_nodes *stats);
bool i915_scheduler_file_queue_wait(struct drm_file *file);
@@ -11607,7 +11607,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
* into the display plane and skip any waits.
*/
if (!mmio_flip) {
- ret = i915_gem_object_sync(obj, engine, &request);
+ ret = i915_gem_object_sync(obj, engine, &request, false);
if (ret)
goto cleanup_pending;
}
@@ -698,7 +698,7 @@ static int execlists_move_to_gpu(struct drm_i915_gem_request *req,
struct drm_i915_gem_object *obj = vma->obj;
if (obj->active & other_rings) {
- ret = i915_gem_object_sync(obj, req->engine, &req);
+ ret = i915_gem_object_sync(obj, req->engine, &req, true);
if (ret)
return ret;
}