@@ -84,9 +84,52 @@ static int query_topology_info(struct drm_i915_private *dev_priv,
return total_length;
}
+static int
+query_engine_queues(struct drm_i915_private *i915,
+ struct drm_i915_query_item *query_item)
+{
+ struct drm_i915_query_engine_queues __user *query_ptr =
+ u64_to_user_ptr(query_item->data_ptr);
+ struct drm_i915_query_engine_queues query;
+ struct intel_engine_cs *engine;
+ const int len = sizeof(query);
+ unsigned int i;
+
+ if (query_item->flags)
+ return -EINVAL;
+
+ if (!query_item->length)
+ return len;
+ else if (query_item->length < len)
+ return -EINVAL;
+
+ if (copy_from_user(&query, query_ptr, len))
+ return -EFAULT;
+
+ for (i = 0; i < ARRAY_SIZE(query.rsvd); i++) {
+ if (query.rsvd[i])
+ return -EINVAL;
+ }
+
+ engine = intel_engine_lookup_user(i915, query.class, query.instance);
+ if (!engine)
+ return -ENOENT;
+
+ query.queued = atomic_read(&engine->request_stats.queued);
+ query.runnable = engine->request_stats.runnable;
+ query.running = intel_engine_last_submit(engine) -
+ intel_engine_get_seqno(engine);
+
+ if (copy_to_user(query_ptr, &query, len))
+ return -EFAULT;
+
+ return len;
+}
+
static int (* const i915_query_funcs[])(struct drm_i915_private *dev_priv,
struct drm_i915_query_item *query_item) = {
query_topology_info,
+ query_engine_queues,
};
int i915_query_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
@@ -1637,6 +1637,7 @@ struct drm_i915_perf_oa_config {
struct drm_i915_query_item {
__u64 query_id;
#define DRM_I915_QUERY_TOPOLOGY_INFO 1
+#define DRM_I915_QUERY_ENGINE_QUEUES 2
/*
* When set to zero by userspace, this is filled with the size of the
@@ -1734,6 +1735,34 @@ struct drm_i915_query_topology_info {
__u8 data[];
};
+/**
+ * struct drm_i915_query_engine_queues
+ *
+ * Engine queues query enables userspace to query current counts of active
+ * requests in their different states.
+ */
+struct drm_i915_query_engine_queues {
+ /**
+ * Engine class as in enum drm_i915_gem_engine_class (set by userspace).
+ */
+ __u16 class;
+
+ /** Engine instance number (set by userspace). */
+ __u16 instance;
+
+ /** Number of requests with unresolved fences and dependencies. */
+ __u32 queued;
+
+ /** Number of ready requests waiting on a slot on GPU. */
+ __u32 runnable;
+
+ /** Number of requests executing on the GPU. */
+ __u32 running;
+
+ /** Reserved bits must be set to zero by userspace. */
+ __u32 rsvd[6];
+};
+
#if defined(__cplusplus)
}
#endif