[RFC][PATCH 3/3] kselftest: Add drm_syncobj API test tool

Christian König christian.koenig at amd.com
Tue Jul 12 07:43:44 UTC 2022


Am 12.07.22 um 06:22 schrieb John Stultz:
> An initial pass at a drm_syncobj API test.
>
> Currently covers trivial use of:
>    DRM_IOCTL_SYNCOBJ_CREATE
>    DRM_IOCTL_SYNCOBJ_DESTROY
>    DRM_IOCTL_SYNCOBJ_HANDLE_TO_FD
>    DRM_IOCTL_SYNCOBJ_FD_TO_HANDLE
>    DRM_IOCTL_SYNCOBJ_WAIT
>    DRM_IOCTL_SYNCOBJ_RESET
>    DRM_IOCTL_SYNCOBJ_SIGNAL
>    DRM_IOCTL_SYNCOBJ_TIMELINE_WAIT
>    DRM_IOCTL_SYNCOBJ_TIMELINE_SIGNAL
>
> And demonstrates how the userspace API can be used, along with
> some fairly simple bad parameter checking.
>
> The patch includes a few helpers taken from libdrm, as at least
> on the VM I was testing with, I didn't have a new enough libdrm
> to support the *_TIMELINE_* ioctls. Ideally the ioctl-helper bits
> can be dropped at a later time.
>
> Feedback would be appreciated!
>
> Cc: Maarten Lankhorst <maarten.lankhorst at linux.intel.com>
> Cc: Maxime Ripard <mripard at kernel.org>
> Cc: Thomas Zimmermann <tzimmermann at suse.de>
> Cc: Jason Ekstrand <jason at jlekstrand.net>
> Cc: Christian König <christian.koenig at amd.com>
> Cc: Lionel Landwerlin <lionel.g.landwerlin at intel.com>
> Cc: Chunming Zhou <david1.zhou at amd.com>
> Cc: David Airlie <airlied at linux.ie>
> Cc: Daniel Vetter <daniel at ffwll.ch>
> Cc: Shuah Khan <shuah at kernel.org>
> Cc: dri-devel at lists.freedesktop.org
> Signed-off-by: John Stultz <jstultz at google.com>
> ---
>   .../drivers/gpu/drm_syncobj/Makefile          |  11 +
>   .../drivers/gpu/drm_syncobj/ioctl-helper.c    |  85 ++++
>   .../drivers/gpu/drm_syncobj/ioctl-helper.h    |  74 ++++
>   .../drivers/gpu/drm_syncobj/syncobj-test.c    | 410 ++++++++++++++++++

DRM userspace selftests usually go either into libdrm or igt and not 
into the kernel source.

If you want to make in kernel self tests they should go into 
drivers/gpu/drm/selftests/

Regards,
Christian.

>   4 files changed, 580 insertions(+)
>   create mode 100644 tools/testing/selftests/drivers/gpu/drm_syncobj/Makefile
>   create mode 100644 tools/testing/selftests/drivers/gpu/drm_syncobj/ioctl-helper.c
>   create mode 100644 tools/testing/selftests/drivers/gpu/drm_syncobj/ioctl-helper.h
>   create mode 100644 tools/testing/selftests/drivers/gpu/drm_syncobj/syncobj-test.c
>
> diff --git a/tools/testing/selftests/drivers/gpu/drm_syncobj/Makefile b/tools/testing/selftests/drivers/gpu/drm_syncobj/Makefile
> new file mode 100644
> index 000000000000..6576d9b2006c
> --- /dev/null
> +++ b/tools/testing/selftests/drivers/gpu/drm_syncobj/Makefile
> @@ -0,0 +1,11 @@
> +# SPDX-License-Identifier: GPL-2.0
> +CFLAGS += -I/usr/include/libdrm/
> +LDFLAGS += -pthread -ldrm
> +
> +TEST_GEN_FILES= syncobj-test
> +
> +include ../../../lib.mk
> +
> +$(OUTPUT)/syncobj-test: syncobj-test.c ioctl-helper.c
> +EXTRA_CLEAN = $(OUTPUT)/ioctl-helper.o
> +
> diff --git a/tools/testing/selftests/drivers/gpu/drm_syncobj/ioctl-helper.c b/tools/testing/selftests/drivers/gpu/drm_syncobj/ioctl-helper.c
> new file mode 100644
> index 000000000000..e5c59c9bed36
> --- /dev/null
> +++ b/tools/testing/selftests/drivers/gpu/drm_syncobj/ioctl-helper.c
> @@ -0,0 +1,85 @@
> +// SPDX-License-Identifier: MIT
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <stdint.h>
> +#include <string.h>
> +#include <unistd.h>
> +#include <time.h>
> +#include <errno.h>
> +#include <libdrm/drm.h>
> +#include <xf86drm.h>
> +#include "ioctl-helper.h"
> +
> +#ifndef DRM_CAP_SYNCOBJ_TIMELINE
> +/*
> + * The following is nabbed from libdrm's xf86drm.c as the
> + * installed libdrm doesn't yet include these definitions
> + *
> + *
> + * \author Rickard E. (Rik) Faith <faith at valinux.com>
> + * \author Kevin E. Martin <martin at valinux.com>
> + */
> +/*
> + * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
> + * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
> + * All Rights Reserved.
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> + * copy of this software and associated documentation files (the "Software"),
> + * to deal in the Software without restriction, including without limitation
> + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> + * and/or sell copies of the Software, and to permit persons to whom the
> + * Software is furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice (including the next
> + * paragraph) shall be included in all copies or substantial portions of the
> + * Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
> + * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
> + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
> + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
> + * DEALINGS IN THE SOFTWARE.
> + */
> +int drmSyncobjTimelineSignal(int fd, const uint32_t *handles,
> +			     uint64_t *points, uint32_t handle_count)
> +{
> +	struct drm_syncobj_timeline_array args;
> +	int ret;
> +
> +	memset(&args, 0, sizeof(args));
> +	args.handles = (uintptr_t)handles;
> +	args.points = (uintptr_t)points;
> +	args.count_handles = handle_count;
> +
> +	ret = drmIoctl(fd, DRM_IOCTL_SYNCOBJ_TIMELINE_SIGNAL, &args);
> +	return ret;
> +}
> +
> +int drmSyncobjTimelineWait(int fd, uint32_t *handles, uint64_t *points,
> +			   unsigned int num_handles,
> +			   int64_t timeout_nsec, unsigned int flags,
> +			   uint32_t *first_signaled)
> +{
> +	struct drm_syncobj_timeline_wait args;
> +	int ret;
> +
> +	memset(&args, 0, sizeof(args));
> +	args.handles = (uintptr_t)handles;
> +	args.points = (uintptr_t)points;
> +	args.timeout_nsec = timeout_nsec;
> +	args.count_handles = num_handles;
> +	args.flags = flags;
> +
> +	ret = drmIoctl(fd, DRM_IOCTL_SYNCOBJ_TIMELINE_WAIT, &args);
> +	if (ret < 0)
> +		return -errno;
> +
> +	if (first_signaled)
> +		*first_signaled = args.first_signaled;
> +	return ret;
> +}
> +
> +#endif
> diff --git a/tools/testing/selftests/drivers/gpu/drm_syncobj/ioctl-helper.h b/tools/testing/selftests/drivers/gpu/drm_syncobj/ioctl-helper.h
> new file mode 100644
> index 000000000000..b0c1025034b5
> --- /dev/null
> +++ b/tools/testing/selftests/drivers/gpu/drm_syncobj/ioctl-helper.h
> @@ -0,0 +1,74 @@
> +/* SPDX-License-Identifier: MIT */
> +#ifndef __IOCTL_HELPER_H__
> +#define __IOCTL_HELPER_H__
> +
> +/* Bits pulled from libdrm's include/drm/drm.h */
> +#ifndef DRM_CAP_SYNCOBJ_TIMELINE
> +/*
> + * Header for the Direct Rendering Manager
> + *
> + * Author: Rickard E. (Rik) Faith <faith at valinux.com>
> + *
> + * Acknowledgments:
> + * Dec 1999, Richard Henderson <rth at twiddle.net>, move to generic cmpxchg.
> + */
> +
> +/*
> + * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
> + * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
> + * All rights reserved.
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> + * copy of this software and associated documentation files (the "Software"),
> + * to deal in the Software without restriction, including without limitation
> + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> + * and/or sell copies of the Software, and to permit persons to whom the
> + * Software is furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice (including the next
> + * paragraph) shall be included in all copies or substantial portions of the
> + * Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
> + * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
> + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
> + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
> + * OTHER DEALINGS IN THE SOFTWARE.
> + */
> +struct drm_syncobj_timeline_wait {
> +	__u64 handles;
> +	/* wait on specific timeline point for every handles*/
> +	__u64 points;
> +	/* absolute timeout */
> +	__s64 timeout_nsec;
> +	__u32 count_handles;
> +	__u32 flags;
> +	__u32 first_signaled; /* only valid when not waiting all */
> +	__u32 pad;
> +};
> +
> +
> +#define DRM_SYNCOBJ_QUERY_FLAGS_LAST_SUBMITTED (1 << 0)
> +struct drm_syncobj_timeline_array {
> +	__u64 handles;
> +	__u64 points;
> +	__u32 count_handles;
> +	__u32 flags;
> +};
> +
> +#define DRM_IOCTL_SYNCOBJ_TIMELINE_WAIT DRM_IOWR(0xCA, struct drm_syncobj_timeline_wait)
> +#define DRM_IOCTL_SYNCOBJ_QUERY         DRM_IOWR(0xCB, struct drm_syncobj_timeline_array)
> +#define DRM_IOCTL_SYNCOBJ_TRANSFER      DRM_IOWR(0xCC, struct drm_syncobj_transfer)
> +#define DRM_IOCTL_SYNCOBJ_TIMELINE_SIGNAL       DRM_IOWR(0xCD, struct drm_syncobj_timeline_array)
> +
> +int drmSyncobjTimelineSignal(int fd, const uint32_t *handles,
> +			     uint64_t *points, uint32_t handle_count);
> +int drmSyncobjTimelineWait(int fd, uint32_t *handles, uint64_t *points,
> +			   unsigned int num_handles,
> +			   int64_t timeout_nsec, unsigned int flags,
> +			   uint32_t *first_signaled);
> +#endif
> +#endif /*__IOCTL_HELPER_H__*/
> +
> diff --git a/tools/testing/selftests/drivers/gpu/drm_syncobj/syncobj-test.c b/tools/testing/selftests/drivers/gpu/drm_syncobj/syncobj-test.c
> new file mode 100644
> index 000000000000..21474b0d3b9e
> --- /dev/null
> +++ b/tools/testing/selftests/drivers/gpu/drm_syncobj/syncobj-test.c
> @@ -0,0 +1,410 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * This test exercises basic syncobj ioctl interfaces from
> + * userland via the libdrm helpers.
> + *
> + * Copyright (C) 2022, Google LLC.
> + *
> + * Currently covers trivial use of:
> + *   DRM_IOCTL_SYNCOBJ_CREATE
> + *   DRM_IOCTL_SYNCOBJ_DESTROY
> + *   DRM_IOCTL_SYNCOBJ_HANDLE_TO_FD
> + *   DRM_IOCTL_SYNCOBJ_FD_TO_HANDLE
> + *   DRM_IOCTL_SYNCOBJ_WAIT
> + *   DRM_IOCTL_SYNCOBJ_RESET
> + *   DRM_IOCTL_SYNCOBJ_SIGNAL
> + *   DRM_IOCTL_SYNCOBJ_TIMELINE_WAIT
> + *   DRM_IOCTL_SYNCOBJ_TIMELINE_SIGNAL
> + *
> + * TODO: Need coverage for the following ioctls:
> + *   DRM_IOCTL_SYNCOBJ_QUERY
> + *   DRM_IOCTL_SYNCOBJ_TRANSFER
> + * As well as more complicated use of interface (like
> + * signal/wait with multiple handles, etc), and sync_file
> + * import/export.
> + */
> +#include <dirent.h>
> +#include <errno.h>
> +#include <fcntl.h>
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <stdint.h>
> +#include <string.h>
> +#include <unistd.h>
> +#include <time.h>
> +#include <poll.h>
> +#include <sys/ioctl.h>
> +#include <sys/mman.h>
> +#include <sys/types.h>
> +#include <sys/wait.h>
> +#include <pthread.h>
> +#include <linux/dma-buf.h>
> +#include <libdrm/drm.h>
> +#include <xf86drm.h>
> +
> +#include "ioctl-helper.h"
> +
> +
> +#define NSEC_PER_SEC 1000000000ULL
> +static uint64_t get_abs_timeout(uint64_t rel_nsec)
> +{
> +	struct timespec ts;
> +	uint64_t ns;
> +
> +	clock_gettime(CLOCK_MONOTONIC, &ts);
> +	ns = ts.tv_sec * NSEC_PER_SEC + ts.tv_nsec;
> +	ns += rel_nsec;
> +	return ns;
> +}
> +
> +struct test_arg {
> +	int	dev_fd;
> +	uint32_t handle;
> +	int	handle_fd;
> +};
> +#define TEST_TIMES 5
> +
> +void *syncobj_signal_reset(void *arg)
> +{
> +	struct test_arg *d = (struct test_arg *)arg;
> +	int ret;
> +	int i;
> +
> +	for (i = 0; i < TEST_TIMES; i++) {
> +		sleep(3);
> +		printf("%s: sending signal!\n", __func__);
> +		ret = drmSyncobjSignal(d->dev_fd, &d->handle, 1);
> +		if (ret)
> +			printf("Signal failed %i\n", ret);
> +	}
> +	return NULL;
> +}
> +
> +static int syncobj_wait_reset(struct test_arg *d)
> +{
> +	uint64_t abs_timeout;
> +	int ret;
> +	int i;
> +
> +	for (i = 0; i < TEST_TIMES; i++) {
> +		abs_timeout = get_abs_timeout(10*NSEC_PER_SEC);
> +		printf("%s calling drmSyncobjWait\n", __func__);
> +		ret = drmSyncobjWait(d->dev_fd, &d->handle, 1, abs_timeout,
> +				     DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT,
> +				     NULL);
> +		if (ret) {
> +			printf("Error: syncobjwait failed %i\n", ret);
> +			break;
> +		}
> +		printf("%s: drmSyncobjWait returned!\n", __func__);
> +
> +		ret = drmSyncobjReset(d->dev_fd, &d->handle, 1);
> +		if (ret) {
> +			printf("Error: syncobjreset failed\n");
> +			break;
> +		}
> +	}
> +	return ret;
> +}
> +
> +void *syncobj_signal_timeline(void *arg)
> +{
> +	struct test_arg *d = (struct test_arg *)arg;
> +	uint64_t point = 0;
> +	int ret;
> +
> +	for (point = 0; point <= (TEST_TIMES-1)*5; point++) {
> +		sleep(1);
> +		printf("%s: sending signal %lld!\n", __func__, point);
> +		ret = drmSyncobjTimelineSignal(d->dev_fd, &d->handle, &point, 1);
> +		if (ret)
> +			printf("Signal failed %i\n", ret);
> +	}
> +	return NULL;
> +}
> +
> +
> +int syncobj_timeline_wait(struct test_arg *d)
> +{
> +	uint64_t abs_timeout;
> +	uint64_t point;
> +	int ret;
> +	int i;
> +
> +	for (i = 0; i < TEST_TIMES; i++) {
> +		abs_timeout = get_abs_timeout(10*NSEC_PER_SEC);
> +
> +		point = i * 5;
> +		printf("%s: drmSyncobjTimelineWait waiting on %lld!\n", __func__, point);
> +		ret = drmSyncobjTimelineWait(d->dev_fd, &d->handle, &point, 1,
> +					     abs_timeout,
> +					     DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT,
> +					     NULL);
> +		if (ret) {
> +			printf("Error: syncobjwait failed %i\n", ret);
> +			return ret;
> +		}
> +		printf("%s: drmSyncobjTimelineWait got %lld!\n", __func__, point);
> +	}
> +	return 0;
> +}
> +
> +
> +static int test_thread_signal_wait(int devfd, void *(*signal_fn)(void *),
> +				   int (*wait_fn)(struct test_arg *))
> +{
> +	uint32_t handle;
> +	struct test_arg d;
> +	pthread_t pth;
> +	int ret;
> +
> +	ret = drmSyncobjCreate(devfd, 0, &handle);
> +	if (ret) {
> +		printf("Error: Couldn't create syncobj\n");
> +		return ret;
> +	}
> +
> +	d.dev_fd = devfd;
> +	d.handle = handle;
> +
> +	pthread_create(&pth, 0, signal_fn, &d);
> +	ret = wait_fn(&d);
> +	pthread_join(pth, NULL);
> +	drmSyncobjDestroy(devfd, handle);
> +
> +	return ret;
> +}
> +
> +static int test_fork_signal_wait(int devfd, void *(*signal_fn)(void *),
> +				 int (*wait_fn)(struct test_arg *))
> +{
> +	uint32_t handle;
> +	struct test_arg p, c;
> +	pid_t id;
> +	int ret;
> +
> +	ret = drmSyncobjCreate(devfd, 0, &handle);
> +	if (ret) {
> +		printf("Error: Couldn't create syncobj\n");
> +		return ret;
> +	}
> +
> +	p.dev_fd = devfd;
> +	p.handle = 0;
> +	p.handle_fd = 0;
> +	c = p;
> +	p.handle = handle;
> +
> +	ret = drmSyncobjHandleToFD(devfd, handle, &c.handle_fd);
> +	if (ret) {
> +		printf("Error: Couldn't convert handle to fd\n");
> +		goto out;
> +	}
> +
> +	id = fork();
> +	if (id == 0) {
> +		ret = drmSyncobjFDToHandle(c.dev_fd, c.handle_fd, &c.handle);
> +		if (ret) {
> +			printf("Error: Couldn't convert fd to handle\n");
> +			exit(-1);
> +		}
> +		close(c.handle_fd);
> +		signal_fn((void *)&c);
> +		exit(0);
> +	} else {
> +		ret = wait_fn(&p);
> +		waitpid(id, 0, 0);
> +	}
> +
> +out:
> +	if (c.handle_fd)
> +		close(c.handle_fd);
> +	drmSyncobjDestroy(devfd, handle);
> +
> +	return ret;
> +}
> +
> +
> +static int test_badparameters(int devfd)
> +{
> +	uint32_t handle1, handle2;
> +	int ret, fail = 0;
> +
> +	/* create bad fd */
> +	ret = drmSyncobjCreate(-1, 0, &handle1);
> +	if (!ret || errno != EBADF) {
> +		printf("drmSyncobjCreate - bad fd fails! (%i != EBADF)\n", errno);
> +		fail = 1;
> +	}
> +	/* destroy bad fd */
> +	ret = drmSyncobjDestroy(-1, handle1);
> +	if (!ret || errno != EBADF) {
> +		printf("drmSyncobjDestroy - bad fd fails! (%i != EBADF)\n", errno);
> +		fail = 1;
> +	}
> +
> +	/* TODO: Bad flags */
> +
> +	ret = drmSyncobjCreate(devfd, 0,  &handle1);
> +	if (ret) {
> +		printf("drmSyncobjCreate - unexpected failure!\n");
> +		fail = 1;
> +	}
> +
> +	/* Destroy zeroed handle */
> +	handle2 = 0;
> +	ret = drmSyncobjDestroy(devfd, handle2);
> +	if (!ret || errno != EINVAL) {
> +		printf("drmSyncobjDestroy - zero'ed handle! (%i != EINVAL)\n", errno);
> +		fail = 1;
> +	}
> +	/* Destroy invalid handle */
> +	handle2 = -1;
> +	ret = drmSyncobjDestroy(devfd, handle2);
> +	if (!ret || errno != EINVAL) {
> +		printf("drmSyncobjDestroy - invalid handle! (%i != EINVAL)\n", errno);
> +		fail = 1;
> +	}
> +
> +	/* invalid timeouts */
> +	ret = drmSyncobjWait(devfd, &handle1, 1, 1000,
> +			     DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT,
> +			     NULL);
> +	if (!ret || errno != ETIME) {
> +		printf("drmSyncobjWait - invalid timeout (relative)! (%i != ETIME)\n", errno);
> +		fail = 1;
> +	}
> +
> +	ret = drmSyncobjWait(devfd, &handle1, 1, -1,
> +			     DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT,
> +			     NULL);
> +	if (!ret || errno != ETIME) {
> +		printf("drmSyncobjWait - invalid timeout (-1)! (%i != ETIME)\n", errno);
> +		fail = 1;
> +	}
> +
> +	ret = drmSyncobjDestroy(devfd, handle1);
> +	if (ret) {
> +		printf("drmSyncobjDestroy - unexpected failure!\n");
> +		fail = 1;
> +	}
> +
> +
> +	return fail;
> +}
> +
> +
> +#define NAME_LEN 16
> +static int check_device(int fd)
> +{
> +	drm_version_t version = { 0 };
> +	char name[NAME_LEN];
> +	uint32_t handle;
> +	int ret;
> +
> +	memset(name, 0, NAME_LEN);
> +	version.name_len = NAME_LEN;
> +	version.name = name;
> +
> +	ret = ioctl(fd, DRM_IOCTL_VERSION, &version);
> +	if (ret)
> +		return -1;
> +
> +	printf("%s name: %s\n", __func__, name);
> +
> +	ret = drmSyncobjCreate(fd, 0,  &handle);
> +	if (!ret) {
> +		drmSyncobjDestroy(fd, handle);
> +		printf("%s selected: %s\n", __func__, name);
> +	}
> +	return ret;
> +}
> +
> +static int find_device(void)
> +{
> +	int i, fd;
> +	const char *drmstr = "/dev/dri/card";
> +
> +	fd = -1;
> +	for (i = 0; i < 16; i++) {
> +		char name[80];
> +
> +		snprintf(name, 80, "%s%u", drmstr, i);
> +
> +		fd = open(name, O_RDWR);
> +		if (fd < 0)
> +			continue;
> +
> +		if (check_device(fd)) {
> +			close(fd);
> +			fd = -1;
> +			continue;
> +		} else {
> +			break;
> +		}
> +	}
> +	return fd;
> +}
> +
> +int main(int argc, char **argv)
> +{
> +	int devfd = find_device();
> +	char *testname;
> +	int ret;
> +
> +	if (devfd < 0) {
> +		printf("Error: Couldn't find supported drm device\n");
> +		return devfd;
> +	}
> +
> +	testname = "Bad parameters test";
> +	printf("\n%s\n", testname);
> +	printf("===================\n");
> +	ret = test_badparameters(devfd);
> +	if (ret)
> +		printf("%s: FAILED\n", testname);
> +	else
> +		printf("%s: PASSED\n", testname);
> +
> +
> +	testname = "Threaded reset test";
> +	printf("\n%s\n", testname);
> +	printf("===================\n");
> +	ret = test_thread_signal_wait(devfd, &syncobj_signal_reset, &syncobj_wait_reset);
> +	if (ret)
> +		printf("%s: FAILED\n", testname);
> +	else
> +		printf("%s: PASSED\n", testname);
> +
> +	testname = "Threaded timeline test";
> +	printf("\n%s\n", testname);
> +	printf("===================\n");
> +	ret = test_thread_signal_wait(devfd, &syncobj_signal_timeline, &syncobj_timeline_wait);
> +	if (ret)
> +		printf("%s: FAILED\n", testname);
> +	else
> +		printf("%s: PASSED\n", testname);
> +
> +
> +	testname = "Forked reset test";
> +	printf("\n%s\n", testname);
> +	printf("===================\n");
> +	ret = test_fork_signal_wait(devfd, &syncobj_signal_reset, &syncobj_wait_reset);
> +	if (ret)
> +		printf("\n%s: FAILED\n", testname);
> +	else
> +		printf("\n%s: PASSED\n", testname);
> +
> +	testname = "Forked timeline test";
> +	printf("\n%s\n", testname);
> +	printf("===================\n");
> +	ret = test_fork_signal_wait(devfd, &syncobj_signal_timeline, &syncobj_timeline_wait);
> +	if (ret)
> +		printf("\n%s: FAILED\n", testname);
> +	else
> +		printf("\n%s: PASSED\n", testname);
> +
> +
> +	close(devfd);
> +	return 0;
> +}



More information about the dri-devel mailing list