selftests: ion: Add simple test with the vgem driver
authorLaura Abbott <labbott@redhat.com>
Fri, 16 Feb 2018 01:24:45 +0000 (17:24 -0800)
committerShuah Khan <shuahkh@osg.samsung.com>
Tue, 6 Mar 2018 01:56:24 +0000 (18:56 -0700)
Ion is designed to be a framework used by other clients who perform
operations on the buffer. Use the DRM vgem client as a simple consumer.
In conjunction with the dma-buf sync ioctls, this tests the full attach/map
path for the system heap.

Signed-off-by: Laura Abbott <labbott@redhat.com>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
tools/testing/selftests/android/ion/Makefile
tools/testing/selftests/android/ion/config
tools/testing/selftests/android/ion/ionmap_test.c [new file with mode: 0644]

index 96e0c448b39d31cf2846040c2df79b78998d9792..d23b6d537d8ba37ec82c01daaf543cea20b0fb82 100644 (file)
@@ -2,7 +2,7 @@
 INCLUDEDIR := -I. -I../../../../../drivers/staging/android/uapi/
 CFLAGS := $(CFLAGS) $(INCLUDEDIR) -Wall -O2 -g
 
-TEST_GEN_FILES := ionapp_export ionapp_import
+TEST_GEN_FILES := ionapp_export ionapp_import ionmap_test
 
 all: $(TEST_GEN_FILES)
 
@@ -14,3 +14,4 @@ include ../../lib.mk
 
 $(OUTPUT)/ionapp_export: ionapp_export.c ipcsocket.c ionutils.c
 $(OUTPUT)/ionapp_import: ionapp_import.c ipcsocket.c ionutils.c
+$(OUTPUT)/ionmap_test: ionmap_test.c ionutils.c
index 19db6ca9aa2b2496f1c457a7053809dea6ec6739..b4ad748a9dd99a586af85c8d584880614a1863c7 100644 (file)
@@ -2,3 +2,4 @@ CONFIG_ANDROID=y
 CONFIG_STAGING=y
 CONFIG_ION=y
 CONFIG_ION_SYSTEM_HEAP=y
+CONFIG_DRM_VGEM=y
diff --git a/tools/testing/selftests/android/ion/ionmap_test.c b/tools/testing/selftests/android/ion/ionmap_test.c
new file mode 100644 (file)
index 0000000..dab36b0
--- /dev/null
@@ -0,0 +1,136 @@
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <linux/dma-buf.h>
+
+#include <drm/drm.h>
+
+#include "ion.h"
+#include "ionutils.h"
+
+int check_vgem(int fd)
+{
+       drm_version_t version = { 0 };
+       char name[5];
+       int ret;
+
+       version.name_len = 4;
+       version.name = name;
+
+       ret = ioctl(fd, DRM_IOCTL_VERSION, &version);
+       if (ret)
+               return 1;
+
+       return strcmp(name, "vgem");
+}
+
+int open_vgem(void)
+{
+       int i, fd;
+       const char *drmstr = "/dev/dri/card";
+
+       fd = -1;
+       for (i = 0; i < 16; i++) {
+               char name[80];
+
+               sprintf(name, "%s%u", drmstr, i);
+
+               fd = open(name, O_RDWR);
+               if (fd < 0)
+                       continue;
+
+               if (check_vgem(fd)) {
+                       close(fd);
+                       continue;
+               } else {
+                       break;
+               }
+
+       }
+       return fd;
+}
+
+int import_vgem_fd(int vgem_fd, int dma_buf_fd, uint32_t *handle)
+{
+       struct drm_prime_handle import_handle = { 0 };
+       int ret;
+
+       import_handle.fd = dma_buf_fd;
+       import_handle.flags = 0;
+       import_handle.handle = 0;
+
+       ret = ioctl(vgem_fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &import_handle);
+       if (ret == 0)
+               *handle = import_handle.handle;
+       return ret;
+}
+
+void close_handle(int vgem_fd, uint32_t handle)
+{
+       struct drm_gem_close close = { 0 };
+
+       close.handle = handle;
+       ioctl(vgem_fd, DRM_IOCTL_GEM_CLOSE, &close);
+}
+
+int main()
+{
+       int ret, vgem_fd;
+       struct ion_buffer_info info;
+       uint32_t handle = 0;
+       struct dma_buf_sync sync = { 0 };
+
+       info.heap_type = ION_HEAP_TYPE_SYSTEM;
+       info.heap_size = 4096;
+       info.flag_type = ION_FLAG_CACHED;
+
+       ret = ion_export_buffer_fd(&info);
+       if (ret < 0) {
+               printf("ion buffer alloc failed\n");
+               return -1;
+       }
+
+       vgem_fd = open_vgem();
+       if (vgem_fd < 0) {
+               ret = vgem_fd;
+               printf("Failed to open vgem\n");
+               goto out_ion;
+       }
+
+       ret = import_vgem_fd(vgem_fd, info.buffd, &handle);
+
+       if (ret < 0) {
+               printf("Failed to import buffer\n");
+               goto out_vgem;
+       }
+
+       sync.flags = DMA_BUF_SYNC_START | DMA_BUF_SYNC_RW;
+       ret = ioctl(info.buffd, DMA_BUF_IOCTL_SYNC, &sync);
+       if (ret)
+               printf("sync start failed %d\n", errno);
+
+       memset(info.buffer, 0xff, 4096);
+
+       sync.flags = DMA_BUF_SYNC_END | DMA_BUF_SYNC_RW;
+       ret = ioctl(info.buffd, DMA_BUF_IOCTL_SYNC, &sync);
+       if (ret)
+               printf("sync end failed %d\n", errno);
+
+       close_handle(vgem_fd, handle);
+       ret = 0;
+
+out_vgem:
+       close(vgem_fd);
+out_ion:
+       ion_close_buffer_fd(&info);
+       printf("done.\n");
+       return ret;
+}