diff options
author | Chanho Park <chanho61.park@samsung.com> | 2014-11-17 22:22:48 +0900 |
---|---|---|
committer | Inki Dae <inki.dae@samsung.com> | 2014-11-20 23:23:33 +0900 |
commit | be6fc3a4e8a2167b8e8c42e5bf8df016efb39c23 (patch) | |
tree | 460b78a6e31af2295f6b72202194b4d843859404 | |
parent | 5ec5f4fc4a9e7b875ae1d867436676a6d3feac2c (diff) | |
download | linux-3.10-be6fc3a4e8a2167b8e8c42e5bf8df016efb39c23.tar.gz linux-3.10-be6fc3a4e8a2167b8e8c42e5bf8df016efb39c23.tar.bz2 linux-3.10-be6fc3a4e8a2167b8e8c42e5bf8df016efb39c23.zip |
selftests: dma-buf: add selftest for dmabuf-syncdmafence
Change-Id: Id5c0cf374ae497dc1c9825109de7dbc5c14ee4dc
Signed-off-by: Chanho Park <chanho61.park@samsung.com>
-rw-r--r-- | tools/testing/selftests/dma-buf/Makefile | 11 | ||||
-rw-r--r-- | tools/testing/selftests/dma-buf/dmabuf-sync-test.c | 185 |
2 files changed, 196 insertions, 0 deletions
diff --git a/tools/testing/selftests/dma-buf/Makefile b/tools/testing/selftests/dma-buf/Makefile new file mode 100644 index 00000000000..f109ddfc791 --- /dev/null +++ b/tools/testing/selftests/dma-buf/Makefile @@ -0,0 +1,11 @@ +CFLAGS= +LDFLAGS=-lpthread -static + +all: + ${CROSS_COMPILE}gcc dmabuf-sync-test.c -o dmabuf-sync-test ${CFLAGS} ${LDFLAGS} + +run_tests: all + @./dmabuf-sync-test || echo "dmabuf-sync-test: [FAIL]" + +clean: + rm -fr ./dmabuf-sync-test diff --git a/tools/testing/selftests/dma-buf/dmabuf-sync-test.c b/tools/testing/selftests/dma-buf/dmabuf-sync-test.c new file mode 100644 index 00000000000..ecf8a52613e --- /dev/null +++ b/tools/testing/selftests/dma-buf/dmabuf-sync-test.c @@ -0,0 +1,185 @@ +#define _GNU_SOURCE + +#include <stdio.h> +#include <stdlib.h> +#include <limits.h> +#include <unistd.h> +#include <errno.h> +#include <string.h> +#include <fcntl.h> +#include <pthread.h> +#include <sys/types.h> +#include <sys/mman.h> + +#include "../../../../include/uapi/linux/dma-buf-test.h" + +#define DMA_BUF_DEV "/dev/dmabuf" + +/* Global variables */ +int thread_count = 100; +int iterations = 10; +int dmabuf_fd; +int verify = 0, buf_sync = 0; +void *vaddr; +int buf_size = 4 * 1024; +pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + +struct dmabuf_sync_thread_data { + pthread_t thread; + int thread_no; +}; + +static int check_results() +{ + int i; + + char *data = vaddr; + for (i = 0; i < buf_size; i++) { + if (data[0] != data[i]) + return -1; + } + return 0; +} + +void *dmabuf_sync_thread(void *data) +{ + int i, err_count = 0; + struct dmabuf_sync_thread_data *sync_data = data; + struct flock lock; + + srand(time(0)); + memset(&lock, 0, sizeof(struct flock)); + lock.l_whence = SEEK_CUR; + + for (i = 0; i < iterations; i++) { + char val = rand() % 256; + + if (buf_sync) { + if (val % 2 == 0) + lock.l_type = F_RDLCK; + else + lock.l_type = F_WRLCK; + if (fcntl(dmabuf_fd, F_SETLKW, &lock) == -1) { + perror("Cannot set lock"); + return NULL; + } + } + + if (val % 2 != 0) + memset(vaddr, val, buf_size); + + if (verify && (val % 2 != 0) && check_results()) + err_count++; + + if (buf_sync) { + lock.l_type = F_UNLCK; + if (fcntl(dmabuf_fd, F_SETLKW, &lock) == -1) { + perror("Cannot set unlock"); + return NULL; + } + } + } + + printf("thread:%d error_count:%d\n", sync_data->thread_no, err_count); + + return NULL; +} + +static void usage(char *name) +{ + fprintf(stderr, "usage: %s [-s]\n", name); + fprintf(stderr, "-t N : the number of threads\n"); + fprintf(stderr, "-v : verification results\n"); + fprintf(stderr, "-b : use buf-sync\n"); + fprintf(stderr, "-s : size of buffer\n"); + exit(0); +} + +extern char *optarg; +static const char optstr[] = "t:vbsh"; + +int main(int argc, char **argv) +{ + int fd, c, err = 0; + int i; + struct dmabuf_create buf; + struct dmabuf_sync_thread_data *data; + + while ((c = getopt(argc, argv, optstr)) != -1) { + switch (c) { + case 't': + if (sscanf(optarg, "%d", &thread_count) != 1) + usage(argv[0]); + break; + case 'v': + verify = 1; + break; + case 'b': + buf_sync = 1; + break; + case 's': + if (sscanf(optarg, "%d", &buf_size) != 1) + usage(argv[0]); + break; + case 'h': + usage(argv[0]); + return 0; + } + } + + fd = open(DMA_BUF_DEV, O_RDWR); + if (fd < 0) { + perror("cannot open device\n"); + return -1; + } + + buf.flags = 0; + buf.size = buf_size; + + err = ioctl(fd, DMABUF_IOCTL_CREATE, &buf); + if (err < 0) { + perror("ioctl DMABUF_IOCTL_CREATE error\n"); + goto err_ioctl; + } + + err = ioctl(fd, DMABUF_IOCTL_EXPORT, &buf); + if (err < 0) { + perror("ioctl DMABUF_IOCTL_EXPORT error\n"); + goto err_alloc; + } + + dmabuf_fd = buf.fd; + + vaddr = mmap(NULL, buf.size, PROT_READ | PROT_WRITE, MAP_PRIVATE, + dmabuf_fd, 0); + if (vaddr == MAP_FAILED) { + perror("mmap error\n"); + goto err_alloc; + } + + data = malloc(sizeof(struct dmabuf_sync_thread_data) * thread_count); + if (!data) { + perror("cannot allocate memory\n"); + close(fd); + return -1; + } + + for (i = 0; i < thread_count; i++) { + data[i].thread_no = i; + pthread_create(&data[i].thread, NULL, dmabuf_sync_thread, + &data[i]); + } + + for (i = 0; i < thread_count; i++) { + void *val; + pthread_join(data[i].thread, &val); + } + +err_alloc: + ioctl(fd, DMABUF_IOCTL_DELETE, &buf); + +err_ioctl: + close(fd); + + return err; +} |