summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDaniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>2018-02-22 09:35:06 -0800
committerChris Wilson <chris@chris-wilson.co.uk>2018-02-23 08:56:58 +0000
commit7040f3be1efec904c3ba5729a5a532d03346a161 (patch)
tree60cb2490bdd3f31374147ceb58a31e72d40b57e3 /lib
parente2e2b4c4d11a1aed2af1079c914e76df4eddbe76 (diff)
lib/igt_dummyload: add igt_cork
The "cork" bo (imported bo with attached fence) and fence is used in several tests to stall execution. Moving it to a common place makes the codebase cleaner. Note that the actual test updates is done in follow up patches as it is simpler to do in one go after one more common function is added in the next patch. v2: don't use new/free naming, don't use dynamic alloc (Chris) v3: add sw_sync common functions. (Chris) v4: squash sw_sync and vgem cork structs into one. (Chris) v5: use anonymous enum in cork struct. (Chris) v6: reset cork after unplugging. (Chris) Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com> Signed-off-by: Antonio Argenziano <antonio.argenziano@intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'lib')
-rw-r--r--lib/igt_dummyload.c119
-rw-r--r--lib/igt_dummyload.h32
2 files changed, 151 insertions, 0 deletions
diff --git a/lib/igt_dummyload.c b/lib/igt_dummyload.c
index 27eb402b..ddd43451 100644
--- a/lib/igt_dummyload.c
+++ b/lib/igt_dummyload.c
@@ -29,12 +29,14 @@
#include <i915_drm.h>
#include "igt_core.h"
+#include "drmtest.h"
#include "igt_dummyload.h"
#include "igt_gt.h"
#include "intel_chipset.h"
#include "intel_reg.h"
#include "ioctl_wrappers.h"
#include "sw_sync.h"
+#include "igt_vgem.h"
/**
* SECTION:igt_dummyload
@@ -371,3 +373,120 @@ void igt_terminate_spin_batches(void)
igt_spin_batch_end(iter);
pthread_mutex_unlock(&list_lock);
}
+
+static uint32_t plug_vgem_handle(struct igt_cork *cork, int fd)
+{
+ struct vgem_bo bo;
+ int dmabuf;
+ uint32_t handle;
+
+ cork->vgem.device = drm_open_driver(DRIVER_VGEM);
+ igt_require(vgem_has_fences(cork->vgem.device));
+
+ bo.width = bo.height = 1;
+ bo.bpp = 4;
+ vgem_create(cork->vgem.device, &bo);
+ cork->vgem.fence = vgem_fence_attach(cork->vgem.device, &bo, VGEM_FENCE_WRITE);
+
+ dmabuf = prime_handle_to_fd(cork->vgem.device, bo.handle);
+ handle = prime_fd_to_handle(fd, dmabuf);
+ close(dmabuf);
+
+ return handle;
+}
+
+static void unplug_vgem_handle(struct igt_cork *cork)
+{
+ vgem_fence_signal(cork->vgem.device, cork->vgem.fence);
+ close(cork->vgem.device);
+}
+
+static uint32_t plug_sync_fd(struct igt_cork *cork)
+{
+ int fence;
+
+ igt_require_sw_sync();
+
+ cork->sw_sync.timeline = sw_sync_timeline_create();
+ fence = sw_sync_timeline_create_fence(cork->sw_sync.timeline, 1);
+
+ return fence;
+}
+
+static void unplug_sync_fd(struct igt_cork *cork)
+{
+ sw_sync_timeline_inc(cork->sw_sync.timeline, 1);
+ close(cork->sw_sync.timeline);
+}
+
+/**
+ * igt_cork_plug:
+ * @fd: open drm file descriptor
+ * @method: method to utilize for corking.
+ * @cork: structure that will be filled with the state of the cork bo.
+ * Note: this has to match the corking method.
+ *
+ * This function provides a mechanism to stall submission. It provides two
+ * blocking methods:
+ *
+ * VGEM_BO.
+ * Imports a vgem bo with a fence attached to it. This bo can be used as a
+ * dependency during submission to stall execution until the fence is signaled.
+ *
+ * SW_SYNC:
+ * Creates a timeline and then a fence on that timeline. The fence can be used
+ * as an input fence to a request, the request will be stalled until the fence
+ * is signaled.
+ *
+ * The parameters required to unblock the execution and to cleanup are stored in
+ * the provided cork structure.
+ *
+ * Returns:
+ * Handle of the imported BO / Sw sync fence FD.
+ */
+uint32_t igt_cork_plug(struct igt_cork *cork, int fd)
+{
+ igt_assert(cork->fd == -1);
+
+ switch (cork->type) {
+ case CORK_SYNC_FD:
+ return plug_sync_fd(cork);
+
+ case CORK_VGEM_HANDLE:
+ return plug_vgem_handle(cork, fd);
+
+ default:
+ igt_assert_f(0, "Invalid cork type!\n");
+ return 0;
+ }
+}
+
+/**
+ * igt_cork_unplug:
+ * @method: method to utilize for corking.
+ * @cork: cork state from igt_cork_plug()
+ *
+ * This function unblocks the execution by signaling the fence attached to the
+ * imported bo and does the necessary post-processing.
+ *
+ * NOTE: the handle returned by igt_cork_plug is not closed during this phase.
+ */
+void igt_cork_unplug(struct igt_cork *cork)
+{
+ igt_assert(cork->fd != -1);
+
+ switch (cork->type) {
+ case CORK_SYNC_FD:
+ unplug_sync_fd(cork);
+ break;
+
+ case CORK_VGEM_HANDLE:
+ unplug_vgem_handle(cork);
+ break;
+
+ default:
+ igt_assert_f(0, "Invalid cork type!\n");
+ }
+
+ cork->fd = -1; /* Reset cork */
+}
diff --git a/lib/igt_dummyload.h b/lib/igt_dummyload.h
index ffa7e351..4103e4ab 100644
--- a/lib/igt_dummyload.h
+++ b/lib/igt_dummyload.h
@@ -61,4 +61,36 @@ void igt_spin_batch_free(int fd, igt_spin_t *spin);
void igt_terminate_spin_batches(void);
+enum igt_cork_type {
+ CORK_SYNC_FD = 1,
+ CORK_VGEM_HANDLE
+};
+
+struct igt_cork_vgem {
+ int device;
+ uint32_t fence;
+};
+
+struct igt_cork_sw_sync {
+ int timeline;
+};
+
+struct igt_cork {
+ enum igt_cork_type type;
+
+ union {
+ int fd;
+
+ struct igt_cork_vgem vgem;
+ struct igt_cork_sw_sync sw_sync;
+ };
+};
+
+#define IGT_CORK(name, cork_type) struct igt_cork name = { .type = cork_type, .fd = -1}
+#define IGT_CORK_HANDLE(name) IGT_CORK(name, CORK_VGEM_HANDLE)
+#define IGT_CORK_FENCE(name) IGT_CORK(name, CORK_SYNC_FD)
+
+uint32_t igt_cork_plug(struct igt_cork *cork, int fd);
+void igt_cork_unplug(struct igt_cork *cork);
+
#endif /* __IGT_DUMMYLOAD_H__ */