diff mbox

[RFC,v1,1/9] selftest: sync: basic tests for sw_sync framework

Message ID 1457537342-678-2-git-send-email-emilio.lopez@collabora.co.uk (mailing list archive)
State New, archived
Headers show

Commit Message

Emilio López March 9, 2016, 3:28 p.m. UTC
These tests are based on the libsync test suite from Android.
This commit lays the ground for future tests, as well as includes
tests for a variety of basic allocation commands.

Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
Signed-off-by: Emilio López <emilio.lopez@collabora.co.uk>
---

 tools/testing/selftests/Makefile          |   1 +
 tools/testing/selftests/sync/.gitignore   |   1 +
 tools/testing/selftests/sync/Makefile     |  21 ++++
 tools/testing/selftests/sync/sw_sync.h    |  46 +++++++
 tools/testing/selftests/sync/sync.c       | 203 ++++++++++++++++++++++++++++++
 tools/testing/selftests/sync/sync.h       | 119 ++++++++++++++++++
 tools/testing/selftests/sync/sync_alloc.c |  74 +++++++++++
 tools/testing/selftests/sync/sync_test.c  |  71 +++++++++++
 tools/testing/selftests/sync/synctest.h   |  47 +++++++
 9 files changed, 583 insertions(+)
 create mode 100644 tools/testing/selftests/sync/.gitignore
 create mode 100644 tools/testing/selftests/sync/Makefile
 create mode 100644 tools/testing/selftests/sync/sw_sync.h
 create mode 100644 tools/testing/selftests/sync/sync.c
 create mode 100644 tools/testing/selftests/sync/sync.h
 create mode 100644 tools/testing/selftests/sync/sync_alloc.c
 create mode 100644 tools/testing/selftests/sync/sync_test.c
 create mode 100644 tools/testing/selftests/sync/synctest.h

Comments

Emil Velikov March 28, 2016, 11:56 a.m. UTC | #1
Hi Emilio,

On 9 March 2016 at 15:28, Emilio López <emilio.lopez@collabora.co.uk> wrote:
> These tests are based on the libsync test suite from Android.
> This commit lays the ground for future tests, as well as includes
> tests for a variety of basic allocation commands.
>
> Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
> Signed-off-by: Emilio López <emilio.lopez@collabora.co.uk>
> ---
>

>  tools/testing/selftests/sync/sync.h       | 119 ++++++++++++++++++
Admittedly I know nothing about the kernel selftests although copying
the UAPI header, seems to defeat the purpose of this exercise.
Shouldn't one reuse the existing header ? It would even cause issues
as the interface gets updated (iirc Gustavo changed the ioctl numbers
and/or header name with latter series).

Regards,
Emil
Emilio López March 28, 2016, 12:20 p.m. UTC | #2
Hi,

El 28/03/16 a las 08:56, Emil Velikov escribió:
> Hi Emilio,
>
> On 9 March 2016 at 15:28, Emilio López <emilio.lopez@collabora.co.uk> wrote:
>> These tests are based on the libsync test suite from Android.
>> This commit lays the ground for future tests, as well as includes
>> tests for a variety of basic allocation commands.
>>
>> Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
>> Signed-off-by: Emilio López <emilio.lopez@collabora.co.uk>
>> ---
>>
>
>>   tools/testing/selftests/sync/sync.h       | 119 ++++++++++++++++++
> Admittedly I know nothing about the kernel selftests although copying
> the UAPI header, seems to defeat the purpose of this exercise.
> Shouldn't one reuse the existing header ? It would even cause issues
> as the interface gets updated (iirc Gustavo changed the ioctl numbers
> and/or header name with latter series).

The problem is that one cannot use the system header without having 
built and installed the kernel first, which is rather problematic for 
eg. crosscompiling or virtualization. I discussed this with Gustavo and 
we agreed that the best way forward would be to copy the interfaces, as 
suggested by kernelnewbies' wiki[0]:

"""
The correct way to address this problem is to isolate the specific 
interfaces that you need, e.g. a single header file that is patched in a 
new kernel providing the ioctl numbers for a character device used by 
your program. In your own program, add a copy of that source file, with 
a notice that it should be kept in sync with new kernel versions.
"""

Cheers,
Emilio

[0] http://kernelnewbies.org/KernelHeaders
Emil Velikov March 28, 2016, 1:48 p.m. UTC | #3
On 28 March 2016 at 13:20, Emilio López <emilio.lopez@collabora.co.uk> wrote:
> Hi,
>
> El 28/03/16 a las 08:56, Emil Velikov escribió:
>>
>> Hi Emilio,
>>
>> On 9 March 2016 at 15:28, Emilio López <emilio.lopez@collabora.co.uk>
>> wrote:
>>>
>>> These tests are based on the libsync test suite from Android.
>>> This commit lays the ground for future tests, as well as includes
>>> tests for a variety of basic allocation commands.
>>>
>>> Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
>>> Signed-off-by: Emilio López <emilio.lopez@collabora.co.uk>
>>> ---
>>>
>>
>>>   tools/testing/selftests/sync/sync.h       | 119 ++++++++++++++++++
>>
>> Admittedly I know nothing about the kernel selftests although copying
>> the UAPI header, seems to defeat the purpose of this exercise.
>> Shouldn't one reuse the existing header ? It would even cause issues
>> as the interface gets updated (iirc Gustavo changed the ioctl numbers
>> and/or header name with latter series).
>
>
> The problem is that one cannot use the system header without having built
> and installed the kernel first, which is rather problematic for eg.
> crosscompiling or virtualization. I discussed this with Gustavo and we
> agreed that the best way forward would be to copy the interfaces, as
> suggested by kernelnewbies' wiki[0]:
>
In the case of using a system header one can just `make
headers_install' without building the kernel, as mentioned in the very
same page ;-) Although I wasn't thinking that one should be using the
header already available in tree. After all this series is not
supposed to land before Gustavo's work, is it ?

From a quick skim though the selftests, I cannot see cases where UAPI
headers are copied/duplicated.

> """
> The correct way to address this problem is to isolate the specific
> interfaces that you need, e.g. a single header file that is patched in a new
> kernel providing the ioctl numbers for a character device used by your
> program. In your own program, add a copy of that source file, with a notice
> that it should be kept in sync with new kernel versions.
> """
My understanding of the article is that it refers to building user
space programs that do _not_ live in the same tree as the kernel. Am I
missing something ?

Regards,
Emil
Emil Velikov April 7, 2016, 2:47 p.m. UTC | #4
On 4 April 2016 at 05:12, Emilio López <emilio.lopez@collabora.co.uk> wrote:
> Hi,
>
> El 28/03/16 a las 10:48, Emil Velikov escribió:
>
>>>>> These tests are based on the libsync test suite from Android.
>>>>> This commit lays the ground for future tests, as well as includes
>>>>> tests for a variety of basic allocation commands.
>>>>>
>>>>> Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
>>>>> Signed-off-by: Emilio López <emilio.lopez@collabora.co.uk>
>>>>> ---
>>>>>
>>>>
>>>>>    tools/testing/selftests/sync/sync.h       | 119 ++++++++++++++++++
>>>>
>>>>
>>>> Admittedly I know nothing about the kernel selftests although copying
>>>> the UAPI header, seems to defeat the purpose of this exercise.
>>>> Shouldn't one reuse the existing header ? It would even cause issues
>>>> as the interface gets updated (iirc Gustavo changed the ioctl numbers
>>>> and/or header name with latter series).
>>>
>>>
>>>
>>> The problem is that one cannot use the system header without having built
>>> and installed the kernel first, which is rather problematic for eg.
>>> crosscompiling or virtualization. I discussed this with Gustavo and we
>>> agreed that the best way forward would be to copy the interfaces, as
>>> suggested by kernelnewbies' wiki[0]:
>>>
>> In the case of using a system header one can just `make
>> headers_install' without building the kernel, as mentioned in the very
>> same page ;-) Although I wasn't thinking that one should be using the
>> header already available in tree. After all this series is not
>> supposed to land before Gustavo's work, is it ?
>>
>>  From a quick skim though the selftests, I cannot see cases where UAPI
>> headers are copied/duplicated.
>>
>>> """
>>> The correct way to address this problem is to isolate the specific
>>> interfaces that you need, e.g. a single header file that is patched in a
>>> new
>>> kernel providing the ioctl numbers for a character device used by your
>>> program. In your own program, add a copy of that source file, with a
>>> notice
>>> that it should be kept in sync with new kernel versions.
>>> """
>>
>> My understanding of the article is that it refers to building user
>> space programs that do _not_ live in the same tree as the kernel. Am I
>> missing something ?
>
>
> When I tried using the header directly from the kernel tree, the compiler
> told me not to do that and pointed me to that kernelnewbies page; I could
> try overriding the check like I see memfd does[0] but I don't know if that's
> the way to go. Shuah, what's your thoughts on this?
>
Afaics the warning comes up, as the uapi header gets picked up prior
to the normal one (in include/).

Thus by reordering the includes things should work. One could even do
a similar thing for memfd and drop the hack(?). Then again, not sure
what's the policy on any of this is. I'm thinking that it should be
documented somewhere, but I could not find anything :-\

Regards,
Emil
diff mbox

Patch

diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile
index b04afc3..35ed218 100644
--- a/tools/testing/selftests/Makefile
+++ b/tools/testing/selftests/Makefile
@@ -21,6 +21,7 @@  TARGETS += ptrace
 TARGETS += seccomp
 TARGETS += size
 TARGETS += static_keys
+TARGETS += sync
 TARGETS += sysctl
 ifneq (1, $(quicktest))
 TARGETS += timers
diff --git a/tools/testing/selftests/sync/.gitignore b/tools/testing/selftests/sync/.gitignore
new file mode 100644
index 0000000..f5091e7
--- /dev/null
+++ b/tools/testing/selftests/sync/.gitignore
@@ -0,0 +1 @@ 
+sync_test
diff --git a/tools/testing/selftests/sync/Makefile b/tools/testing/selftests/sync/Makefile
new file mode 100644
index 0000000..b21382d
--- /dev/null
+++ b/tools/testing/selftests/sync/Makefile
@@ -0,0 +1,21 @@ 
+CC = $(CROSS_COMPILE)gcc
+CFLAGS := -O2 -g -std=gnu89 -pthread -Wall
+CFLAGS += -I../../../../drivers/staging/android/
+LDFLAGS += -pthread
+
+TEST_PROGS = sync_test
+
+all: $(TEST_PROGS)
+
+include ../lib.mk
+
+SRC = sync_test.o sync.o
+
+TESTS += sync_alloc.o
+
+sync_test: $(SRC) $(TESTS)
+
+.PHONY: clean
+
+clean:
+	$(RM) sync_test $(SRC) $(TESTS)
diff --git a/tools/testing/selftests/sync/sw_sync.h b/tools/testing/selftests/sync/sw_sync.h
new file mode 100644
index 0000000..105961a
--- /dev/null
+++ b/tools/testing/selftests/sync/sw_sync.h
@@ -0,0 +1,46 @@ 
+/*
+ *  sw_sync abstraction
+ *
+ *  Copyright 2015-2016 Collabora Ltd.
+ *
+ *  Based on the implementation from the Android Open Source Project,
+ *
+ *  Copyright 2013 Google, Inc
+ *
+ *  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 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
+ *  THE AUTHORS OR COPYRIGHT HOLDERS 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.
+ */
+
+#ifndef _SELFTESTS_SW_SYNC_H
+#define _SELFTESTS_SW_SYNC_H
+
+/*
+ * sw_sync is mainly intended for testing and should not be compiled into
+ * production kernels
+ */
+
+int sw_sync_timeline_create(void);
+int sw_sync_timeline_is_valid(int fd);
+int sw_sync_timeline_inc(int fd, unsigned count);
+void sw_sync_timeline_destroy(int fd);
+
+int sw_sync_fence_create(int fd, const char *name, unsigned value);
+int sw_sync_fence_is_valid(int fd);
+void sw_sync_fence_destroy(int fd);
+
+#endif
diff --git a/tools/testing/selftests/sync/sync.c b/tools/testing/selftests/sync/sync.c
new file mode 100644
index 0000000..99570ab
--- /dev/null
+++ b/tools/testing/selftests/sync/sync.c
@@ -0,0 +1,203 @@ 
+/*
+ *  sync / sw_sync abstraction
+ *  Copyright 2015-2016 Collabora Ltd.
+ *
+ *  Based on the implementation from the Android Open Source Project,
+ *
+ *  Copyright 2012 Google, Inc
+ *
+ *  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 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
+ *  THE AUTHORS OR COPYRIGHT HOLDERS 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.
+ */
+
+#include <fcntl.h>
+#include <malloc.h>
+#include <string.h>
+#include <unistd.h>
+#include <poll.h>
+
+#include <uapi/sync.h>
+#include <uapi/sw_sync.h>
+
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include "sync.h"
+#include "sw_sync.h"
+#include "synctest.h"
+
+int sync_wait(int fd, int timeout)
+{
+	struct pollfd fds;
+
+	fds.fd = fd;
+	fds.events = POLLIN | POLLERR;
+	return poll(&fds, 1, timeout);
+}
+
+int sync_merge(const char *name, int fd1, int fd2)
+{
+	struct sync_merge_data data = {};
+	int err;
+
+	data.fd2 = fd2;
+	strncpy(data.name, name, sizeof(data.name) - 1);
+	data.name[sizeof(data.name) - 1] = '\0';
+
+	err = ioctl(fd1, SYNC_IOC_MERGE, &data);
+	if (err < 0)
+		return err;
+
+	return data.fence;
+}
+
+static struct sync_file_info *sync_file_info(int fd)
+{
+	struct sync_file_info *info;
+	int err, num_fences;
+
+	info = malloc(sizeof(*info));
+	if (info == NULL)
+		return NULL;
+
+	memset(info, 0, sizeof(*info));
+	err = ioctl(fd, SYNC_IOC_FILE_INFO, info);
+	if (err < 0) {
+		free(info);
+		return NULL;
+	}
+
+	num_fences = info->num_fences;
+
+	if (num_fences) {
+		info->flags = 0;
+		info->num_fences = num_fences;
+		info->sync_fence_info = (uint64_t) calloc(num_fences,
+					sizeof(struct sync_fence_info));
+		if ((void *)info->sync_fence_info == NULL)
+			return NULL;
+
+		err = ioctl(fd, SYNC_IOC_FILE_INFO, info);
+		if (err < 0) {
+			free((void *)info->sync_fence_info);
+			free(info);
+			return NULL;
+		}
+	}
+
+	return info;
+}
+
+static void sync_file_info_free(struct sync_file_info *info)
+{
+	free((void *)info->sync_fence_info);
+	free(info);
+}
+
+int sync_fence_size(int fd)
+{
+	int count;
+	struct sync_file_info *info = sync_file_info(fd);
+
+	if (!info)
+		return 0;
+
+	count = info->num_fences;
+
+	sync_file_info_free(info);
+
+	return count;
+}
+
+
+int sync_fence_count_with_status(int fd, int status)
+{
+	int i, count = 0;
+	struct sync_fence_info *fenceInfo = NULL;
+	struct sync_file_info *info = sync_file_info(fd);
+
+	if (!info)
+		return -1;
+
+	fenceInfo = (struct sync_fence_info *)info->sync_fence_info;
+	for (i = 0 ; i < info->num_fences ; i++) {
+		if (fenceInfo[i].status == status)
+			count++;
+	}
+
+	sync_file_info_free(info);
+
+	return count;
+}
+
+int sw_sync_timeline_create(void)
+{
+	return open("/sys/kernel/debug/sync/sw_sync", O_RDWR);
+}
+
+int sw_sync_timeline_inc(int fd, unsigned count)
+{
+	__u32 arg = count;
+
+	return ioctl(fd, SW_SYNC_IOC_INC, &arg);
+}
+
+int sw_sync_timeline_is_valid(int fd)
+{
+	int status;
+
+	if (fd == -1)
+		return 0;
+
+	status = fcntl(fd, F_GETFD, 0);
+	return (status >= 0);
+}
+
+void sw_sync_timeline_destroy(int fd)
+{
+	if (fd != -1)
+		close(fd);
+}
+
+int sw_sync_fence_create(int fd, const char *name, unsigned value)
+{
+	struct sw_sync_create_fence_data data = {};
+	int err;
+
+	data.value = value;
+	strncpy(data.name, name, sizeof(data.name) - 1);
+	data.name[sizeof(data.name) - 1] = '\0';
+
+	err = ioctl(fd, SW_SYNC_IOC_CREATE_FENCE, &data);
+	if (err < 0)
+		return err;
+
+	return data.fence;
+}
+
+int sw_sync_fence_is_valid(int fd)
+{
+	/* Same code! */
+	return sw_sync_timeline_is_valid(fd);
+}
+
+void sw_sync_fence_destroy(int fd)
+{
+	if (sw_sync_fence_is_valid(fd))
+		close(fd);
+}
diff --git a/tools/testing/selftests/sync/sync.h b/tools/testing/selftests/sync/sync.h
new file mode 100644
index 0000000..9370fa3
--- /dev/null
+++ b/tools/testing/selftests/sync/sync.h
@@ -0,0 +1,119 @@ 
+/*
+ *  sync abstraction
+ *  Copyright 2015-2016 Collabora Ltd.
+ *
+ *  Based on the implementation from the Android Open Source Project,
+ *
+ *  Copyright 2012 Google, Inc
+ *
+ *  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 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
+ *  THE AUTHORS OR COPYRIGHT HOLDERS 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.
+ */
+
+#ifndef _SELFTESTS_SYNC_H
+#define _SELFTESTS_SYNC_H
+
+#include <stdint.h>
+#include <sys/ioctl.h>
+
+#define FENCE_STATUS_ERROR	(-1)
+#define FENCE_STATUS_ACTIVE	(0)
+#define FENCE_STATUS_SIGNALED	(1)
+
+struct sync_merge_data {
+	char	name[32];
+	int32_t	fd2;
+	int32_t	fence;
+	uint32_t	flags;
+	uint32_t	pad;
+};
+
+/**
+ * struct sync_fence_info - detailed fence information
+ * @obj_name:		name of parent sync_timeline
+ * @driver_name:	name of driver implementing the parent
+ * @status:		status of the fence 0:active 1:signaled <0:error
+ * @flags:		fence_info flags
+ * @timestamp_ns:	timestamp of status change in nanoseconds
+ */
+struct sync_fence_info {
+	char	obj_name[32];
+	char	driver_name[32];
+	int32_t	status;
+	uint32_t	flags;
+	uint64_t	timestamp_ns;
+};
+
+/**
+ * struct sync_file_info - data returned from fence info ioctl
+ * @name:	name of fence
+ * @status:	status of fence. 1: signaled 0:active <0:error
+ * @flags:	sync_file_info flags
+ * @num_fences	number of fences in the sync_file
+ * @pad:	padding for 64-bit alignment, should always be zero
+ * @sync_fence_info: pointer to array of structs sync_fence_info with all
+ *		 fences in the sync_file
+ */
+struct sync_file_info {
+	char	name[32];
+	int32_t	status;
+	uint32_t	flags;
+	uint32_t	num_fences;
+	uint32_t	pad;
+
+	uint64_t	sync_fence_info;
+};
+
+#define SYNC_IOC_MAGIC		'>'
+
+/**
+ * Opcodes  0, 1 and 2 were burned during a API change to avoid users of the
+ * old API to get weird errors when trying to handling sync_files. The API
+ * change happened during the de-stage of the Sync Framework when there was
+ * no upstream users available.
+ */
+
+/**
+ * DOC: SYNC_IOC_MERGE - merge two fences
+ *
+ * Takes a struct sync_merge_data.  Creates a new fence containing copies of
+ * the sync_pts in both the calling fd and sync_merge_data.fd2.  Returns the
+ * new fence's fd in sync_merge_data.fence
+ */
+#define SYNC_IOC_MERGE		_IOWR(SYNC_IOC_MAGIC, 3, struct sync_merge_data)
+
+/**
+ * DOC: SYNC_IOC_FENCE_INFO - get detailed information on a fence
+ *
+ * Takes a struct sync_file_info_data with extra space allocated for pt_info.
+ * Caller should write the size of the buffer into len.  On return, len is
+ * updated to reflect the total size of the sync_file_info_data including
+ * pt_info.
+ *
+ * pt_info is a buffer containing sync_pt_infos for every sync_pt in the fence.
+ * To iterate over the sync_pt_infos, use the sync_pt_info.len field.
+ */
+#define SYNC_IOC_FILE_INFO	_IOWR(SYNC_IOC_MAGIC, 4, struct sync_file_info)
+
+
+int sync_wait(int fd, int timeout);
+int sync_merge(const char *name, int fd1, int fd2);
+int sync_fence_size(int fd);
+int sync_fence_count_with_status(int fd, int status);
+
+#endif
diff --git a/tools/testing/selftests/sync/sync_alloc.c b/tools/testing/selftests/sync/sync_alloc.c
new file mode 100644
index 0000000..66a28af
--- /dev/null
+++ b/tools/testing/selftests/sync/sync_alloc.c
@@ -0,0 +1,74 @@ 
+/*
+ *  sync allocation tests
+ *  Copyright 2015-2016 Collabora Ltd.
+ *
+ *  Based on the implementation from the Android Open Source Project,
+ *
+ *  Copyright 2012 Google, Inc
+ *
+ *  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 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
+ *  THE AUTHORS OR COPYRIGHT HOLDERS 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.
+ */
+
+#include "sync.h"
+#include "sw_sync.h"
+#include "synctest.h"
+
+int test_alloc_timeline(void)
+{
+	int timeline, valid;
+
+	timeline = sw_sync_timeline_create();
+	valid = sw_sync_timeline_is_valid(timeline);
+	ASSERT(valid, "Failure allocating timeline\n");
+
+	sw_sync_timeline_destroy(timeline);
+	return 0;
+}
+
+int test_alloc_fence(void)
+{
+	int timeline, fence, valid;
+
+	timeline = sw_sync_timeline_create();
+	valid = sw_sync_timeline_is_valid(timeline);
+	ASSERT(valid, "Failure allocating timeline\n");
+
+	fence = sw_sync_fence_create(timeline, "allocFence", 1);
+	valid = sw_sync_fence_is_valid(fence);
+	ASSERT(valid, "Failure allocating fence\n");
+
+	sw_sync_fence_destroy(fence);
+	sw_sync_timeline_destroy(timeline);
+	return 0;
+}
+
+int test_alloc_fence_negative(void)
+{
+	int fence, timeline;
+
+	timeline = sw_sync_timeline_create();
+	ASSERT(timeline > 0, "Failure allocating timeline\n");
+
+	fence = sw_sync_fence_create(-1, "fence", 1);
+	ASSERT(fence < 0, "Success allocating negative fence\n");
+
+	sw_sync_fence_destroy(fence);
+	sw_sync_timeline_destroy(timeline);
+	return 0;
+}
diff --git a/tools/testing/selftests/sync/sync_test.c b/tools/testing/selftests/sync/sync_test.c
new file mode 100644
index 0000000..51efa71
--- /dev/null
+++ b/tools/testing/selftests/sync/sync_test.c
@@ -0,0 +1,71 @@ 
+/*
+ *  sync test runner
+ *  Copyright 2015-2016 Collabora Ltd.
+ *
+ *  Based on the implementation from the Android Open Source Project,
+ *
+ *  Copyright 2012 Google, Inc
+ *
+ *  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 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
+ *  THE AUTHORS OR COPYRIGHT HOLDERS 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.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include "synctest.h"
+
+static int run_test(int (*test)(void), char *name)
+{
+	int result;
+	pid_t childpid;
+
+	fflush(stdout);
+	childpid = fork();
+
+	if (childpid) {
+		waitpid(childpid, &result, 0);
+		if (WIFEXITED(result))
+			return WEXITSTATUS(result);
+		return 1;
+	} else {
+		printf("[RUN]\tExecuting %s\n", name);
+		exit(test());
+	}
+}
+
+int main(void)
+{
+	int err = 0;
+
+	printf("[RUN]\tTesting sync framework\n");
+
+	err += RUN_TEST(test_alloc_timeline);
+	err += RUN_TEST(test_alloc_fence);
+	err += RUN_TEST(test_alloc_fence_negative);
+
+	if (err)
+		printf("[FAIL]\tsync errors: %d\n", err);
+	else
+		printf("[OK]\tsync\n");
+
+	return !!err;
+}
diff --git a/tools/testing/selftests/sync/synctest.h b/tools/testing/selftests/sync/synctest.h
new file mode 100644
index 0000000..edc5a8a
--- /dev/null
+++ b/tools/testing/selftests/sync/synctest.h
@@ -0,0 +1,47 @@ 
+/*
+ *  sync tests
+ *  Copyright 2015-2016 Collabora Ltd.
+ *
+ *  Based on the implementation from the Android Open Source Project,
+ *
+ *  Copyright 2012 Google, Inc
+ *
+ *  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 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
+ *  THE AUTHORS OR COPYRIGHT HOLDERS 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.
+ */
+
+#ifndef _SELFTESTS_SYNCTEST_H
+#define _SELFTESTS_SYNCTEST_H
+
+#include <stdio.h>
+
+#define ASSERT(cond, msg) do { \
+	if (!(cond)) { \
+		printf("[BAD]\t%s", (msg)); \
+		return 1; \
+	} \
+} while (0)
+
+#define RUN_TEST(x) run_test((x), #x)
+
+/* Allocation tests */
+int test_alloc_timeline(void);
+int test_alloc_fence(void);
+int test_alloc_fence_negative(void);
+
+#endif