lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <5576E25E.40600@osg.samsung.com>
Date:	Tue, 09 Jun 2015 06:55:58 -0600
From:	Shuah Khan <shuahkh@....samsung.com>
To:	Davidlohr Bueso <dave@...olabs.net>,
	Andrew Morton <akpm@...ux-foundation.org>
CC:	linux-kernel@...r.kernel.org, Shuah Khan <shuahkh@....samsung.com>
Subject: Re: [PATCH -next] selftests/ipc: Consolidate posix and sysv msg queue
 tests

On 06/08/2015 05:51 PM, Davidlohr Bueso wrote:
> Move them both in the their own directory, under selftests/ipc/.
> As with the actual code, all forms of ipc tend to reside in the
> same directory, so apply this to selftests.
> 
> Keep the Makefiles (at least for now), with some minor path
> hierarchy tweaks, for both msg and mqueue. Add a trivial
> ipc/Makefile that simply passes the building to the individual
> subdirectory.
> 
> Signed-off-by: Davidlohr Bueso <dbueso@...e.de>

Looks good in general. Please see comments below.

> ---
>  tools/testing/selftests/ipc/.gitignore             |   3 +
>  tools/testing/selftests/ipc/Makefile               |  32 +-
>  tools/testing/selftests/ipc/mqueue/Makefile        |  22 +
>  tools/testing/selftests/ipc/mqueue/mq_open_tests.c | 500 ++++++++++++++
>  tools/testing/selftests/ipc/mqueue/mq_perf_tests.c | 742 +++++++++++++++++++++
>  tools/testing/selftests/ipc/msg/Makefile           |  22 +
>  tools/testing/selftests/ipc/msg/msgque.c           | 254 +++++++
>  tools/testing/selftests/ipc/msgque.c               | 254 -------
>  tools/testing/selftests/mqueue/.gitignore          |   2 -
>  tools/testing/selftests/mqueue/Makefile            |  22 -
>  tools/testing/selftests/mqueue/mq_open_tests.c     | 500 --------------
>  tools/testing/selftests/mqueue/mq_perf_tests.c     | 742 ---------------------
>  12 files changed, 1559 insertions(+), 1536 deletions(-)
>  create mode 100644 tools/testing/selftests/ipc/.gitignore
>  create mode 100644 tools/testing/selftests/ipc/mqueue/Makefile
>  create mode 100644 tools/testing/selftests/ipc/mqueue/mq_open_tests.c
>  create mode 100644 tools/testing/selftests/ipc/mqueue/mq_perf_tests.c
>  create mode 100644 tools/testing/selftests/ipc/msg/Makefile
>  create mode 100644 tools/testing/selftests/ipc/msg/msgque.c
>  delete mode 100644 tools/testing/selftests/ipc/msgque.c
>  delete mode 100644 tools/testing/selftests/mqueue/.gitignore
>  delete mode 100644 tools/testing/selftests/mqueue/Makefile
>  delete mode 100644 tools/testing/selftests/mqueue/mq_open_tests.c
>  delete mode 100644 tools/testing/selftests/mqueue/mq_perf_tests.c
> 
> diff --git a/tools/testing/selftests/ipc/.gitignore b/tools/testing/selftests/ipc/.gitignore
> new file mode 100644
> index 0000000..3d8a449
> --- /dev/null
> +++ b/tools/testing/selftests/ipc/.gitignore
> @@ -0,0 +1,3 @@
> +mqueue/mq_open_tests
> +mqueue/mq_perf_tests
> +msg/msgque_test
> diff --git a/tools/testing/selftests/ipc/Makefile b/tools/testing/selftests/ipc/Makefile
> index 25d2e70..8686551 100644
> --- a/tools/testing/selftests/ipc/Makefile
> +++ b/tools/testing/selftests/ipc/Makefile
> @@ -1,22 +1,22 @@
> -uname_M := $(shell uname -m 2>/dev/null || echo not)
> -ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/i386/)
> -ifeq ($(ARCH),i386)
> -        ARCH := x86
> -	CFLAGS := -DCONFIG_X86_32 -D__i386__
> -endif
> -ifeq ($(ARCH),x86_64)
> -	ARCH := x86
> -	CFLAGS := -DCONFIG_X86_64 -D__x86_64__
> -endif
> -
> -CFLAGS += -I../../../../usr/include/

Hmm. This looks like more than a moving code and cleanup change.
The above is removing special handling for x86 and x86_64.

I would like to see this as a separate patch and not combined
with the moving code.

> +SUBDIRS := msg
> +SUBDIRS += mqueue
>  
> +.PHONY: all clean
>  all:
> -	$(CC) $(CFLAGS) msgque.c -o msgque_test
> -
> -TEST_PROGS := msgque_test
> +	for DIR in $(SUBDIRS); do $(MAKE) -C $$DIR $@ ; done
>  
>  include ../lib.mk
> +override define RUN_TESTS
> +	for DIR in $(SUBDIRS); do $(MAKE) -C $$DIR $@ ; done
> +endef
> +
> +override define INSTALL_RULE
> +	for DIR in $(SUBDIRS); do $(MAKE) -C $$DIR $@ ; done
> +endef
> +
> +override define EMIT_TESTS
> +	for DIR in $(SUBDIRS); do $(MAKE) -C $$DIR $@ ; done
> +endef
>  
>  clean:
> -	rm -fr ./msgque_test
> +	for DIR in $(SUBDIRS); do $(MAKE) -C $$DIR $@ ; done
> diff --git a/tools/testing/selftests/ipc/mqueue/Makefile b/tools/testing/selftests/ipc/mqueue/Makefile
> new file mode 100644
> index 0000000..1fa56ea
> --- /dev/null
> +++ b/tools/testing/selftests/ipc/mqueue/Makefile
> @@ -0,0 +1,22 @@
> +CFLAGS = -O2
> +
> +all:
> +	$(CC) $(CFLAGS) mq_open_tests.c -o mq_open_tests -lrt
> +	$(CC) $(CFLAGS) -o mq_perf_tests mq_perf_tests.c -lrt -lpthread -lpopt
> +
> +include ../../lib.mk
> +
> +override define RUN_TESTS
> +	@./mq_open_tests /test1 || echo "selftests: mq_open_tests [FAIL]"
> +	@./mq_perf_tests || echo "selftests: mq_perf_tests [FAIL]"
> +endef
> +
> +TEST_PROGS := mq_open_tests mq_perf_tests
> +
> +override define EMIT_TESTS
> +	echo "./mq_open_tests /test1 || echo \"selftests: mq_open_tests [FAIL]\""
> +	echo "./mq_perf_tests || echo \"selftests: mq_perf_tests [FAIL]\""
> +endef
> +
> +clean:
> +	rm -f mq_open_tests mq_perf_tests
> diff --git a/tools/testing/selftests/ipc/mqueue/mq_open_tests.c b/tools/testing/selftests/ipc/mqueue/mq_open_tests.c
> new file mode 100644
> index 0000000..9c1a5d35
> --- /dev/null
> +++ b/tools/testing/selftests/ipc/mqueue/mq_open_tests.c
> @@ -0,0 +1,500 @@
> +/*
> + * This application is Copyright 2012 Red Hat, Inc.
> + *	Doug Ledford <dledford@...hat.com>
> + *
> + * mq_open_tests is free software: you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation, version 3.
> + *
> + * mq_open_tests is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * For the full text of the license, see <http://www.gnu.org/licenses/>.
> + *
> + * mq_open_tests.c
> + *   Tests the various situations that should either succeed or fail to
> + *   open a posix message queue and then reports whether or not they
> + *   did as they were supposed to.
> + *
> + */
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <unistd.h>
> +#include <fcntl.h>
> +#include <string.h>
> +#include <limits.h>
> +#include <errno.h>
> +#include <sys/types.h>
> +#include <sys/time.h>
> +#include <sys/resource.h>
> +#include <sys/stat.h>
> +#include <mqueue.h>
> +
> +static char *usage =
> +"Usage:\n"
> +"  %s path\n"
> +"\n"
> +"	path	Path name of the message queue to create\n"
> +"\n"
> +"	Note: this program must be run as root in order to enable all tests\n"
> +"\n";
> +
> +char *DEF_MSGS = "/proc/sys/fs/mqueue/msg_default";
> +char *DEF_MSGSIZE = "/proc/sys/fs/mqueue/msgsize_default";
> +char *MAX_MSGS = "/proc/sys/fs/mqueue/msg_max";
> +char *MAX_MSGSIZE = "/proc/sys/fs/mqueue/msgsize_max";
> +
> +int default_settings;
> +struct rlimit saved_limits, cur_limits;
> +int saved_def_msgs, saved_def_msgsize, saved_max_msgs, saved_max_msgsize;
> +int cur_def_msgs, cur_def_msgsize, cur_max_msgs, cur_max_msgsize;
> +FILE *def_msgs, *def_msgsize, *max_msgs, *max_msgsize;
> +char *queue_path;
> +mqd_t queue = -1;
> +
> +static inline void __set(FILE *stream, int value, char *err_msg);
> +void shutdown(int exit_val, char *err_cause, int line_no);
> +static inline int get(FILE *stream);
> +static inline void set(FILE *stream, int value);
> +static inline void getr(int type, struct rlimit *rlim);
> +static inline void setr(int type, struct rlimit *rlim);
> +void validate_current_settings();
> +static inline void test_queue(struct mq_attr *attr, struct mq_attr *result);
> +static inline int test_queue_fail(struct mq_attr *attr, struct mq_attr *result);
> +
> +static inline void __set(FILE *stream, int value, char *err_msg)
> +{
> +	rewind(stream);
> +	if (fprintf(stream, "%d", value) < 0)
> +		perror(err_msg);
> +}
> +
> +
> +void shutdown(int exit_val, char *err_cause, int line_no)
> +{
> +	static int in_shutdown = 0;
> +
> +	/* In case we get called recursively by a set() call below */
> +	if (in_shutdown++)
> +		return;
> +
> +	if (seteuid(0) == -1)
> +		perror("seteuid() failed");
> +
> +	if (queue != -1)
> +		if (mq_close(queue))
> +			perror("mq_close() during shutdown");
> +	if (queue_path)
> +		/*
> +		 * Be silent if this fails, if we cleaned up already it's
> +		 * expected to fail
> +		 */
> +		mq_unlink(queue_path);
> +	if (default_settings) {
> +		if (saved_def_msgs)
> +			__set(def_msgs, saved_def_msgs,
> +			      "failed to restore saved_def_msgs");
> +		if (saved_def_msgsize)
> +			__set(def_msgsize, saved_def_msgsize,
> +			      "failed to restore saved_def_msgsize");
> +	}
> +	if (saved_max_msgs)
> +		__set(max_msgs, saved_max_msgs,
> +		      "failed to restore saved_max_msgs");
> +	if (saved_max_msgsize)
> +		__set(max_msgsize, saved_max_msgsize,
> +		      "failed to restore saved_max_msgsize");
> +	if (exit_val)
> +		error(exit_val, errno, "%s at %d", err_cause, line_no);
> +	exit(0);
> +}
> +
> +static inline int get(FILE *stream)
> +{
> +	int value;
> +	rewind(stream);
> +	if (fscanf(stream, "%d", &value) != 1)
> +		shutdown(4, "Error reading /proc entry", __LINE__ - 1);
> +	return value;
> +}
> +
> +static inline void set(FILE *stream, int value)
> +{
> +	int new_value;
> +
> +	rewind(stream);
> +	if (fprintf(stream, "%d", value) < 0)
> +		return shutdown(5, "Failed writing to /proc file",
> +				__LINE__ - 1);
> +	new_value = get(stream);
> +	if (new_value != value)
> +		return shutdown(5, "We didn't get what we wrote to /proc back",
> +				__LINE__ - 1);
> +}
> +
> +static inline void getr(int type, struct rlimit *rlim)
> +{
> +	if (getrlimit(type, rlim))
> +		shutdown(6, "getrlimit()", __LINE__ - 1);
> +}
> +
> +static inline void setr(int type, struct rlimit *rlim)
> +{
> +	if (setrlimit(type, rlim))
> +		shutdown(7, "setrlimit()", __LINE__ - 1);
> +}
> +
> +void validate_current_settings()
> +{
> +	int rlim_needed;
> +
> +	if (cur_limits.rlim_cur < 4096) {
> +		printf("Current rlimit value for POSIX message queue bytes is "
> +		       "unreasonably low,\nincreasing.\n\n");
> +		cur_limits.rlim_cur = 8192;
> +		cur_limits.rlim_max = 16384;
> +		setr(RLIMIT_MSGQUEUE, &cur_limits);
> +	}
> +
> +	if (default_settings) {
> +		rlim_needed = (cur_def_msgs + 1) * (cur_def_msgsize + 1 +
> +						    2 * sizeof(void *));
> +		if (rlim_needed > cur_limits.rlim_cur) {
> +			printf("Temporarily lowering default queue parameters "
> +			       "to something that will work\n"
> +			       "with the current rlimit values.\n\n");
> +			set(def_msgs, 10);
> +			cur_def_msgs = 10;
> +			set(def_msgsize, 128);
> +			cur_def_msgsize = 128;
> +		}
> +	} else {
> +		rlim_needed = (cur_max_msgs + 1) * (cur_max_msgsize + 1 +
> +						    2 * sizeof(void *));
> +		if (rlim_needed > cur_limits.rlim_cur) {
> +			printf("Temporarily lowering maximum queue parameters "
> +			       "to something that will work\n"
> +			       "with the current rlimit values in case this is "
> +			       "a kernel that ties the default\n"
> +			       "queue parameters to the maximum queue "
> +			       "parameters.\n\n");
> +			set(max_msgs, 10);
> +			cur_max_msgs = 10;
> +			set(max_msgsize, 128);
> +			cur_max_msgsize = 128;
> +		}
> +	}
> +}
> +
> +/*
> + * test_queue - Test opening a queue, shutdown if we fail.  This should
> + * only be called in situations that should never fail.  We clean up
> + * after ourselves and return the queue attributes in *result.
> + */
> +static inline void test_queue(struct mq_attr *attr, struct mq_attr *result)
> +{
> +	int flags = O_RDWR | O_EXCL | O_CREAT;
> +	int perms = DEFFILEMODE;
> +
> +	if ((queue = mq_open(queue_path, flags, perms, attr)) == -1)
> +		shutdown(1, "mq_open()", __LINE__);
> +	if (mq_getattr(queue, result))
> +		shutdown(1, "mq_getattr()", __LINE__);
> +	if (mq_close(queue))
> +		shutdown(1, "mq_close()", __LINE__);
> +	queue = -1;
> +	if (mq_unlink(queue_path))
> +		shutdown(1, "mq_unlink()", __LINE__);
> +}
> +
> +/*
> + * Same as test_queue above, but failure is not fatal.
> + * Returns:
> + * 0 - Failed to create a queue
> + * 1 - Created a queue, attributes in *result
> + */
> +static inline int test_queue_fail(struct mq_attr *attr, struct mq_attr *result)
> +{
> +	int flags = O_RDWR | O_EXCL | O_CREAT;
> +	int perms = DEFFILEMODE;
> +
> +	if ((queue = mq_open(queue_path, flags, perms, attr)) == -1)
> +		return 0;
> +	if (mq_getattr(queue, result))
> +		shutdown(1, "mq_getattr()", __LINE__);
> +	if (mq_close(queue))
> +		shutdown(1, "mq_close()", __LINE__);
> +	queue = -1;
> +	if (mq_unlink(queue_path))
> +		shutdown(1, "mq_unlink()", __LINE__);
> +	return 1;
> +}
> +
> +int main(int argc, char *argv[])
> +{
> +	struct mq_attr attr, result;
> +
> +	if (argc != 2) {
> +		fprintf(stderr, "Must pass a valid queue name\n\n");
> +		fprintf(stderr, usage, argv[0]);
> +		exit(1);
> +	}
> +
> +	/*
> +	 * Although we can create a msg queue with a non-absolute path name,
> +	 * unlink will fail.  So, if the name doesn't start with a /, add one
> +	 * when we save it.
> +	 */
> +	if (*argv[1] == '/')
> +		queue_path = strdup(argv[1]);
> +	else {
> +		queue_path = malloc(strlen(argv[1]) + 2);
> +		if (!queue_path) {
> +			perror("malloc()");
> +			exit(1);
> +		}
> +		queue_path[0] = '/';
> +		queue_path[1] = 0;
> +		strcat(queue_path, argv[1]);
> +	}
> +
> +	if (getuid() != 0) {
> +		fprintf(stderr, "Not running as root, but almost all tests "
> +			"require root in order to modify\nsystem settings.  "
> +			"Exiting.\n");
> +		exit(1);
> +	}
> +
> +	/* Find out what files there are for us to make tweaks in */
> +	def_msgs = fopen(DEF_MSGS, "r+");
> +	def_msgsize = fopen(DEF_MSGSIZE, "r+");
> +	max_msgs = fopen(MAX_MSGS, "r+");
> +	max_msgsize = fopen(MAX_MSGSIZE, "r+");
> +
> +	if (!max_msgs)
> +		shutdown(2, "Failed to open msg_max", __LINE__);
> +	if (!max_msgsize)
> +		shutdown(2, "Failed to open msgsize_max", __LINE__);
> +	if (def_msgs || def_msgsize)
> +		default_settings = 1;
> +
> +	/* Load up the current system values for everything we can */
> +	getr(RLIMIT_MSGQUEUE, &saved_limits);
> +	cur_limits = saved_limits;
> +	if (default_settings) {
> +		saved_def_msgs = cur_def_msgs = get(def_msgs);
> +		saved_def_msgsize = cur_def_msgsize = get(def_msgsize);
> +	}
> +	saved_max_msgs = cur_max_msgs = get(max_msgs);
> +	saved_max_msgsize = cur_max_msgsize = get(max_msgsize);
> +
> +	/* Tell the user our initial state */
> +	printf("\nInitial system state:\n");
> +	printf("\tUsing queue path:\t\t%s\n", queue_path);
> +	printf("\tRLIMIT_MSGQUEUE(soft):\t\t%ld\n",
> +		(long) saved_limits.rlim_cur);
> +	printf("\tRLIMIT_MSGQUEUE(hard):\t\t%ld\n",
> +		(long) saved_limits.rlim_max);
> +	printf("\tMaximum Message Size:\t\t%d\n", saved_max_msgsize);
> +	printf("\tMaximum Queue Size:\t\t%d\n", saved_max_msgs);
> +	if (default_settings) {
> +		printf("\tDefault Message Size:\t\t%d\n", saved_def_msgsize);
> +		printf("\tDefault Queue Size:\t\t%d\n", saved_def_msgs);
> +	} else {
> +		printf("\tDefault Message Size:\t\tNot Supported\n");
> +		printf("\tDefault Queue Size:\t\tNot Supported\n");
> +	}
> +	printf("\n");
> +
> +	validate_current_settings();
> +
> +	printf("Adjusted system state for testing:\n");
> +	printf("\tRLIMIT_MSGQUEUE(soft):\t\t%ld\n", (long) cur_limits.rlim_cur);
> +	printf("\tRLIMIT_MSGQUEUE(hard):\t\t%ld\n", (long) cur_limits.rlim_max);
> +	printf("\tMaximum Message Size:\t\t%d\n", cur_max_msgsize);
> +	printf("\tMaximum Queue Size:\t\t%d\n", cur_max_msgs);
> +	if (default_settings) {
> +		printf("\tDefault Message Size:\t\t%d\n", cur_def_msgsize);
> +		printf("\tDefault Queue Size:\t\t%d\n", cur_def_msgs);
> +	}
> +
> +	printf("\n\nTest series 1, behavior when no attr struct "
> +	       "passed to mq_open:\n");
> +	if (!default_settings) {
> +		test_queue(NULL, &result);
> +		printf("Given sane system settings, mq_open without an attr "
> +		       "struct succeeds:\tPASS\n");
> +		if (result.mq_maxmsg != cur_max_msgs ||
> +		    result.mq_msgsize != cur_max_msgsize) {
> +			printf("Kernel does not support setting the default "
> +			       "mq attributes,\nbut also doesn't tie the "
> +			       "defaults to the maximums:\t\t\tPASS\n");
> +		} else {
> +			set(max_msgs, ++cur_max_msgs);
> +			set(max_msgsize, ++cur_max_msgsize);
> +			test_queue(NULL, &result);
> +			if (result.mq_maxmsg == cur_max_msgs &&
> +			    result.mq_msgsize == cur_max_msgsize)
> +				printf("Kernel does not support setting the "
> +				       "default mq attributes and\n"
> +				       "also ties system wide defaults to "
> +				       "the system wide maximums:\t\t"
> +				       "FAIL\n");
> +			else
> +				printf("Kernel does not support setting the "
> +				       "default mq attributes,\n"
> +				       "but also doesn't tie the defaults to "
> +				       "the maximums:\t\t\tPASS\n");
> +		}
> +	} else {
> +		printf("Kernel supports setting defaults separately from "
> +		       "maximums:\t\tPASS\n");
> +		/*
> +		 * While we are here, go ahead and test that the kernel
> +		 * properly follows the default settings
> +		 */
> +		test_queue(NULL, &result);
> +		printf("Given sane values, mq_open without an attr struct "
> +		       "succeeds:\t\tPASS\n");
> +		if (result.mq_maxmsg != cur_def_msgs ||
> +		    result.mq_msgsize != cur_def_msgsize)
> +			printf("Kernel supports setting defaults, but does "
> +			       "not actually honor them:\tFAIL\n\n");
> +		else {
> +			set(def_msgs, ++cur_def_msgs);
> +			set(def_msgsize, ++cur_def_msgsize);
> +			/* In case max was the same as the default */
> +			set(max_msgs, ++cur_max_msgs);
> +			set(max_msgsize, ++cur_max_msgsize);
> +			test_queue(NULL, &result);
> +			if (result.mq_maxmsg != cur_def_msgs ||
> +			    result.mq_msgsize != cur_def_msgsize)
> +				printf("Kernel supports setting defaults, but "
> +				       "does not actually honor them:\t"
> +				       "FAIL\n");
> +			else
> +				printf("Kernel properly honors default setting "
> +				       "knobs:\t\t\t\tPASS\n");
> +		}
> +		set(def_msgs, cur_max_msgs + 1);
> +		cur_def_msgs = cur_max_msgs + 1;
> +		set(def_msgsize, cur_max_msgsize + 1);
> +		cur_def_msgsize = cur_max_msgsize + 1;
> +		if (cur_def_msgs * (cur_def_msgsize + 2 * sizeof(void *)) >=
> +		    cur_limits.rlim_cur) {
> +			cur_limits.rlim_cur = (cur_def_msgs + 2) *
> +				(cur_def_msgsize + 2 * sizeof(void *));
> +			cur_limits.rlim_max = 2 * cur_limits.rlim_cur;
> +			setr(RLIMIT_MSGQUEUE, &cur_limits);
> +		}
> +		if (test_queue_fail(NULL, &result)) {
> +			if (result.mq_maxmsg == cur_max_msgs &&
> +			    result.mq_msgsize == cur_max_msgsize)
> +				printf("Kernel properly limits default values "
> +				       "to lesser of default/max:\t\tPASS\n");
> +			else
> +				printf("Kernel does not properly set default "
> +				       "queue parameters when\ndefaults > "
> +				       "max:\t\t\t\t\t\t\t\tFAIL\n");
> +		} else
> +			printf("Kernel fails to open mq because defaults are "
> +			       "greater than maximums:\tFAIL\n");
> +		set(def_msgs, --cur_def_msgs);
> +		set(def_msgsize, --cur_def_msgsize);
> +		cur_limits.rlim_cur = cur_limits.rlim_max = cur_def_msgs *
> +			cur_def_msgsize;
> +		setr(RLIMIT_MSGQUEUE, &cur_limits);
> +		if (test_queue_fail(NULL, &result))
> +			printf("Kernel creates queue even though defaults "
> +			       "would exceed\nrlimit setting:"
> +			       "\t\t\t\t\t\t\t\tFAIL\n");
> +		else
> +			printf("Kernel properly fails to create queue when "
> +			       "defaults would\nexceed rlimit:"
> +			       "\t\t\t\t\t\t\t\tPASS\n");
> +	}
> +
> +	/*
> +	 * Test #2 - open with an attr struct that exceeds rlimit
> +	 */
> +	printf("\n\nTest series 2, behavior when attr struct is "
> +	       "passed to mq_open:\n");
> +	cur_max_msgs = 32;
> +	cur_max_msgsize = cur_limits.rlim_max >> 4;
> +	set(max_msgs, cur_max_msgs);
> +	set(max_msgsize, cur_max_msgsize);
> +	attr.mq_maxmsg = cur_max_msgs;
> +	attr.mq_msgsize = cur_max_msgsize;
> +	if (test_queue_fail(&attr, &result))
> +		printf("Queue open in excess of rlimit max when euid = 0 "
> +		       "succeeded:\t\tFAIL\n");
> +	else
> +		printf("Queue open in excess of rlimit max when euid = 0 "
> +		       "failed:\t\tPASS\n");
> +	attr.mq_maxmsg = cur_max_msgs + 1;
> +	attr.mq_msgsize = 10;
> +	if (test_queue_fail(&attr, &result))
> +		printf("Queue open with mq_maxmsg > limit when euid = 0 "
> +		       "succeeded:\t\tPASS\n");
> +	else
> +		printf("Queue open with mq_maxmsg > limit when euid = 0 "
> +		       "failed:\t\tFAIL\n");
> +	attr.mq_maxmsg = 1;
> +	attr.mq_msgsize = cur_max_msgsize + 1;
> +	if (test_queue_fail(&attr, &result))
> +		printf("Queue open with mq_msgsize > limit when euid = 0 "
> +		       "succeeded:\t\tPASS\n");
> +	else
> +		printf("Queue open with mq_msgsize > limit when euid = 0 "
> +		       "failed:\t\tFAIL\n");
> +	attr.mq_maxmsg = 65536;
> +	attr.mq_msgsize = 65536;
> +	if (test_queue_fail(&attr, &result))
> +		printf("Queue open with total size > 2GB when euid = 0 "
> +		       "succeeded:\t\tFAIL\n");
> +	else
> +		printf("Queue open with total size > 2GB when euid = 0 "
> +		       "failed:\t\t\tPASS\n");
> +
> +	if (seteuid(99) == -1) {
> +		perror("seteuid() failed");
> +		exit(1);
> +	}
> +
> +	attr.mq_maxmsg = cur_max_msgs;
> +	attr.mq_msgsize = cur_max_msgsize;
> +	if (test_queue_fail(&attr, &result))
> +		printf("Queue open in excess of rlimit max when euid = 99 "
> +		       "succeeded:\t\tFAIL\n");
> +	else
> +		printf("Queue open in excess of rlimit max when euid = 99 "
> +		       "failed:\t\tPASS\n");
> +	attr.mq_maxmsg = cur_max_msgs + 1;
> +	attr.mq_msgsize = 10;
> +	if (test_queue_fail(&attr, &result))
> +		printf("Queue open with mq_maxmsg > limit when euid = 99 "
> +		       "succeeded:\t\tFAIL\n");
> +	else
> +		printf("Queue open with mq_maxmsg > limit when euid = 99 "
> +		       "failed:\t\tPASS\n");
> +	attr.mq_maxmsg = 1;
> +	attr.mq_msgsize = cur_max_msgsize + 1;
> +	if (test_queue_fail(&attr, &result))
> +		printf("Queue open with mq_msgsize > limit when euid = 99 "
> +		       "succeeded:\t\tFAIL\n");
> +	else
> +		printf("Queue open with mq_msgsize > limit when euid = 99 "
> +		       "failed:\t\tPASS\n");
> +	attr.mq_maxmsg = 65536;
> +	attr.mq_msgsize = 65536;
> +	if (test_queue_fail(&attr, &result))
> +		printf("Queue open with total size > 2GB when euid = 99 "
> +		       "succeeded:\t\tFAIL\n");
> +	else
> +		printf("Queue open with total size > 2GB when euid = 99 "
> +		       "failed:\t\t\tPASS\n");
> +
> +	shutdown(0,"",0);
> +}
> diff --git a/tools/testing/selftests/ipc/mqueue/mq_perf_tests.c b/tools/testing/selftests/ipc/mqueue/mq_perf_tests.c
> new file mode 100644
> index 0000000..8519e9e
> --- /dev/null
> +++ b/tools/testing/selftests/ipc/mqueue/mq_perf_tests.c
> @@ -0,0 +1,742 @@
> +/*
> + * This application is Copyright 2012 Red Hat, Inc.
> + *	Doug Ledford <dledford@...hat.com>
> + *
> + * mq_perf_tests is free software: you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation, version 3.
> + *
> + * mq_perf_tests is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * For the full text of the license, see <http://www.gnu.org/licenses/>.
> + *
> + * mq_perf_tests.c
> + *   Tests various types of message queue workloads, concentrating on those
> + *   situations that invole large message sizes, large message queue depths,
> + *   or both, and reports back useful metrics about kernel message queue
> + *   performance.
> + *
> + */
> +#define _GNU_SOURCE
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <unistd.h>
> +#include <fcntl.h>
> +#include <string.h>
> +#include <limits.h>
> +#include <errno.h>
> +#include <signal.h>
> +#include <pthread.h>
> +#include <sched.h>
> +#include <sys/types.h>
> +#include <sys/time.h>
> +#include <sys/resource.h>
> +#include <sys/stat.h>
> +#include <mqueue.h>
> +#include <popt.h>
> +
> +static char *usage =
> +"Usage:\n"
> +"  %s [-c #[,#..] -f] path\n"
> +"\n"
> +"	-c #	Skip most tests and go straight to a high queue depth test\n"
> +"		and then run that test continuously (useful for running at\n"
> +"		the same time as some other workload to see how much the\n"
> +"		cache thrashing caused by adding messages to a very deep\n"
> +"		queue impacts the performance of other programs).  The number\n"
> +"		indicates which CPU core we should bind the process to during\n"
> +"		the run.  If you have more than one physical CPU, then you\n"
> +"		will need one copy per physical CPU package, and you should\n"
> +"		specify the CPU cores to pin ourself to via a comma separated\n"
> +"		list of CPU values.\n"
> +"	-f	Only usable with continuous mode.  Pin ourself to the CPUs\n"
> +"		as requested, then instead of looping doing a high mq\n"
> +"		workload, just busy loop.  This will allow us to lock up a\n"
> +"		single CPU just like we normally would, but without actually\n"
> +"		thrashing the CPU cache.  This is to make it easier to get\n"
> +"		comparable numbers from some other workload running on the\n"
> +"		other CPUs.  One set of numbers with # CPUs locked up running\n"
> +"		an mq workload, and another set of numbers with those same\n"
> +"		CPUs locked away from the test workload, but not doing\n"
> +"		anything to trash the cache like the mq workload might.\n"
> +"	path	Path name of the message queue to create\n"
> +"\n"
> +"	Note: this program must be run as root in order to enable all tests\n"
> +"\n";
> +
> +char *MAX_MSGS = "/proc/sys/fs/mqueue/msg_max";
> +char *MAX_MSGSIZE = "/proc/sys/fs/mqueue/msgsize_max";
> +
> +#define min(a, b) ((a) < (b) ? (a) : (b))
> +#define MAX_CPUS 64
> +char *cpu_option_string;
> +int cpus_to_pin[MAX_CPUS];
> +int num_cpus_to_pin;
> +pthread_t cpu_threads[MAX_CPUS];
> +pthread_t main_thread;
> +cpu_set_t *cpu_set;
> +int cpu_set_size;
> +int cpus_online;
> +
> +#define MSG_SIZE 16
> +#define TEST1_LOOPS 10000000
> +#define TEST2_LOOPS 100000
> +int continuous_mode;
> +int continuous_mode_fake;
> +
> +struct rlimit saved_limits, cur_limits;
> +int saved_max_msgs, saved_max_msgsize;
> +int cur_max_msgs, cur_max_msgsize;
> +FILE *max_msgs, *max_msgsize;
> +int cur_nice;
> +char *queue_path = "/mq_perf_tests";
> +mqd_t queue = -1;
> +struct mq_attr result;
> +int mq_prio_max;
> +
> +const struct poptOption options[] = {
> +	{
> +		.longName = "continuous",
> +		.shortName = 'c',
> +		.argInfo = POPT_ARG_STRING,
> +		.arg = &cpu_option_string,
> +		.val = 'c',
> +		.descrip = "Run continuous tests at a high queue depth in "
> +			"order to test the effects of cache thrashing on "
> +			"other tasks on the system.  This test is intended "
> +			"to be run on one core of each physical CPU while "
> +			"some other CPU intensive task is run on all the other "
> +			"cores of that same physical CPU and the other task "
> +			"is timed.  It is assumed that the process of adding "
> +			"messages to the message queue in a tight loop will "
> +			"impact that other task to some degree.  Once the "
> +			"tests are performed in this way, you should then "
> +			"re-run the tests using fake mode in order to check "
> +			"the difference in time required to perform the CPU "
> +			"intensive task",
> +		.argDescrip = "cpu[,cpu]",
> +	},
> +	{
> +		.longName = "fake",
> +		.shortName = 'f',
> +		.argInfo = POPT_ARG_NONE,
> +		.arg = &continuous_mode_fake,
> +		.val = 0,
> +		.descrip = "Tie up the CPUs that we would normally tie up in"
> +			"continuous mode, but don't actually do any mq stuff, "
> +			"just keep the CPU busy so it can't be used to process "
> +			"system level tasks as this would free up resources on "
> +			"the other CPU cores and skew the comparison between "
> +			"the no-mqueue work and mqueue work tests",
> +		.argDescrip = NULL,
> +	},
> +	{
> +		.longName = "path",
> +		.shortName = 'p',
> +		.argInfo = POPT_ARG_STRING | POPT_ARGFLAG_SHOW_DEFAULT,
> +		.arg = &queue_path,
> +		.val = 'p',
> +		.descrip = "The name of the path to use in the mqueue "
> +			"filesystem for our tests",
> +		.argDescrip = "pathname",
> +	},
> +	POPT_AUTOHELP
> +	POPT_TABLEEND
> +};
> +
> +static inline void __set(FILE *stream, int value, char *err_msg);
> +void shutdown(int exit_val, char *err_cause, int line_no);
> +void sig_action_SIGUSR1(int signum, siginfo_t *info, void *context);
> +void sig_action(int signum, siginfo_t *info, void *context);
> +static inline int get(FILE *stream);
> +static inline void set(FILE *stream, int value);
> +static inline int try_set(FILE *stream, int value);
> +static inline void getr(int type, struct rlimit *rlim);
> +static inline void setr(int type, struct rlimit *rlim);
> +static inline void open_queue(struct mq_attr *attr);
> +void increase_limits(void);
> +
> +static inline void __set(FILE *stream, int value, char *err_msg)
> +{
> +	rewind(stream);
> +	if (fprintf(stream, "%d", value) < 0)
> +		perror(err_msg);
> +}
> +
> +
> +void shutdown(int exit_val, char *err_cause, int line_no)
> +{
> +	static int in_shutdown = 0;
> +	int errno_at_shutdown = errno;
> +	int i;
> +
> +	/* In case we get called by multiple threads or from an sighandler */
> +	if (in_shutdown++)
> +		return;
> +
> +	for (i = 0; i < num_cpus_to_pin; i++)
> +		if (cpu_threads[i]) {
> +			pthread_kill(cpu_threads[i], SIGUSR1);
> +			pthread_join(cpu_threads[i], NULL);
> +		}
> +
> +	if (queue != -1)
> +		if (mq_close(queue))
> +			perror("mq_close() during shutdown");
> +	if (queue_path)
> +		/*
> +		 * Be silent if this fails, if we cleaned up already it's
> +		 * expected to fail
> +		 */
> +		mq_unlink(queue_path);
> +	if (saved_max_msgs)
> +		__set(max_msgs, saved_max_msgs,
> +		      "failed to restore saved_max_msgs");
> +	if (saved_max_msgsize)
> +		__set(max_msgsize, saved_max_msgsize,
> +		      "failed to restore saved_max_msgsize");
> +	if (exit_val)
> +		error(exit_val, errno_at_shutdown, "%s at %d",
> +		      err_cause, line_no);
> +	exit(0);
> +}
> +
> +void sig_action_SIGUSR1(int signum, siginfo_t *info, void *context)
> +{
> +	if (pthread_self() != main_thread)
> +		pthread_exit(0);
> +	else {
> +		fprintf(stderr, "Caught signal %d in SIGUSR1 handler, "
> +				"exiting\n", signum);
> +		shutdown(0, "", 0);
> +		fprintf(stderr, "\n\nReturned from shutdown?!?!\n\n");
> +		exit(0);
> +	}
> +}
> +
> +void sig_action(int signum, siginfo_t *info, void *context)
> +{
> +	if (pthread_self() != main_thread)
> +		pthread_kill(main_thread, signum);
> +	else {
> +		fprintf(stderr, "Caught signal %d, exiting\n", signum);
> +		shutdown(0, "", 0);
> +		fprintf(stderr, "\n\nReturned from shutdown?!?!\n\n");
> +		exit(0);
> +	}
> +}
> +
> +static inline int get(FILE *stream)
> +{
> +	int value;
> +	rewind(stream);
> +	if (fscanf(stream, "%d", &value) != 1)
> +		shutdown(4, "Error reading /proc entry", __LINE__);
> +	return value;
> +}
> +
> +static inline void set(FILE *stream, int value)
> +{
> +	int new_value;
> +
> +	rewind(stream);
> +	if (fprintf(stream, "%d", value) < 0)
> +		return shutdown(5, "Failed writing to /proc file", __LINE__);
> +	new_value = get(stream);
> +	if (new_value != value)
> +		return shutdown(5, "We didn't get what we wrote to /proc back",
> +				__LINE__);
> +}
> +
> +static inline int try_set(FILE *stream, int value)
> +{
> +	int new_value;
> +
> +	rewind(stream);
> +	fprintf(stream, "%d", value);
> +	new_value = get(stream);
> +	return new_value == value;
> +}
> +
> +static inline void getr(int type, struct rlimit *rlim)
> +{
> +	if (getrlimit(type, rlim))
> +		shutdown(6, "getrlimit()", __LINE__);
> +}
> +
> +static inline void setr(int type, struct rlimit *rlim)
> +{
> +	if (setrlimit(type, rlim))
> +		shutdown(7, "setrlimit()", __LINE__);
> +}
> +
> +/**
> + * open_queue - open the global queue for testing
> + * @attr - An attr struct specifying the desired queue traits
> + * @result - An attr struct that lists the actual traits the queue has
> + *
> + * This open is not allowed to fail, failure will result in an orderly
> + * shutdown of the program.  The global queue_path is used to set what
> + * queue to open, the queue descriptor is saved in the global queue
> + * variable.
> + */
> +static inline void open_queue(struct mq_attr *attr)
> +{
> +	int flags = O_RDWR | O_EXCL | O_CREAT | O_NONBLOCK;
> +	int perms = DEFFILEMODE;
> +
> +	queue = mq_open(queue_path, flags, perms, attr);
> +	if (queue == -1)
> +		shutdown(1, "mq_open()", __LINE__);
> +	if (mq_getattr(queue, &result))
> +		shutdown(1, "mq_getattr()", __LINE__);
> +	printf("\n\tQueue %s created:\n", queue_path);
> +	printf("\t\tmq_flags:\t\t\t%s\n", result.mq_flags & O_NONBLOCK ?
> +	       "O_NONBLOCK" : "(null)");
> +	printf("\t\tmq_maxmsg:\t\t\t%lu\n", result.mq_maxmsg);
> +	printf("\t\tmq_msgsize:\t\t\t%lu\n", result.mq_msgsize);
> +	printf("\t\tmq_curmsgs:\t\t\t%lu\n", result.mq_curmsgs);
> +}
> +
> +void *fake_cont_thread(void *arg)
> +{
> +	int i;
> +
> +	for (i = 0; i < num_cpus_to_pin; i++)
> +		if (cpu_threads[i] == pthread_self())
> +			break;
> +	printf("\tStarted fake continuous mode thread %d on CPU %d\n", i,
> +	       cpus_to_pin[i]);
> +	while (1)
> +		;
> +}
> +
> +void *cont_thread(void *arg)
> +{
> +	char buff[MSG_SIZE];
> +	int i, priority;
> +
> +	for (i = 0; i < num_cpus_to_pin; i++)
> +		if (cpu_threads[i] == pthread_self())
> +			break;
> +	printf("\tStarted continuous mode thread %d on CPU %d\n", i,
> +	       cpus_to_pin[i]);
> +	while (1) {
> +		while (mq_send(queue, buff, sizeof(buff), 0) == 0)
> +			;
> +		mq_receive(queue, buff, sizeof(buff), &priority);
> +	}
> +}
> +
> +#define drain_queue() \
> +	while (mq_receive(queue, buff, MSG_SIZE, &prio_in) == MSG_SIZE)
> +
> +#define do_untimed_send() \
> +	do { \
> +		if (mq_send(queue, buff, MSG_SIZE, prio_out)) \
> +			shutdown(3, "Test send failure", __LINE__); \
> +	} while (0)
> +
> +#define do_send_recv() \
> +	do { \
> +		clock_gettime(clock, &start); \
> +		if (mq_send(queue, buff, MSG_SIZE, prio_out)) \
> +			shutdown(3, "Test send failure", __LINE__); \
> +		clock_gettime(clock, &middle); \
> +		if (mq_receive(queue, buff, MSG_SIZE, &prio_in) != MSG_SIZE) \
> +			shutdown(3, "Test receive failure", __LINE__); \
> +		clock_gettime(clock, &end); \
> +		nsec = ((middle.tv_sec - start.tv_sec) * 1000000000) + \
> +			(middle.tv_nsec - start.tv_nsec); \
> +		send_total.tv_nsec += nsec; \
> +		if (send_total.tv_nsec >= 1000000000) { \
> +			send_total.tv_sec++; \
> +			send_total.tv_nsec -= 1000000000; \
> +		} \
> +		nsec = ((end.tv_sec - middle.tv_sec) * 1000000000) + \
> +			(end.tv_nsec - middle.tv_nsec); \
> +		recv_total.tv_nsec += nsec; \
> +		if (recv_total.tv_nsec >= 1000000000) { \
> +			recv_total.tv_sec++; \
> +			recv_total.tv_nsec -= 1000000000; \
> +		} \
> +	} while (0)
> +
> +struct test {
> +	char *desc;
> +	void (*func)(int *);
> +};
> +
> +void const_prio(int *prio)
> +{
> +	return;
> +}
> +
> +void inc_prio(int *prio)
> +{
> +	if (++*prio == mq_prio_max)
> +		*prio = 0;
> +}
> +
> +void dec_prio(int *prio)
> +{
> +	if (--*prio < 0)
> +		*prio = mq_prio_max - 1;
> +}
> +
> +void random_prio(int *prio)
> +{
> +	*prio = random() % mq_prio_max;
> +}
> +
> +struct test test2[] = {
> +	{"\n\tTest #2a: Time send/recv message, queue full, constant prio\n",
> +		const_prio},
> +	{"\n\tTest #2b: Time send/recv message, queue full, increasing prio\n",
> +		inc_prio},
> +	{"\n\tTest #2c: Time send/recv message, queue full, decreasing prio\n",
> +		dec_prio},
> +	{"\n\tTest #2d: Time send/recv message, queue full, random prio\n",
> +		random_prio},
> +	{NULL, NULL}
> +};
> +
> +/**
> + * Tests to perform (all done with MSG_SIZE messages):
> + *
> + * 1) Time to add/remove message with 0 messages on queue
> + * 1a) with constant prio
> + * 2) Time to add/remove message when queue close to capacity:
> + * 2a) with constant prio
> + * 2b) with increasing prio
> + * 2c) with decreasing prio
> + * 2d) with random prio
> + * 3) Test limits of priorities honored (double check _SC_MQ_PRIO_MAX)
> + */
> +void *perf_test_thread(void *arg)
> +{
> +	char buff[MSG_SIZE];
> +	int prio_out, prio_in;
> +	int i;
> +	clockid_t clock;
> +	pthread_t *t;
> +	struct timespec res, start, middle, end, send_total, recv_total;
> +	unsigned long long nsec;
> +	struct test *cur_test;
> +
> +	t = &cpu_threads[0];
> +	printf("\n\tStarted mqueue performance test thread on CPU %d\n",
> +	       cpus_to_pin[0]);
> +	mq_prio_max = sysconf(_SC_MQ_PRIO_MAX);
> +	if (mq_prio_max == -1)
> +		shutdown(2, "sysconf(_SC_MQ_PRIO_MAX)", __LINE__);
> +	if (pthread_getcpuclockid(cpu_threads[0], &clock) != 0)
> +		shutdown(2, "pthread_getcpuclockid", __LINE__);
> +
> +	if (clock_getres(clock, &res))
> +		shutdown(2, "clock_getres()", __LINE__);
> +
> +	printf("\t\tMax priorities:\t\t\t%d\n", mq_prio_max);
> +	printf("\t\tClock resolution:\t\t%lu nsec%s\n", res.tv_nsec,
> +	       res.tv_nsec > 1 ? "s" : "");
> +
> +
> +
> +	printf("\n\tTest #1: Time send/recv message, queue empty\n");
> +	printf("\t\t(%d iterations)\n", TEST1_LOOPS);
> +	prio_out = 0;
> +	send_total.tv_sec = 0;
> +	send_total.tv_nsec = 0;
> +	recv_total.tv_sec = 0;
> +	recv_total.tv_nsec = 0;
> +	for (i = 0; i < TEST1_LOOPS; i++)
> +		do_send_recv();
> +	printf("\t\tSend msg:\t\t\t%ld.%lus total time\n",
> +	       send_total.tv_sec, send_total.tv_nsec);
> +	nsec = ((unsigned long long)send_total.tv_sec * 1000000000 +
> +		 send_total.tv_nsec) / TEST1_LOOPS;
> +	printf("\t\t\t\t\t\t%lld nsec/msg\n", nsec);
> +	printf("\t\tRecv msg:\t\t\t%ld.%lus total time\n",
> +	       recv_total.tv_sec, recv_total.tv_nsec);
> +	nsec = ((unsigned long long)recv_total.tv_sec * 1000000000 +
> +		recv_total.tv_nsec) / TEST1_LOOPS;
> +	printf("\t\t\t\t\t\t%lld nsec/msg\n", nsec);
> +
> +
> +	for (cur_test = test2; cur_test->desc != NULL; cur_test++) {
> +		printf("%s:\n", cur_test->desc);
> +		printf("\t\t(%d iterations)\n", TEST2_LOOPS);
> +		prio_out = 0;
> +		send_total.tv_sec = 0;
> +		send_total.tv_nsec = 0;
> +		recv_total.tv_sec = 0;
> +		recv_total.tv_nsec = 0;
> +		printf("\t\tFilling queue...");
> +		fflush(stdout);
> +		clock_gettime(clock, &start);
> +		for (i = 0; i < result.mq_maxmsg - 1; i++) {
> +			do_untimed_send();
> +			cur_test->func(&prio_out);
> +		}
> +		clock_gettime(clock, &end);
> +		nsec = ((unsigned long long)(end.tv_sec - start.tv_sec) *
> +			1000000000) + (end.tv_nsec - start.tv_nsec);
> +		printf("done.\t\t%lld.%llds\n", nsec / 1000000000,
> +		       nsec % 1000000000);
> +		printf("\t\tTesting...");
> +		fflush(stdout);
> +		for (i = 0; i < TEST2_LOOPS; i++) {
> +			do_send_recv();
> +			cur_test->func(&prio_out);
> +		}
> +		printf("done.\n");
> +		printf("\t\tSend msg:\t\t\t%ld.%lus total time\n",
> +		       send_total.tv_sec, send_total.tv_nsec);
> +		nsec = ((unsigned long long)send_total.tv_sec * 1000000000 +
> +			 send_total.tv_nsec) / TEST2_LOOPS;
> +		printf("\t\t\t\t\t\t%lld nsec/msg\n", nsec);
> +		printf("\t\tRecv msg:\t\t\t%ld.%lus total time\n",
> +		       recv_total.tv_sec, recv_total.tv_nsec);
> +		nsec = ((unsigned long long)recv_total.tv_sec * 1000000000 +
> +			recv_total.tv_nsec) / TEST2_LOOPS;
> +		printf("\t\t\t\t\t\t%lld nsec/msg\n", nsec);
> +		printf("\t\tDraining queue...");
> +		fflush(stdout);
> +		clock_gettime(clock, &start);
> +		drain_queue();
> +		clock_gettime(clock, &end);
> +		nsec = ((unsigned long long)(end.tv_sec - start.tv_sec) *
> +			1000000000) + (end.tv_nsec - start.tv_nsec);
> +		printf("done.\t\t%lld.%llds\n", nsec / 1000000000,
> +		       nsec % 1000000000);
> +	}
> +	return 0;
> +}
> +
> +void increase_limits(void)
> +{
> +	cur_limits.rlim_cur = RLIM_INFINITY;
> +	cur_limits.rlim_max = RLIM_INFINITY;
> +	setr(RLIMIT_MSGQUEUE, &cur_limits);
> +	while (try_set(max_msgs, cur_max_msgs += 10))
> +		;
> +	cur_max_msgs = get(max_msgs);
> +	while (try_set(max_msgsize, cur_max_msgsize += 1024))
> +		;
> +	cur_max_msgsize = get(max_msgsize);
> +	if (setpriority(PRIO_PROCESS, 0, -20) != 0)
> +		shutdown(2, "setpriority()", __LINE__);
> +	cur_nice = -20;
> +}
> +
> +int main(int argc, char *argv[])
> +{
> +	struct mq_attr attr;
> +	char *option, *next_option;
> +	int i, cpu, rc;
> +	struct sigaction sa;
> +	poptContext popt_context;
> +	void *retval;
> +
> +	main_thread = pthread_self();
> +	num_cpus_to_pin = 0;
> +
> +	if (sysconf(_SC_NPROCESSORS_ONLN) == -1) {
> +		perror("sysconf(_SC_NPROCESSORS_ONLN)");
> +		exit(1);
> +	}
> +	cpus_online = min(MAX_CPUS, sysconf(_SC_NPROCESSORS_ONLN));
> +	cpu_set = CPU_ALLOC(cpus_online);
> +	if (cpu_set == NULL) {
> +		perror("CPU_ALLOC()");
> +		exit(1);
> +	}
> +	cpu_set_size = CPU_ALLOC_SIZE(cpus_online);
> +	CPU_ZERO_S(cpu_set_size, cpu_set);
> +
> +	popt_context = poptGetContext(NULL, argc, (const char **)argv,
> +				      options, 0);
> +
> +	while ((rc = poptGetNextOpt(popt_context)) > 0) {
> +		switch (rc) {
> +		case 'c':
> +			continuous_mode = 1;
> +			option = cpu_option_string;
> +			do {
> +				next_option = strchr(option, ',');
> +				if (next_option)
> +					*next_option = '\0';
> +				cpu = atoi(option);
> +				if (cpu >= cpus_online)
> +					fprintf(stderr, "CPU %d exceeds "
> +						"cpus online, ignoring.\n",
> +						cpu);
> +				else
> +					cpus_to_pin[num_cpus_to_pin++] = cpu;
> +				if (next_option)
> +					option = ++next_option;
> +			} while (next_option && num_cpus_to_pin < MAX_CPUS);
> +			/* Double check that they didn't give us the same CPU
> +			 * more than once */
> +			for (cpu = 0; cpu < num_cpus_to_pin; cpu++) {
> +				if (CPU_ISSET_S(cpus_to_pin[cpu], cpu_set_size,
> +						cpu_set)) {
> +					fprintf(stderr, "Any given CPU may "
> +						"only be given once.\n");
> +					exit(1);
> +				} else
> +					CPU_SET_S(cpus_to_pin[cpu],
> +						  cpu_set_size, cpu_set);
> +			}
> +			break;
> +		case 'p':
> +			/*
> +			 * Although we can create a msg queue with a
> +			 * non-absolute path name, unlink will fail.  So,
> +			 * if the name doesn't start with a /, add one
> +			 * when we save it.
> +			 */
> +			option = queue_path;
> +			if (*option != '/') {
> +				queue_path = malloc(strlen(option) + 2);
> +				if (!queue_path) {
> +					perror("malloc()");
> +					exit(1);
> +				}
> +				queue_path[0] = '/';
> +				queue_path[1] = 0;
> +				strcat(queue_path, option);
> +				free(option);
> +			}
> +			break;
> +		}
> +	}
> +
> +	if (continuous_mode && num_cpus_to_pin == 0) {
> +		fprintf(stderr, "Must pass at least one CPU to continuous "
> +			"mode.\n");
> +		poptPrintUsage(popt_context, stderr, 0);
> +		exit(1);
> +	} else if (!continuous_mode) {
> +		num_cpus_to_pin = 1;
> +		cpus_to_pin[0] = cpus_online - 1;
> +	}
> +
> +	if (getuid() != 0) {
> +		fprintf(stderr, "Not running as root, but almost all tests "
> +			"require root in order to modify\nsystem settings.  "
> +			"Exiting.\n");
> +		exit(1);
> +	}
> +
> +	max_msgs = fopen(MAX_MSGS, "r+");
> +	max_msgsize = fopen(MAX_MSGSIZE, "r+");
> +	if (!max_msgs)
> +		shutdown(2, "Failed to open msg_max", __LINE__);
> +	if (!max_msgsize)
> +		shutdown(2, "Failed to open msgsize_max", __LINE__);
> +
> +	/* Load up the current system values for everything we can */
> +	getr(RLIMIT_MSGQUEUE, &saved_limits);
> +	cur_limits = saved_limits;
> +	saved_max_msgs = cur_max_msgs = get(max_msgs);
> +	saved_max_msgsize = cur_max_msgsize = get(max_msgsize);
> +	errno = 0;
> +	cur_nice = getpriority(PRIO_PROCESS, 0);
> +	if (errno)
> +		shutdown(2, "getpriority()", __LINE__);
> +
> +	/* Tell the user our initial state */
> +	printf("\nInitial system state:\n");
> +	printf("\tUsing queue path:\t\t\t%s\n", queue_path);
> +	printf("\tRLIMIT_MSGQUEUE(soft):\t\t\t%ld\n",
> +		(long) saved_limits.rlim_cur);
> +	printf("\tRLIMIT_MSGQUEUE(hard):\t\t\t%ld\n",
> +		(long) saved_limits.rlim_max);
> +	printf("\tMaximum Message Size:\t\t\t%d\n", saved_max_msgsize);
> +	printf("\tMaximum Queue Size:\t\t\t%d\n", saved_max_msgs);
> +	printf("\tNice value:\t\t\t\t%d\n", cur_nice);
> +	printf("\n");
> +
> +	increase_limits();
> +
> +	printf("Adjusted system state for testing:\n");
> +	if (cur_limits.rlim_cur == RLIM_INFINITY) {
> +		printf("\tRLIMIT_MSGQUEUE(soft):\t\t\t(unlimited)\n");
> +		printf("\tRLIMIT_MSGQUEUE(hard):\t\t\t(unlimited)\n");
> +	} else {
> +		printf("\tRLIMIT_MSGQUEUE(soft):\t\t\t%ld\n",
> +		       (long) cur_limits.rlim_cur);
> +		printf("\tRLIMIT_MSGQUEUE(hard):\t\t\t%ld\n",
> +		       (long) cur_limits.rlim_max);
> +	}
> +	printf("\tMaximum Message Size:\t\t\t%d\n", cur_max_msgsize);
> +	printf("\tMaximum Queue Size:\t\t\t%d\n", cur_max_msgs);
> +	printf("\tNice value:\t\t\t\t%d\n", cur_nice);
> +	printf("\tContinuous mode:\t\t\t(%s)\n", continuous_mode ?
> +	       (continuous_mode_fake ? "fake mode" : "enabled") :
> +	       "disabled");
> +	printf("\tCPUs to pin:\t\t\t\t%d", cpus_to_pin[0]);
> +	for (cpu = 1; cpu < num_cpus_to_pin; cpu++)
> +			printf(",%d", cpus_to_pin[cpu]);
> +	printf("\n");
> +
> +	sa.sa_sigaction = sig_action_SIGUSR1;
> +	sigemptyset(&sa.sa_mask);
> +	sigaddset(&sa.sa_mask, SIGHUP);
> +	sigaddset(&sa.sa_mask, SIGINT);
> +	sigaddset(&sa.sa_mask, SIGQUIT);
> +	sigaddset(&sa.sa_mask, SIGTERM);
> +	sa.sa_flags = SA_SIGINFO;
> +	if (sigaction(SIGUSR1, &sa, NULL) == -1)
> +		shutdown(1, "sigaction(SIGUSR1)", __LINE__);
> +	sa.sa_sigaction = sig_action;
> +	if (sigaction(SIGHUP, &sa, NULL) == -1)
> +		shutdown(1, "sigaction(SIGHUP)", __LINE__);
> +	if (sigaction(SIGINT, &sa, NULL) == -1)
> +		shutdown(1, "sigaction(SIGINT)", __LINE__);
> +	if (sigaction(SIGQUIT, &sa, NULL) == -1)
> +		shutdown(1, "sigaction(SIGQUIT)", __LINE__);
> +	if (sigaction(SIGTERM, &sa, NULL) == -1)
> +		shutdown(1, "sigaction(SIGTERM)", __LINE__);
> +
> +	if (!continuous_mode_fake) {
> +		attr.mq_flags = O_NONBLOCK;
> +		attr.mq_maxmsg = cur_max_msgs;
> +		attr.mq_msgsize = MSG_SIZE;
> +		open_queue(&attr);
> +	}
> +	for (i = 0; i < num_cpus_to_pin; i++) {
> +		pthread_attr_t thread_attr;
> +		void *thread_func;
> +
> +		if (continuous_mode_fake)
> +			thread_func = &fake_cont_thread;
> +		else if (continuous_mode)
> +			thread_func = &cont_thread;
> +		else
> +			thread_func = &perf_test_thread;
> +
> +		CPU_ZERO_S(cpu_set_size, cpu_set);
> +		CPU_SET_S(cpus_to_pin[i], cpu_set_size, cpu_set);
> +		pthread_attr_init(&thread_attr);
> +		pthread_attr_setaffinity_np(&thread_attr, cpu_set_size,
> +					    cpu_set);
> +		if (pthread_create(&cpu_threads[i], &thread_attr, thread_func,
> +				   NULL))
> +			shutdown(1, "pthread_create()", __LINE__);
> +		pthread_attr_destroy(&thread_attr);
> +	}
> +
> +	if (!continuous_mode) {
> +		pthread_join(cpu_threads[0], &retval);
> +		shutdown((long)retval, "perf_test_thread()", __LINE__);
> +	} else {
> +		while (1)
> +			sleep(1);
> +	}
> +	shutdown(0, "", 0);
> +}
> diff --git a/tools/testing/selftests/ipc/msg/Makefile b/tools/testing/selftests/ipc/msg/Makefile
> new file mode 100644
> index 0000000..777ca76
> --- /dev/null
> +++ b/tools/testing/selftests/ipc/msg/Makefile
> @@ -0,0 +1,22 @@
> +uname_M := $(shell uname -m 2>/dev/null || echo not)
> +ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/i386/)
> +ifeq ($(ARCH),i386)
> +        ARCH := x86
> +	CFLAGS := -DCONFIG_X86_32 -D__i386__
> +endif
> +ifeq ($(ARCH),x86_64)
> +	ARCH := x86
> +	CFLAGS := -DCONFIG_X86_64 -D__x86_64__
> +endif
> +
> +CFLAGS += -I../../../../usr/include/
> +
> +all:
> +	$(CC) $(CFLAGS) msgque.c -o msgque_test
> +
> +TEST_PROGS := msgque_test
> +
> +include ../../lib.mk
> +
> +clean:
> +	rm -fr ./msgque_test
> diff --git a/tools/testing/selftests/ipc/msg/msgque.c b/tools/testing/selftests/ipc/msg/msgque.c
> new file mode 100644
> index 0000000..69d539d
> --- /dev/null
> +++ b/tools/testing/selftests/ipc/msg/msgque.c
> @@ -0,0 +1,254 @@
> +#include <stdlib.h>
> +#include <stdio.h>
> +#include <string.h>
> +#include <errno.h>
> +#include <linux/msg.h>
> +#include <fcntl.h>
> +
> +#include "../../kselftest.h"
> +
> +#define MAX_MSG_SIZE		32
> +
> +struct msg1 {
> +	int msize;
> +	long mtype;
> +	char mtext[MAX_MSG_SIZE];
> +};
> +
> +#define TEST_STRING "Test sysv5 msg"
> +#define MSG_TYPE 1
> +
> +#define ANOTHER_TEST_STRING "Yet another test sysv5 msg"
> +#define ANOTHER_MSG_TYPE 26538
> +
> +struct msgque_data {
> +	key_t key;
> +	int msq_id;
> +	int qbytes;
> +	int qnum;
> +	int mode;
> +	struct msg1 *messages;
> +};
> +
> +int restore_queue(struct msgque_data *msgque)
> +{
> +	int fd, ret, id, i;
> +	char buf[32];
> +
> +	fd = open("/proc/sys/kernel/msg_next_id", O_WRONLY);
> +	if (fd == -1) {
> +		printf("Failed to open /proc/sys/kernel/msg_next_id\n");
> +		return -errno;
> +	}
> +	sprintf(buf, "%d", msgque->msq_id);
> +
> +	ret = write(fd, buf, strlen(buf));
> +	if (ret != strlen(buf)) {
> +		printf("Failed to write to /proc/sys/kernel/msg_next_id\n");
> +		return -errno;
> +	}
> +
> +	id = msgget(msgque->key, msgque->mode | IPC_CREAT | IPC_EXCL);
> +	if (id == -1) {
> +		printf("Failed to create queue\n");
> +		return -errno;
> +	}
> +
> +	if (id != msgque->msq_id) {
> +		printf("Restored queue has wrong id (%d instead of %d)\n",
> +							id, msgque->msq_id);
> +		ret = -EFAULT;
> +		goto destroy;
> +	}
> +
> +	for (i = 0; i < msgque->qnum; i++) {
> +		if (msgsnd(msgque->msq_id, &msgque->messages[i].mtype,
> +			   msgque->messages[i].msize, IPC_NOWAIT) != 0) {
> +			printf("msgsnd failed (%m)\n");
> +			ret = -errno;
> +			goto destroy;
> +		};
> +	}
> +	return 0;
> +
> +destroy:
> +	if (msgctl(id, IPC_RMID, 0))
> +		printf("Failed to destroy queue: %d\n", -errno);
> +	return ret;
> +}
> +
> +int check_and_destroy_queue(struct msgque_data *msgque)
> +{
> +	struct msg1 message;
> +	int cnt = 0, ret;
> +
> +	while (1) {
> +		ret = msgrcv(msgque->msq_id, &message.mtype, MAX_MSG_SIZE,
> +				0, IPC_NOWAIT);
> +		if (ret < 0) {
> +			if (errno == ENOMSG)
> +				break;
> +			printf("Failed to read IPC message: %m\n");
> +			ret = -errno;
> +			goto err;
> +		}
> +		if (ret != msgque->messages[cnt].msize) {
> +			printf("Wrong message size: %d (expected %d)\n", ret,
> +						msgque->messages[cnt].msize);
> +			ret = -EINVAL;
> +			goto err;
> +		}
> +		if (message.mtype != msgque->messages[cnt].mtype) {
> +			printf("Wrong message type\n");
> +			ret = -EINVAL;
> +			goto err;
> +		}
> +		if (memcmp(message.mtext, msgque->messages[cnt].mtext, ret)) {
> +			printf("Wrong message content\n");
> +			ret = -EINVAL;
> +			goto err;
> +		}
> +		cnt++;
> +	}
> +
> +	if (cnt != msgque->qnum) {
> +		printf("Wrong message number\n");
> +		ret = -EINVAL;
> +		goto err;
> +	}
> +
> +	ret = 0;
> +err:
> +	if (msgctl(msgque->msq_id, IPC_RMID, 0)) {
> +		printf("Failed to destroy queue: %d\n", -errno);
> +		return -errno;
> +	}
> +	return ret;
> +}
> +
> +int dump_queue(struct msgque_data *msgque)
> +{
> +	struct msqid64_ds ds;
> +	int kern_id;
> +	int i, ret;
> +
> +	for (kern_id = 0; kern_id < 256; kern_id++) {
> +		ret = msgctl(kern_id, MSG_STAT, &ds);
> +		if (ret < 0) {
> +			if (errno == -EINVAL)
> +				continue;
> +			printf("Failed to get stats for IPC queue with id %d\n",
> +					kern_id);
> +			return -errno;
> +		}
> +
> +		if (ret == msgque->msq_id)
> +			break;
> +	}
> +
> +	msgque->messages = malloc(sizeof(struct msg1) * ds.msg_qnum);
> +	if (msgque->messages == NULL) {
> +		printf("Failed to get stats for IPC queue\n");
> +		return -ENOMEM;
> +	}
> +
> +	msgque->qnum = ds.msg_qnum;
> +	msgque->mode = ds.msg_perm.mode;
> +	msgque->qbytes = ds.msg_qbytes;
> +
> +	for (i = 0; i < msgque->qnum; i++) {
> +		ret = msgrcv(msgque->msq_id, &msgque->messages[i].mtype,
> +				MAX_MSG_SIZE, i, IPC_NOWAIT | MSG_COPY);
> +		if (ret < 0) {
> +			printf("Failed to copy IPC message: %m (%d)\n", errno);
> +			return -errno;
> +		}
> +		msgque->messages[i].msize = ret;
> +	}
> +	return 0;
> +}
> +
> +int fill_msgque(struct msgque_data *msgque)
> +{
> +	struct msg1 msgbuf;
> +
> +	msgbuf.mtype = MSG_TYPE;
> +	memcpy(msgbuf.mtext, TEST_STRING, sizeof(TEST_STRING));
> +	if (msgsnd(msgque->msq_id, &msgbuf.mtype, sizeof(TEST_STRING),
> +				IPC_NOWAIT) != 0) {
> +		printf("First message send failed (%m)\n");
> +		return -errno;
> +	};
> +
> +	msgbuf.mtype = ANOTHER_MSG_TYPE;
> +	memcpy(msgbuf.mtext, ANOTHER_TEST_STRING, sizeof(ANOTHER_TEST_STRING));
> +	if (msgsnd(msgque->msq_id, &msgbuf.mtype, sizeof(ANOTHER_TEST_STRING),
> +				IPC_NOWAIT) != 0) {
> +		printf("Second message send failed (%m)\n");
> +		return -errno;
> +	};
> +	return 0;
> +}
> +
> +int main(int argc, char **argv)
> +{
> +	int msg, pid, err;
> +	struct msgque_data msgque;
> +
> +	if (getuid() != 0) {
> +		printf("Please run the test as root - Exiting.\n");
> +		return ksft_exit_fail();
> +	}
> +
> +	msgque.key = ftok(argv[0], 822155650);
> +	if (msgque.key == -1) {
> +		printf("Can't make key: %d\n", -errno);
> +		return ksft_exit_fail();
> +	}
> +
> +	msgque.msq_id = msgget(msgque.key, IPC_CREAT | IPC_EXCL | 0666);
> +	if (msgque.msq_id == -1) {
> +		err = -errno;
> +		printf("Can't create queue: %d\n", err);
> +		goto err_out;
> +	}
> +
> +	err = fill_msgque(&msgque);
> +	if (err) {
> +		printf("Failed to fill queue: %d\n", err);
> +		goto err_destroy;
> +	}
> +
> +	err = dump_queue(&msgque);
> +	if (err) {
> +		printf("Failed to dump queue: %d\n", err);
> +		goto err_destroy;
> +	}
> +
> +	err = check_and_destroy_queue(&msgque);
> +	if (err) {
> +		printf("Failed to check and destroy queue: %d\n", err);
> +		goto err_out;
> +	}
> +
> +	err = restore_queue(&msgque);
> +	if (err) {
> +		printf("Failed to restore queue: %d\n", err);
> +		goto err_destroy;
> +	}
> +
> +	err = check_and_destroy_queue(&msgque);
> +	if (err) {
> +		printf("Failed to test queue: %d\n", err);
> +		goto err_out;
> +	}
> +	return ksft_exit_pass();
> +
> +err_destroy:
> +	if (msgctl(msgque.msq_id, IPC_RMID, 0)) {
> +		printf("Failed to destroy queue: %d\n", -errno);
> +		return ksft_exit_fail();
> +	}
> +err_out:
> +	return ksft_exit_fail();
> +}
> diff --git a/tools/testing/selftests/ipc/msgque.c b/tools/testing/selftests/ipc/msgque.c
> deleted file mode 100644
> index 1b2ce33..0000000
> --- a/tools/testing/selftests/ipc/msgque.c
> +++ /dev/null
> @@ -1,254 +0,0 @@
> -#include <stdlib.h>
> -#include <stdio.h>
> -#include <string.h>
> -#include <errno.h>
> -#include <linux/msg.h>
> -#include <fcntl.h>
> -
> -#include "../kselftest.h"
> -
> -#define MAX_MSG_SIZE		32
> -
> -struct msg1 {
> -	int msize;
> -	long mtype;
> -	char mtext[MAX_MSG_SIZE];
> -};
> -
> -#define TEST_STRING "Test sysv5 msg"
> -#define MSG_TYPE 1
> -
> -#define ANOTHER_TEST_STRING "Yet another test sysv5 msg"
> -#define ANOTHER_MSG_TYPE 26538
> -
> -struct msgque_data {
> -	key_t key;
> -	int msq_id;
> -	int qbytes;
> -	int qnum;
> -	int mode;
> -	struct msg1 *messages;
> -};
> -
> -int restore_queue(struct msgque_data *msgque)
> -{
> -	int fd, ret, id, i;
> -	char buf[32];
> -
> -	fd = open("/proc/sys/kernel/msg_next_id", O_WRONLY);
> -	if (fd == -1) {
> -		printf("Failed to open /proc/sys/kernel/msg_next_id\n");
> -		return -errno;
> -	}
> -	sprintf(buf, "%d", msgque->msq_id);
> -
> -	ret = write(fd, buf, strlen(buf));
> -	if (ret != strlen(buf)) {
> -		printf("Failed to write to /proc/sys/kernel/msg_next_id\n");
> -		return -errno;
> -	}
> -
> -	id = msgget(msgque->key, msgque->mode | IPC_CREAT | IPC_EXCL);
> -	if (id == -1) {
> -		printf("Failed to create queue\n");
> -		return -errno;
> -	}
> -
> -	if (id != msgque->msq_id) {
> -		printf("Restored queue has wrong id (%d instead of %d)\n",
> -							id, msgque->msq_id);
> -		ret = -EFAULT;
> -		goto destroy;
> -	}
> -
> -	for (i = 0; i < msgque->qnum; i++) {
> -		if (msgsnd(msgque->msq_id, &msgque->messages[i].mtype,
> -			   msgque->messages[i].msize, IPC_NOWAIT) != 0) {
> -			printf("msgsnd failed (%m)\n");
> -			ret = -errno;
> -			goto destroy;
> -		};
> -	}
> -	return 0;
> -
> -destroy:
> -	if (msgctl(id, IPC_RMID, 0))
> -		printf("Failed to destroy queue: %d\n", -errno);
> -	return ret;
> -}
> -
> -int check_and_destroy_queue(struct msgque_data *msgque)
> -{
> -	struct msg1 message;
> -	int cnt = 0, ret;
> -
> -	while (1) {
> -		ret = msgrcv(msgque->msq_id, &message.mtype, MAX_MSG_SIZE,
> -				0, IPC_NOWAIT);
> -		if (ret < 0) {
> -			if (errno == ENOMSG)
> -				break;
> -			printf("Failed to read IPC message: %m\n");
> -			ret = -errno;
> -			goto err;
> -		}
> -		if (ret != msgque->messages[cnt].msize) {
> -			printf("Wrong message size: %d (expected %d)\n", ret,
> -						msgque->messages[cnt].msize);
> -			ret = -EINVAL;
> -			goto err;
> -		}
> -		if (message.mtype != msgque->messages[cnt].mtype) {
> -			printf("Wrong message type\n");
> -			ret = -EINVAL;
> -			goto err;
> -		}
> -		if (memcmp(message.mtext, msgque->messages[cnt].mtext, ret)) {
> -			printf("Wrong message content\n");
> -			ret = -EINVAL;
> -			goto err;
> -		}
> -		cnt++;
> -	}
> -
> -	if (cnt != msgque->qnum) {
> -		printf("Wrong message number\n");
> -		ret = -EINVAL;
> -		goto err;
> -	}
> -
> -	ret = 0;
> -err:
> -	if (msgctl(msgque->msq_id, IPC_RMID, 0)) {
> -		printf("Failed to destroy queue: %d\n", -errno);
> -		return -errno;
> -	}
> -	return ret;
> -}
> -
> -int dump_queue(struct msgque_data *msgque)
> -{
> -	struct msqid64_ds ds;
> -	int kern_id;
> -	int i, ret;
> -
> -	for (kern_id = 0; kern_id < 256; kern_id++) {
> -		ret = msgctl(kern_id, MSG_STAT, &ds);
> -		if (ret < 0) {
> -			if (errno == -EINVAL)
> -				continue;
> -			printf("Failed to get stats for IPC queue with id %d\n",
> -					kern_id);
> -			return -errno;
> -		}
> -
> -		if (ret == msgque->msq_id)
> -			break;
> -	}
> -
> -	msgque->messages = malloc(sizeof(struct msg1) * ds.msg_qnum);
> -	if (msgque->messages == NULL) {
> -		printf("Failed to get stats for IPC queue\n");
> -		return -ENOMEM;
> -	}
> -
> -	msgque->qnum = ds.msg_qnum;
> -	msgque->mode = ds.msg_perm.mode;
> -	msgque->qbytes = ds.msg_qbytes;
> -
> -	for (i = 0; i < msgque->qnum; i++) {
> -		ret = msgrcv(msgque->msq_id, &msgque->messages[i].mtype,
> -				MAX_MSG_SIZE, i, IPC_NOWAIT | MSG_COPY);
> -		if (ret < 0) {
> -			printf("Failed to copy IPC message: %m (%d)\n", errno);
> -			return -errno;
> -		}
> -		msgque->messages[i].msize = ret;
> -	}
> -	return 0;
> -}
> -
> -int fill_msgque(struct msgque_data *msgque)
> -{
> -	struct msg1 msgbuf;
> -
> -	msgbuf.mtype = MSG_TYPE;
> -	memcpy(msgbuf.mtext, TEST_STRING, sizeof(TEST_STRING));
> -	if (msgsnd(msgque->msq_id, &msgbuf.mtype, sizeof(TEST_STRING),
> -				IPC_NOWAIT) != 0) {
> -		printf("First message send failed (%m)\n");
> -		return -errno;
> -	};
> -
> -	msgbuf.mtype = ANOTHER_MSG_TYPE;
> -	memcpy(msgbuf.mtext, ANOTHER_TEST_STRING, sizeof(ANOTHER_TEST_STRING));
> -	if (msgsnd(msgque->msq_id, &msgbuf.mtype, sizeof(ANOTHER_TEST_STRING),
> -				IPC_NOWAIT) != 0) {
> -		printf("Second message send failed (%m)\n");
> -		return -errno;
> -	};
> -	return 0;
> -}
> -
> -int main(int argc, char **argv)
> -{
> -	int msg, pid, err;
> -	struct msgque_data msgque;
> -
> -	if (getuid() != 0) {
> -		printf("Please run the test as root - Exiting.\n");
> -		return ksft_exit_fail();
> -	}
> -
> -	msgque.key = ftok(argv[0], 822155650);
> -	if (msgque.key == -1) {
> -		printf("Can't make key: %d\n", -errno);
> -		return ksft_exit_fail();
> -	}
> -
> -	msgque.msq_id = msgget(msgque.key, IPC_CREAT | IPC_EXCL | 0666);
> -	if (msgque.msq_id == -1) {
> -		err = -errno;
> -		printf("Can't create queue: %d\n", err);
> -		goto err_out;
> -	}
> -
> -	err = fill_msgque(&msgque);
> -	if (err) {
> -		printf("Failed to fill queue: %d\n", err);
> -		goto err_destroy;
> -	}
> -
> -	err = dump_queue(&msgque);
> -	if (err) {
> -		printf("Failed to dump queue: %d\n", err);
> -		goto err_destroy;
> -	}
> -
> -	err = check_and_destroy_queue(&msgque);
> -	if (err) {
> -		printf("Failed to check and destroy queue: %d\n", err);
> -		goto err_out;
> -	}
> -
> -	err = restore_queue(&msgque);
> -	if (err) {
> -		printf("Failed to restore queue: %d\n", err);
> -		goto err_destroy;
> -	}
> -
> -	err = check_and_destroy_queue(&msgque);
> -	if (err) {
> -		printf("Failed to test queue: %d\n", err);
> -		goto err_out;
> -	}
> -	return ksft_exit_pass();
> -
> -err_destroy:
> -	if (msgctl(msgque.msq_id, IPC_RMID, 0)) {
> -		printf("Failed to destroy queue: %d\n", -errno);
> -		return ksft_exit_fail();
> -	}
> -err_out:
> -	return ksft_exit_fail();
> -}
> diff --git a/tools/testing/selftests/mqueue/.gitignore b/tools/testing/selftests/mqueue/.gitignore
> deleted file mode 100644
> index d8d4237..0000000
> --- a/tools/testing/selftests/mqueue/.gitignore
> +++ /dev/null
> @@ -1,2 +0,0 @@
> -mq_open_tests
> -mq_perf_tests
> diff --git a/tools/testing/selftests/mqueue/Makefile b/tools/testing/selftests/mqueue/Makefile
> deleted file mode 100644
> index 0e3b41e..0000000
> --- a/tools/testing/selftests/mqueue/Makefile
> +++ /dev/null
> @@ -1,22 +0,0 @@
> -CFLAGS = -O2
> -
> -all:
> -	$(CC) $(CFLAGS) mq_open_tests.c -o mq_open_tests -lrt
> -	$(CC) $(CFLAGS) -o mq_perf_tests mq_perf_tests.c -lrt -lpthread -lpopt
> -
> -include ../lib.mk
> -
> -override define RUN_TESTS
> -	@./mq_open_tests /test1 || echo "selftests: mq_open_tests [FAIL]"
> -	@./mq_perf_tests || echo "selftests: mq_perf_tests [FAIL]"
> -endef
> -
> -TEST_PROGS := mq_open_tests mq_perf_tests
> -
> -override define EMIT_TESTS
> -	echo "./mq_open_tests /test1 || echo \"selftests: mq_open_tests [FAIL]\""
> -	echo "./mq_perf_tests || echo \"selftests: mq_perf_tests [FAIL]\""
> -endef
> -
> -clean:
> -	rm -f mq_open_tests mq_perf_tests
> diff --git a/tools/testing/selftests/mqueue/mq_open_tests.c b/tools/testing/selftests/mqueue/mq_open_tests.c
> deleted file mode 100644
> index 9c1a5d35..0000000
> --- a/tools/testing/selftests/mqueue/mq_open_tests.c
> +++ /dev/null
> @@ -1,500 +0,0 @@
> -/*
> - * This application is Copyright 2012 Red Hat, Inc.
> - *	Doug Ledford <dledford@...hat.com>
> - *
> - * mq_open_tests is free software: you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation, version 3.
> - *
> - * mq_open_tests is distributed in the hope that it will be useful,
> - * but WITHOUT ANY WARRANTY; without even the implied warranty of
> - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> - * GNU General Public License for more details.
> - *
> - * For the full text of the license, see <http://www.gnu.org/licenses/>.
> - *
> - * mq_open_tests.c
> - *   Tests the various situations that should either succeed or fail to
> - *   open a posix message queue and then reports whether or not they
> - *   did as they were supposed to.
> - *
> - */
> -#include <stdio.h>
> -#include <stdlib.h>
> -#include <unistd.h>
> -#include <fcntl.h>
> -#include <string.h>
> -#include <limits.h>
> -#include <errno.h>
> -#include <sys/types.h>
> -#include <sys/time.h>
> -#include <sys/resource.h>
> -#include <sys/stat.h>
> -#include <mqueue.h>
> -
> -static char *usage =
> -"Usage:\n"
> -"  %s path\n"
> -"\n"
> -"	path	Path name of the message queue to create\n"
> -"\n"
> -"	Note: this program must be run as root in order to enable all tests\n"
> -"\n";
> -
> -char *DEF_MSGS = "/proc/sys/fs/mqueue/msg_default";
> -char *DEF_MSGSIZE = "/proc/sys/fs/mqueue/msgsize_default";
> -char *MAX_MSGS = "/proc/sys/fs/mqueue/msg_max";
> -char *MAX_MSGSIZE = "/proc/sys/fs/mqueue/msgsize_max";
> -
> -int default_settings;
> -struct rlimit saved_limits, cur_limits;
> -int saved_def_msgs, saved_def_msgsize, saved_max_msgs, saved_max_msgsize;
> -int cur_def_msgs, cur_def_msgsize, cur_max_msgs, cur_max_msgsize;
> -FILE *def_msgs, *def_msgsize, *max_msgs, *max_msgsize;
> -char *queue_path;
> -mqd_t queue = -1;
> -
> -static inline void __set(FILE *stream, int value, char *err_msg);
> -void shutdown(int exit_val, char *err_cause, int line_no);
> -static inline int get(FILE *stream);
> -static inline void set(FILE *stream, int value);
> -static inline void getr(int type, struct rlimit *rlim);
> -static inline void setr(int type, struct rlimit *rlim);
> -void validate_current_settings();
> -static inline void test_queue(struct mq_attr *attr, struct mq_attr *result);
> -static inline int test_queue_fail(struct mq_attr *attr, struct mq_attr *result);
> -
> -static inline void __set(FILE *stream, int value, char *err_msg)
> -{
> -	rewind(stream);
> -	if (fprintf(stream, "%d", value) < 0)
> -		perror(err_msg);
> -}
> -
> -
> -void shutdown(int exit_val, char *err_cause, int line_no)
> -{
> -	static int in_shutdown = 0;
> -
> -	/* In case we get called recursively by a set() call below */
> -	if (in_shutdown++)
> -		return;
> -
> -	if (seteuid(0) == -1)
> -		perror("seteuid() failed");
> -
> -	if (queue != -1)
> -		if (mq_close(queue))
> -			perror("mq_close() during shutdown");
> -	if (queue_path)
> -		/*
> -		 * Be silent if this fails, if we cleaned up already it's
> -		 * expected to fail
> -		 */
> -		mq_unlink(queue_path);
> -	if (default_settings) {
> -		if (saved_def_msgs)
> -			__set(def_msgs, saved_def_msgs,
> -			      "failed to restore saved_def_msgs");
> -		if (saved_def_msgsize)
> -			__set(def_msgsize, saved_def_msgsize,
> -			      "failed to restore saved_def_msgsize");
> -	}
> -	if (saved_max_msgs)
> -		__set(max_msgs, saved_max_msgs,
> -		      "failed to restore saved_max_msgs");
> -	if (saved_max_msgsize)
> -		__set(max_msgsize, saved_max_msgsize,
> -		      "failed to restore saved_max_msgsize");
> -	if (exit_val)
> -		error(exit_val, errno, "%s at %d", err_cause, line_no);
> -	exit(0);
> -}
> -
> -static inline int get(FILE *stream)
> -{
> -	int value;
> -	rewind(stream);
> -	if (fscanf(stream, "%d", &value) != 1)
> -		shutdown(4, "Error reading /proc entry", __LINE__ - 1);
> -	return value;
> -}
> -
> -static inline void set(FILE *stream, int value)
> -{
> -	int new_value;
> -
> -	rewind(stream);
> -	if (fprintf(stream, "%d", value) < 0)
> -		return shutdown(5, "Failed writing to /proc file",
> -				__LINE__ - 1);
> -	new_value = get(stream);
> -	if (new_value != value)
> -		return shutdown(5, "We didn't get what we wrote to /proc back",
> -				__LINE__ - 1);
> -}
> -
> -static inline void getr(int type, struct rlimit *rlim)
> -{
> -	if (getrlimit(type, rlim))
> -		shutdown(6, "getrlimit()", __LINE__ - 1);
> -}
> -
> -static inline void setr(int type, struct rlimit *rlim)
> -{
> -	if (setrlimit(type, rlim))
> -		shutdown(7, "setrlimit()", __LINE__ - 1);
> -}
> -
> -void validate_current_settings()
> -{
> -	int rlim_needed;
> -
> -	if (cur_limits.rlim_cur < 4096) {
> -		printf("Current rlimit value for POSIX message queue bytes is "
> -		       "unreasonably low,\nincreasing.\n\n");
> -		cur_limits.rlim_cur = 8192;
> -		cur_limits.rlim_max = 16384;
> -		setr(RLIMIT_MSGQUEUE, &cur_limits);
> -	}
> -
> -	if (default_settings) {
> -		rlim_needed = (cur_def_msgs + 1) * (cur_def_msgsize + 1 +
> -						    2 * sizeof(void *));
> -		if (rlim_needed > cur_limits.rlim_cur) {
> -			printf("Temporarily lowering default queue parameters "
> -			       "to something that will work\n"
> -			       "with the current rlimit values.\n\n");
> -			set(def_msgs, 10);
> -			cur_def_msgs = 10;
> -			set(def_msgsize, 128);
> -			cur_def_msgsize = 128;
> -		}
> -	} else {
> -		rlim_needed = (cur_max_msgs + 1) * (cur_max_msgsize + 1 +
> -						    2 * sizeof(void *));
> -		if (rlim_needed > cur_limits.rlim_cur) {
> -			printf("Temporarily lowering maximum queue parameters "
> -			       "to something that will work\n"
> -			       "with the current rlimit values in case this is "
> -			       "a kernel that ties the default\n"
> -			       "queue parameters to the maximum queue "
> -			       "parameters.\n\n");
> -			set(max_msgs, 10);
> -			cur_max_msgs = 10;
> -			set(max_msgsize, 128);
> -			cur_max_msgsize = 128;
> -		}
> -	}
> -}
> -
> -/*
> - * test_queue - Test opening a queue, shutdown if we fail.  This should
> - * only be called in situations that should never fail.  We clean up
> - * after ourselves and return the queue attributes in *result.
> - */
> -static inline void test_queue(struct mq_attr *attr, struct mq_attr *result)
> -{
> -	int flags = O_RDWR | O_EXCL | O_CREAT;
> -	int perms = DEFFILEMODE;
> -
> -	if ((queue = mq_open(queue_path, flags, perms, attr)) == -1)
> -		shutdown(1, "mq_open()", __LINE__);
> -	if (mq_getattr(queue, result))
> -		shutdown(1, "mq_getattr()", __LINE__);
> -	if (mq_close(queue))
> -		shutdown(1, "mq_close()", __LINE__);
> -	queue = -1;
> -	if (mq_unlink(queue_path))
> -		shutdown(1, "mq_unlink()", __LINE__);
> -}
> -
> -/*
> - * Same as test_queue above, but failure is not fatal.
> - * Returns:
> - * 0 - Failed to create a queue
> - * 1 - Created a queue, attributes in *result
> - */
> -static inline int test_queue_fail(struct mq_attr *attr, struct mq_attr *result)
> -{
> -	int flags = O_RDWR | O_EXCL | O_CREAT;
> -	int perms = DEFFILEMODE;
> -
> -	if ((queue = mq_open(queue_path, flags, perms, attr)) == -1)
> -		return 0;
> -	if (mq_getattr(queue, result))
> -		shutdown(1, "mq_getattr()", __LINE__);
> -	if (mq_close(queue))
> -		shutdown(1, "mq_close()", __LINE__);
> -	queue = -1;
> -	if (mq_unlink(queue_path))
> -		shutdown(1, "mq_unlink()", __LINE__);
> -	return 1;
> -}
> -
> -int main(int argc, char *argv[])
> -{
> -	struct mq_attr attr, result;
> -
> -	if (argc != 2) {
> -		fprintf(stderr, "Must pass a valid queue name\n\n");
> -		fprintf(stderr, usage, argv[0]);
> -		exit(1);
> -	}
> -
> -	/*
> -	 * Although we can create a msg queue with a non-absolute path name,
> -	 * unlink will fail.  So, if the name doesn't start with a /, add one
> -	 * when we save it.
> -	 */
> -	if (*argv[1] == '/')
> -		queue_path = strdup(argv[1]);
> -	else {
> -		queue_path = malloc(strlen(argv[1]) + 2);
> -		if (!queue_path) {
> -			perror("malloc()");
> -			exit(1);
> -		}
> -		queue_path[0] = '/';
> -		queue_path[1] = 0;
> -		strcat(queue_path, argv[1]);
> -	}
> -
> -	if (getuid() != 0) {
> -		fprintf(stderr, "Not running as root, but almost all tests "
> -			"require root in order to modify\nsystem settings.  "
> -			"Exiting.\n");
> -		exit(1);
> -	}
> -
> -	/* Find out what files there are for us to make tweaks in */
> -	def_msgs = fopen(DEF_MSGS, "r+");
> -	def_msgsize = fopen(DEF_MSGSIZE, "r+");
> -	max_msgs = fopen(MAX_MSGS, "r+");
> -	max_msgsize = fopen(MAX_MSGSIZE, "r+");
> -
> -	if (!max_msgs)
> -		shutdown(2, "Failed to open msg_max", __LINE__);
> -	if (!max_msgsize)
> -		shutdown(2, "Failed to open msgsize_max", __LINE__);
> -	if (def_msgs || def_msgsize)
> -		default_settings = 1;
> -
> -	/* Load up the current system values for everything we can */
> -	getr(RLIMIT_MSGQUEUE, &saved_limits);
> -	cur_limits = saved_limits;
> -	if (default_settings) {
> -		saved_def_msgs = cur_def_msgs = get(def_msgs);
> -		saved_def_msgsize = cur_def_msgsize = get(def_msgsize);
> -	}
> -	saved_max_msgs = cur_max_msgs = get(max_msgs);
> -	saved_max_msgsize = cur_max_msgsize = get(max_msgsize);
> -
> -	/* Tell the user our initial state */
> -	printf("\nInitial system state:\n");
> -	printf("\tUsing queue path:\t\t%s\n", queue_path);
> -	printf("\tRLIMIT_MSGQUEUE(soft):\t\t%ld\n",
> -		(long) saved_limits.rlim_cur);
> -	printf("\tRLIMIT_MSGQUEUE(hard):\t\t%ld\n",
> -		(long) saved_limits.rlim_max);
> -	printf("\tMaximum Message Size:\t\t%d\n", saved_max_msgsize);
> -	printf("\tMaximum Queue Size:\t\t%d\n", saved_max_msgs);
> -	if (default_settings) {
> -		printf("\tDefault Message Size:\t\t%d\n", saved_def_msgsize);
> -		printf("\tDefault Queue Size:\t\t%d\n", saved_def_msgs);
> -	} else {
> -		printf("\tDefault Message Size:\t\tNot Supported\n");
> -		printf("\tDefault Queue Size:\t\tNot Supported\n");
> -	}
> -	printf("\n");
> -
> -	validate_current_settings();
> -
> -	printf("Adjusted system state for testing:\n");
> -	printf("\tRLIMIT_MSGQUEUE(soft):\t\t%ld\n", (long) cur_limits.rlim_cur);
> -	printf("\tRLIMIT_MSGQUEUE(hard):\t\t%ld\n", (long) cur_limits.rlim_max);
> -	printf("\tMaximum Message Size:\t\t%d\n", cur_max_msgsize);
> -	printf("\tMaximum Queue Size:\t\t%d\n", cur_max_msgs);
> -	if (default_settings) {
> -		printf("\tDefault Message Size:\t\t%d\n", cur_def_msgsize);
> -		printf("\tDefault Queue Size:\t\t%d\n", cur_def_msgs);
> -	}
> -
> -	printf("\n\nTest series 1, behavior when no attr struct "
> -	       "passed to mq_open:\n");
> -	if (!default_settings) {
> -		test_queue(NULL, &result);
> -		printf("Given sane system settings, mq_open without an attr "
> -		       "struct succeeds:\tPASS\n");
> -		if (result.mq_maxmsg != cur_max_msgs ||
> -		    result.mq_msgsize != cur_max_msgsize) {
> -			printf("Kernel does not support setting the default "
> -			       "mq attributes,\nbut also doesn't tie the "
> -			       "defaults to the maximums:\t\t\tPASS\n");
> -		} else {
> -			set(max_msgs, ++cur_max_msgs);
> -			set(max_msgsize, ++cur_max_msgsize);
> -			test_queue(NULL, &result);
> -			if (result.mq_maxmsg == cur_max_msgs &&
> -			    result.mq_msgsize == cur_max_msgsize)
> -				printf("Kernel does not support setting the "
> -				       "default mq attributes and\n"
> -				       "also ties system wide defaults to "
> -				       "the system wide maximums:\t\t"
> -				       "FAIL\n");
> -			else
> -				printf("Kernel does not support setting the "
> -				       "default mq attributes,\n"
> -				       "but also doesn't tie the defaults to "
> -				       "the maximums:\t\t\tPASS\n");
> -		}
> -	} else {
> -		printf("Kernel supports setting defaults separately from "
> -		       "maximums:\t\tPASS\n");
> -		/*
> -		 * While we are here, go ahead and test that the kernel
> -		 * properly follows the default settings
> -		 */
> -		test_queue(NULL, &result);
> -		printf("Given sane values, mq_open without an attr struct "
> -		       "succeeds:\t\tPASS\n");
> -		if (result.mq_maxmsg != cur_def_msgs ||
> -		    result.mq_msgsize != cur_def_msgsize)
> -			printf("Kernel supports setting defaults, but does "
> -			       "not actually honor them:\tFAIL\n\n");
> -		else {
> -			set(def_msgs, ++cur_def_msgs);
> -			set(def_msgsize, ++cur_def_msgsize);
> -			/* In case max was the same as the default */
> -			set(max_msgs, ++cur_max_msgs);
> -			set(max_msgsize, ++cur_max_msgsize);
> -			test_queue(NULL, &result);
> -			if (result.mq_maxmsg != cur_def_msgs ||
> -			    result.mq_msgsize != cur_def_msgsize)
> -				printf("Kernel supports setting defaults, but "
> -				       "does not actually honor them:\t"
> -				       "FAIL\n");
> -			else
> -				printf("Kernel properly honors default setting "
> -				       "knobs:\t\t\t\tPASS\n");
> -		}
> -		set(def_msgs, cur_max_msgs + 1);
> -		cur_def_msgs = cur_max_msgs + 1;
> -		set(def_msgsize, cur_max_msgsize + 1);
> -		cur_def_msgsize = cur_max_msgsize + 1;
> -		if (cur_def_msgs * (cur_def_msgsize + 2 * sizeof(void *)) >=
> -		    cur_limits.rlim_cur) {
> -			cur_limits.rlim_cur = (cur_def_msgs + 2) *
> -				(cur_def_msgsize + 2 * sizeof(void *));
> -			cur_limits.rlim_max = 2 * cur_limits.rlim_cur;
> -			setr(RLIMIT_MSGQUEUE, &cur_limits);
> -		}
> -		if (test_queue_fail(NULL, &result)) {
> -			if (result.mq_maxmsg == cur_max_msgs &&
> -			    result.mq_msgsize == cur_max_msgsize)
> -				printf("Kernel properly limits default values "
> -				       "to lesser of default/max:\t\tPASS\n");
> -			else
> -				printf("Kernel does not properly set default "
> -				       "queue parameters when\ndefaults > "
> -				       "max:\t\t\t\t\t\t\t\tFAIL\n");
> -		} else
> -			printf("Kernel fails to open mq because defaults are "
> -			       "greater than maximums:\tFAIL\n");
> -		set(def_msgs, --cur_def_msgs);
> -		set(def_msgsize, --cur_def_msgsize);
> -		cur_limits.rlim_cur = cur_limits.rlim_max = cur_def_msgs *
> -			cur_def_msgsize;
> -		setr(RLIMIT_MSGQUEUE, &cur_limits);
> -		if (test_queue_fail(NULL, &result))
> -			printf("Kernel creates queue even though defaults "
> -			       "would exceed\nrlimit setting:"
> -			       "\t\t\t\t\t\t\t\tFAIL\n");
> -		else
> -			printf("Kernel properly fails to create queue when "
> -			       "defaults would\nexceed rlimit:"
> -			       "\t\t\t\t\t\t\t\tPASS\n");
> -	}
> -
> -	/*
> -	 * Test #2 - open with an attr struct that exceeds rlimit
> -	 */
> -	printf("\n\nTest series 2, behavior when attr struct is "
> -	       "passed to mq_open:\n");
> -	cur_max_msgs = 32;
> -	cur_max_msgsize = cur_limits.rlim_max >> 4;
> -	set(max_msgs, cur_max_msgs);
> -	set(max_msgsize, cur_max_msgsize);
> -	attr.mq_maxmsg = cur_max_msgs;
> -	attr.mq_msgsize = cur_max_msgsize;
> -	if (test_queue_fail(&attr, &result))
> -		printf("Queue open in excess of rlimit max when euid = 0 "
> -		       "succeeded:\t\tFAIL\n");
> -	else
> -		printf("Queue open in excess of rlimit max when euid = 0 "
> -		       "failed:\t\tPASS\n");
> -	attr.mq_maxmsg = cur_max_msgs + 1;
> -	attr.mq_msgsize = 10;
> -	if (test_queue_fail(&attr, &result))
> -		printf("Queue open with mq_maxmsg > limit when euid = 0 "
> -		       "succeeded:\t\tPASS\n");
> -	else
> -		printf("Queue open with mq_maxmsg > limit when euid = 0 "
> -		       "failed:\t\tFAIL\n");
> -	attr.mq_maxmsg = 1;
> -	attr.mq_msgsize = cur_max_msgsize + 1;
> -	if (test_queue_fail(&attr, &result))
> -		printf("Queue open with mq_msgsize > limit when euid = 0 "
> -		       "succeeded:\t\tPASS\n");
> -	else
> -		printf("Queue open with mq_msgsize > limit when euid = 0 "
> -		       "failed:\t\tFAIL\n");
> -	attr.mq_maxmsg = 65536;
> -	attr.mq_msgsize = 65536;
> -	if (test_queue_fail(&attr, &result))
> -		printf("Queue open with total size > 2GB when euid = 0 "
> -		       "succeeded:\t\tFAIL\n");
> -	else
> -		printf("Queue open with total size > 2GB when euid = 0 "
> -		       "failed:\t\t\tPASS\n");
> -
> -	if (seteuid(99) == -1) {
> -		perror("seteuid() failed");
> -		exit(1);
> -	}
> -
> -	attr.mq_maxmsg = cur_max_msgs;
> -	attr.mq_msgsize = cur_max_msgsize;
> -	if (test_queue_fail(&attr, &result))
> -		printf("Queue open in excess of rlimit max when euid = 99 "
> -		       "succeeded:\t\tFAIL\n");
> -	else
> -		printf("Queue open in excess of rlimit max when euid = 99 "
> -		       "failed:\t\tPASS\n");
> -	attr.mq_maxmsg = cur_max_msgs + 1;
> -	attr.mq_msgsize = 10;
> -	if (test_queue_fail(&attr, &result))
> -		printf("Queue open with mq_maxmsg > limit when euid = 99 "
> -		       "succeeded:\t\tFAIL\n");
> -	else
> -		printf("Queue open with mq_maxmsg > limit when euid = 99 "
> -		       "failed:\t\tPASS\n");
> -	attr.mq_maxmsg = 1;
> -	attr.mq_msgsize = cur_max_msgsize + 1;
> -	if (test_queue_fail(&attr, &result))
> -		printf("Queue open with mq_msgsize > limit when euid = 99 "
> -		       "succeeded:\t\tFAIL\n");
> -	else
> -		printf("Queue open with mq_msgsize > limit when euid = 99 "
> -		       "failed:\t\tPASS\n");
> -	attr.mq_maxmsg = 65536;
> -	attr.mq_msgsize = 65536;
> -	if (test_queue_fail(&attr, &result))
> -		printf("Queue open with total size > 2GB when euid = 99 "
> -		       "succeeded:\t\tFAIL\n");
> -	else
> -		printf("Queue open with total size > 2GB when euid = 99 "
> -		       "failed:\t\t\tPASS\n");
> -
> -	shutdown(0,"",0);
> -}
> diff --git a/tools/testing/selftests/mqueue/mq_perf_tests.c b/tools/testing/selftests/mqueue/mq_perf_tests.c
> deleted file mode 100644
> index 8519e9e..0000000
> --- a/tools/testing/selftests/mqueue/mq_perf_tests.c
> +++ /dev/null
> @@ -1,742 +0,0 @@
> -/*
> - * This application is Copyright 2012 Red Hat, Inc.
> - *	Doug Ledford <dledford@...hat.com>
> - *
> - * mq_perf_tests is free software: you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation, version 3.
> - *
> - * mq_perf_tests is distributed in the hope that it will be useful,
> - * but WITHOUT ANY WARRANTY; without even the implied warranty of
> - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> - * GNU General Public License for more details.
> - *
> - * For the full text of the license, see <http://www.gnu.org/licenses/>.
> - *
> - * mq_perf_tests.c
> - *   Tests various types of message queue workloads, concentrating on those
> - *   situations that invole large message sizes, large message queue depths,
> - *   or both, and reports back useful metrics about kernel message queue
> - *   performance.
> - *
> - */
> -#define _GNU_SOURCE
> -#include <stdio.h>
> -#include <stdlib.h>
> -#include <unistd.h>
> -#include <fcntl.h>
> -#include <string.h>
> -#include <limits.h>
> -#include <errno.h>
> -#include <signal.h>
> -#include <pthread.h>
> -#include <sched.h>
> -#include <sys/types.h>
> -#include <sys/time.h>
> -#include <sys/resource.h>
> -#include <sys/stat.h>
> -#include <mqueue.h>
> -#include <popt.h>
> -
> -static char *usage =
> -"Usage:\n"
> -"  %s [-c #[,#..] -f] path\n"
> -"\n"
> -"	-c #	Skip most tests and go straight to a high queue depth test\n"
> -"		and then run that test continuously (useful for running at\n"
> -"		the same time as some other workload to see how much the\n"
> -"		cache thrashing caused by adding messages to a very deep\n"
> -"		queue impacts the performance of other programs).  The number\n"
> -"		indicates which CPU core we should bind the process to during\n"
> -"		the run.  If you have more than one physical CPU, then you\n"
> -"		will need one copy per physical CPU package, and you should\n"
> -"		specify the CPU cores to pin ourself to via a comma separated\n"
> -"		list of CPU values.\n"
> -"	-f	Only usable with continuous mode.  Pin ourself to the CPUs\n"
> -"		as requested, then instead of looping doing a high mq\n"
> -"		workload, just busy loop.  This will allow us to lock up a\n"
> -"		single CPU just like we normally would, but without actually\n"
> -"		thrashing the CPU cache.  This is to make it easier to get\n"
> -"		comparable numbers from some other workload running on the\n"
> -"		other CPUs.  One set of numbers with # CPUs locked up running\n"
> -"		an mq workload, and another set of numbers with those same\n"
> -"		CPUs locked away from the test workload, but not doing\n"
> -"		anything to trash the cache like the mq workload might.\n"
> -"	path	Path name of the message queue to create\n"
> -"\n"
> -"	Note: this program must be run as root in order to enable all tests\n"
> -"\n";
> -
> -char *MAX_MSGS = "/proc/sys/fs/mqueue/msg_max";
> -char *MAX_MSGSIZE = "/proc/sys/fs/mqueue/msgsize_max";
> -
> -#define min(a, b) ((a) < (b) ? (a) : (b))
> -#define MAX_CPUS 64
> -char *cpu_option_string;
> -int cpus_to_pin[MAX_CPUS];
> -int num_cpus_to_pin;
> -pthread_t cpu_threads[MAX_CPUS];
> -pthread_t main_thread;
> -cpu_set_t *cpu_set;
> -int cpu_set_size;
> -int cpus_online;
> -
> -#define MSG_SIZE 16
> -#define TEST1_LOOPS 10000000
> -#define TEST2_LOOPS 100000
> -int continuous_mode;
> -int continuous_mode_fake;
> -
> -struct rlimit saved_limits, cur_limits;
> -int saved_max_msgs, saved_max_msgsize;
> -int cur_max_msgs, cur_max_msgsize;
> -FILE *max_msgs, *max_msgsize;
> -int cur_nice;
> -char *queue_path = "/mq_perf_tests";
> -mqd_t queue = -1;
> -struct mq_attr result;
> -int mq_prio_max;
> -
> -const struct poptOption options[] = {
> -	{
> -		.longName = "continuous",
> -		.shortName = 'c',
> -		.argInfo = POPT_ARG_STRING,
> -		.arg = &cpu_option_string,
> -		.val = 'c',
> -		.descrip = "Run continuous tests at a high queue depth in "
> -			"order to test the effects of cache thrashing on "
> -			"other tasks on the system.  This test is intended "
> -			"to be run on one core of each physical CPU while "
> -			"some other CPU intensive task is run on all the other "
> -			"cores of that same physical CPU and the other task "
> -			"is timed.  It is assumed that the process of adding "
> -			"messages to the message queue in a tight loop will "
> -			"impact that other task to some degree.  Once the "
> -			"tests are performed in this way, you should then "
> -			"re-run the tests using fake mode in order to check "
> -			"the difference in time required to perform the CPU "
> -			"intensive task",
> -		.argDescrip = "cpu[,cpu]",
> -	},
> -	{
> -		.longName = "fake",
> -		.shortName = 'f',
> -		.argInfo = POPT_ARG_NONE,
> -		.arg = &continuous_mode_fake,
> -		.val = 0,
> -		.descrip = "Tie up the CPUs that we would normally tie up in"
> -			"continuous mode, but don't actually do any mq stuff, "
> -			"just keep the CPU busy so it can't be used to process "
> -			"system level tasks as this would free up resources on "
> -			"the other CPU cores and skew the comparison between "
> -			"the no-mqueue work and mqueue work tests",
> -		.argDescrip = NULL,
> -	},
> -	{
> -		.longName = "path",
> -		.shortName = 'p',
> -		.argInfo = POPT_ARG_STRING | POPT_ARGFLAG_SHOW_DEFAULT,
> -		.arg = &queue_path,
> -		.val = 'p',
> -		.descrip = "The name of the path to use in the mqueue "
> -			"filesystem for our tests",
> -		.argDescrip = "pathname",
> -	},
> -	POPT_AUTOHELP
> -	POPT_TABLEEND
> -};
> -
> -static inline void __set(FILE *stream, int value, char *err_msg);
> -void shutdown(int exit_val, char *err_cause, int line_no);
> -void sig_action_SIGUSR1(int signum, siginfo_t *info, void *context);
> -void sig_action(int signum, siginfo_t *info, void *context);
> -static inline int get(FILE *stream);
> -static inline void set(FILE *stream, int value);
> -static inline int try_set(FILE *stream, int value);
> -static inline void getr(int type, struct rlimit *rlim);
> -static inline void setr(int type, struct rlimit *rlim);
> -static inline void open_queue(struct mq_attr *attr);
> -void increase_limits(void);
> -
> -static inline void __set(FILE *stream, int value, char *err_msg)
> -{
> -	rewind(stream);
> -	if (fprintf(stream, "%d", value) < 0)
> -		perror(err_msg);
> -}
> -
> -
> -void shutdown(int exit_val, char *err_cause, int line_no)
> -{
> -	static int in_shutdown = 0;
> -	int errno_at_shutdown = errno;
> -	int i;
> -
> -	/* In case we get called by multiple threads or from an sighandler */
> -	if (in_shutdown++)
> -		return;
> -
> -	for (i = 0; i < num_cpus_to_pin; i++)
> -		if (cpu_threads[i]) {
> -			pthread_kill(cpu_threads[i], SIGUSR1);
> -			pthread_join(cpu_threads[i], NULL);
> -		}
> -
> -	if (queue != -1)
> -		if (mq_close(queue))
> -			perror("mq_close() during shutdown");
> -	if (queue_path)
> -		/*
> -		 * Be silent if this fails, if we cleaned up already it's
> -		 * expected to fail
> -		 */
> -		mq_unlink(queue_path);
> -	if (saved_max_msgs)
> -		__set(max_msgs, saved_max_msgs,
> -		      "failed to restore saved_max_msgs");
> -	if (saved_max_msgsize)
> -		__set(max_msgsize, saved_max_msgsize,
> -		      "failed to restore saved_max_msgsize");
> -	if (exit_val)
> -		error(exit_val, errno_at_shutdown, "%s at %d",
> -		      err_cause, line_no);
> -	exit(0);
> -}
> -
> -void sig_action_SIGUSR1(int signum, siginfo_t *info, void *context)
> -{
> -	if (pthread_self() != main_thread)
> -		pthread_exit(0);
> -	else {
> -		fprintf(stderr, "Caught signal %d in SIGUSR1 handler, "
> -				"exiting\n", signum);
> -		shutdown(0, "", 0);
> -		fprintf(stderr, "\n\nReturned from shutdown?!?!\n\n");
> -		exit(0);
> -	}
> -}
> -
> -void sig_action(int signum, siginfo_t *info, void *context)
> -{
> -	if (pthread_self() != main_thread)
> -		pthread_kill(main_thread, signum);
> -	else {
> -		fprintf(stderr, "Caught signal %d, exiting\n", signum);
> -		shutdown(0, "", 0);
> -		fprintf(stderr, "\n\nReturned from shutdown?!?!\n\n");
> -		exit(0);
> -	}
> -}
> -
> -static inline int get(FILE *stream)
> -{
> -	int value;
> -	rewind(stream);
> -	if (fscanf(stream, "%d", &value) != 1)
> -		shutdown(4, "Error reading /proc entry", __LINE__);
> -	return value;
> -}
> -
> -static inline void set(FILE *stream, int value)
> -{
> -	int new_value;
> -
> -	rewind(stream);
> -	if (fprintf(stream, "%d", value) < 0)
> -		return shutdown(5, "Failed writing to /proc file", __LINE__);
> -	new_value = get(stream);
> -	if (new_value != value)
> -		return shutdown(5, "We didn't get what we wrote to /proc back",
> -				__LINE__);
> -}
> -
> -static inline int try_set(FILE *stream, int value)
> -{
> -	int new_value;
> -
> -	rewind(stream);
> -	fprintf(stream, "%d", value);
> -	new_value = get(stream);
> -	return new_value == value;
> -}
> -
> -static inline void getr(int type, struct rlimit *rlim)
> -{
> -	if (getrlimit(type, rlim))
> -		shutdown(6, "getrlimit()", __LINE__);
> -}
> -
> -static inline void setr(int type, struct rlimit *rlim)
> -{
> -	if (setrlimit(type, rlim))
> -		shutdown(7, "setrlimit()", __LINE__);
> -}
> -
> -/**
> - * open_queue - open the global queue for testing
> - * @attr - An attr struct specifying the desired queue traits
> - * @result - An attr struct that lists the actual traits the queue has
> - *
> - * This open is not allowed to fail, failure will result in an orderly
> - * shutdown of the program.  The global queue_path is used to set what
> - * queue to open, the queue descriptor is saved in the global queue
> - * variable.
> - */
> -static inline void open_queue(struct mq_attr *attr)
> -{
> -	int flags = O_RDWR | O_EXCL | O_CREAT | O_NONBLOCK;
> -	int perms = DEFFILEMODE;
> -
> -	queue = mq_open(queue_path, flags, perms, attr);
> -	if (queue == -1)
> -		shutdown(1, "mq_open()", __LINE__);
> -	if (mq_getattr(queue, &result))
> -		shutdown(1, "mq_getattr()", __LINE__);
> -	printf("\n\tQueue %s created:\n", queue_path);
> -	printf("\t\tmq_flags:\t\t\t%s\n", result.mq_flags & O_NONBLOCK ?
> -	       "O_NONBLOCK" : "(null)");
> -	printf("\t\tmq_maxmsg:\t\t\t%lu\n", result.mq_maxmsg);
> -	printf("\t\tmq_msgsize:\t\t\t%lu\n", result.mq_msgsize);
> -	printf("\t\tmq_curmsgs:\t\t\t%lu\n", result.mq_curmsgs);
> -}
> -
> -void *fake_cont_thread(void *arg)
> -{
> -	int i;
> -
> -	for (i = 0; i < num_cpus_to_pin; i++)
> -		if (cpu_threads[i] == pthread_self())
> -			break;
> -	printf("\tStarted fake continuous mode thread %d on CPU %d\n", i,
> -	       cpus_to_pin[i]);
> -	while (1)
> -		;
> -}
> -
> -void *cont_thread(void *arg)
> -{
> -	char buff[MSG_SIZE];
> -	int i, priority;
> -
> -	for (i = 0; i < num_cpus_to_pin; i++)
> -		if (cpu_threads[i] == pthread_self())
> -			break;
> -	printf("\tStarted continuous mode thread %d on CPU %d\n", i,
> -	       cpus_to_pin[i]);
> -	while (1) {
> -		while (mq_send(queue, buff, sizeof(buff), 0) == 0)
> -			;
> -		mq_receive(queue, buff, sizeof(buff), &priority);
> -	}
> -}
> -
> -#define drain_queue() \
> -	while (mq_receive(queue, buff, MSG_SIZE, &prio_in) == MSG_SIZE)
> -
> -#define do_untimed_send() \
> -	do { \
> -		if (mq_send(queue, buff, MSG_SIZE, prio_out)) \
> -			shutdown(3, "Test send failure", __LINE__); \
> -	} while (0)
> -
> -#define do_send_recv() \
> -	do { \
> -		clock_gettime(clock, &start); \
> -		if (mq_send(queue, buff, MSG_SIZE, prio_out)) \
> -			shutdown(3, "Test send failure", __LINE__); \
> -		clock_gettime(clock, &middle); \
> -		if (mq_receive(queue, buff, MSG_SIZE, &prio_in) != MSG_SIZE) \
> -			shutdown(3, "Test receive failure", __LINE__); \
> -		clock_gettime(clock, &end); \
> -		nsec = ((middle.tv_sec - start.tv_sec) * 1000000000) + \
> -			(middle.tv_nsec - start.tv_nsec); \
> -		send_total.tv_nsec += nsec; \
> -		if (send_total.tv_nsec >= 1000000000) { \
> -			send_total.tv_sec++; \
> -			send_total.tv_nsec -= 1000000000; \
> -		} \
> -		nsec = ((end.tv_sec - middle.tv_sec) * 1000000000) + \
> -			(end.tv_nsec - middle.tv_nsec); \
> -		recv_total.tv_nsec += nsec; \
> -		if (recv_total.tv_nsec >= 1000000000) { \
> -			recv_total.tv_sec++; \
> -			recv_total.tv_nsec -= 1000000000; \
> -		} \
> -	} while (0)
> -
> -struct test {
> -	char *desc;
> -	void (*func)(int *);
> -};
> -
> -void const_prio(int *prio)
> -{
> -	return;
> -}
> -
> -void inc_prio(int *prio)
> -{
> -	if (++*prio == mq_prio_max)
> -		*prio = 0;
> -}
> -
> -void dec_prio(int *prio)
> -{
> -	if (--*prio < 0)
> -		*prio = mq_prio_max - 1;
> -}
> -
> -void random_prio(int *prio)
> -{
> -	*prio = random() % mq_prio_max;
> -}
> -
> -struct test test2[] = {
> -	{"\n\tTest #2a: Time send/recv message, queue full, constant prio\n",
> -		const_prio},
> -	{"\n\tTest #2b: Time send/recv message, queue full, increasing prio\n",
> -		inc_prio},
> -	{"\n\tTest #2c: Time send/recv message, queue full, decreasing prio\n",
> -		dec_prio},
> -	{"\n\tTest #2d: Time send/recv message, queue full, random prio\n",
> -		random_prio},
> -	{NULL, NULL}
> -};
> -
> -/**
> - * Tests to perform (all done with MSG_SIZE messages):
> - *
> - * 1) Time to add/remove message with 0 messages on queue
> - * 1a) with constant prio
> - * 2) Time to add/remove message when queue close to capacity:
> - * 2a) with constant prio
> - * 2b) with increasing prio
> - * 2c) with decreasing prio
> - * 2d) with random prio
> - * 3) Test limits of priorities honored (double check _SC_MQ_PRIO_MAX)
> - */
> -void *perf_test_thread(void *arg)
> -{
> -	char buff[MSG_SIZE];
> -	int prio_out, prio_in;
> -	int i;
> -	clockid_t clock;
> -	pthread_t *t;
> -	struct timespec res, start, middle, end, send_total, recv_total;
> -	unsigned long long nsec;
> -	struct test *cur_test;
> -
> -	t = &cpu_threads[0];
> -	printf("\n\tStarted mqueue performance test thread on CPU %d\n",
> -	       cpus_to_pin[0]);
> -	mq_prio_max = sysconf(_SC_MQ_PRIO_MAX);
> -	if (mq_prio_max == -1)
> -		shutdown(2, "sysconf(_SC_MQ_PRIO_MAX)", __LINE__);
> -	if (pthread_getcpuclockid(cpu_threads[0], &clock) != 0)
> -		shutdown(2, "pthread_getcpuclockid", __LINE__);
> -
> -	if (clock_getres(clock, &res))
> -		shutdown(2, "clock_getres()", __LINE__);
> -
> -	printf("\t\tMax priorities:\t\t\t%d\n", mq_prio_max);
> -	printf("\t\tClock resolution:\t\t%lu nsec%s\n", res.tv_nsec,
> -	       res.tv_nsec > 1 ? "s" : "");
> -
> -
> -
> -	printf("\n\tTest #1: Time send/recv message, queue empty\n");
> -	printf("\t\t(%d iterations)\n", TEST1_LOOPS);
> -	prio_out = 0;
> -	send_total.tv_sec = 0;
> -	send_total.tv_nsec = 0;
> -	recv_total.tv_sec = 0;
> -	recv_total.tv_nsec = 0;
> -	for (i = 0; i < TEST1_LOOPS; i++)
> -		do_send_recv();
> -	printf("\t\tSend msg:\t\t\t%ld.%lus total time\n",
> -	       send_total.tv_sec, send_total.tv_nsec);
> -	nsec = ((unsigned long long)send_total.tv_sec * 1000000000 +
> -		 send_total.tv_nsec) / TEST1_LOOPS;
> -	printf("\t\t\t\t\t\t%lld nsec/msg\n", nsec);
> -	printf("\t\tRecv msg:\t\t\t%ld.%lus total time\n",
> -	       recv_total.tv_sec, recv_total.tv_nsec);
> -	nsec = ((unsigned long long)recv_total.tv_sec * 1000000000 +
> -		recv_total.tv_nsec) / TEST1_LOOPS;
> -	printf("\t\t\t\t\t\t%lld nsec/msg\n", nsec);
> -
> -
> -	for (cur_test = test2; cur_test->desc != NULL; cur_test++) {
> -		printf("%s:\n", cur_test->desc);
> -		printf("\t\t(%d iterations)\n", TEST2_LOOPS);
> -		prio_out = 0;
> -		send_total.tv_sec = 0;
> -		send_total.tv_nsec = 0;
> -		recv_total.tv_sec = 0;
> -		recv_total.tv_nsec = 0;
> -		printf("\t\tFilling queue...");
> -		fflush(stdout);
> -		clock_gettime(clock, &start);
> -		for (i = 0; i < result.mq_maxmsg - 1; i++) {
> -			do_untimed_send();
> -			cur_test->func(&prio_out);
> -		}
> -		clock_gettime(clock, &end);
> -		nsec = ((unsigned long long)(end.tv_sec - start.tv_sec) *
> -			1000000000) + (end.tv_nsec - start.tv_nsec);
> -		printf("done.\t\t%lld.%llds\n", nsec / 1000000000,
> -		       nsec % 1000000000);
> -		printf("\t\tTesting...");
> -		fflush(stdout);
> -		for (i = 0; i < TEST2_LOOPS; i++) {
> -			do_send_recv();
> -			cur_test->func(&prio_out);
> -		}
> -		printf("done.\n");
> -		printf("\t\tSend msg:\t\t\t%ld.%lus total time\n",
> -		       send_total.tv_sec, send_total.tv_nsec);
> -		nsec = ((unsigned long long)send_total.tv_sec * 1000000000 +
> -			 send_total.tv_nsec) / TEST2_LOOPS;
> -		printf("\t\t\t\t\t\t%lld nsec/msg\n", nsec);
> -		printf("\t\tRecv msg:\t\t\t%ld.%lus total time\n",
> -		       recv_total.tv_sec, recv_total.tv_nsec);
> -		nsec = ((unsigned long long)recv_total.tv_sec * 1000000000 +
> -			recv_total.tv_nsec) / TEST2_LOOPS;
> -		printf("\t\t\t\t\t\t%lld nsec/msg\n", nsec);
> -		printf("\t\tDraining queue...");
> -		fflush(stdout);
> -		clock_gettime(clock, &start);
> -		drain_queue();
> -		clock_gettime(clock, &end);
> -		nsec = ((unsigned long long)(end.tv_sec - start.tv_sec) *
> -			1000000000) + (end.tv_nsec - start.tv_nsec);
> -		printf("done.\t\t%lld.%llds\n", nsec / 1000000000,
> -		       nsec % 1000000000);
> -	}
> -	return 0;
> -}
> -
> -void increase_limits(void)
> -{
> -	cur_limits.rlim_cur = RLIM_INFINITY;
> -	cur_limits.rlim_max = RLIM_INFINITY;
> -	setr(RLIMIT_MSGQUEUE, &cur_limits);
> -	while (try_set(max_msgs, cur_max_msgs += 10))
> -		;
> -	cur_max_msgs = get(max_msgs);
> -	while (try_set(max_msgsize, cur_max_msgsize += 1024))
> -		;
> -	cur_max_msgsize = get(max_msgsize);
> -	if (setpriority(PRIO_PROCESS, 0, -20) != 0)
> -		shutdown(2, "setpriority()", __LINE__);
> -	cur_nice = -20;
> -}
> -
> -int main(int argc, char *argv[])
> -{
> -	struct mq_attr attr;
> -	char *option, *next_option;
> -	int i, cpu, rc;
> -	struct sigaction sa;
> -	poptContext popt_context;
> -	void *retval;
> -
> -	main_thread = pthread_self();
> -	num_cpus_to_pin = 0;
> -
> -	if (sysconf(_SC_NPROCESSORS_ONLN) == -1) {
> -		perror("sysconf(_SC_NPROCESSORS_ONLN)");
> -		exit(1);
> -	}
> -	cpus_online = min(MAX_CPUS, sysconf(_SC_NPROCESSORS_ONLN));
> -	cpu_set = CPU_ALLOC(cpus_online);
> -	if (cpu_set == NULL) {
> -		perror("CPU_ALLOC()");
> -		exit(1);
> -	}
> -	cpu_set_size = CPU_ALLOC_SIZE(cpus_online);
> -	CPU_ZERO_S(cpu_set_size, cpu_set);
> -
> -	popt_context = poptGetContext(NULL, argc, (const char **)argv,
> -				      options, 0);
> -
> -	while ((rc = poptGetNextOpt(popt_context)) > 0) {
> -		switch (rc) {
> -		case 'c':
> -			continuous_mode = 1;
> -			option = cpu_option_string;
> -			do {
> -				next_option = strchr(option, ',');
> -				if (next_option)
> -					*next_option = '\0';
> -				cpu = atoi(option);
> -				if (cpu >= cpus_online)
> -					fprintf(stderr, "CPU %d exceeds "
> -						"cpus online, ignoring.\n",
> -						cpu);
> -				else
> -					cpus_to_pin[num_cpus_to_pin++] = cpu;
> -				if (next_option)
> -					option = ++next_option;
> -			} while (next_option && num_cpus_to_pin < MAX_CPUS);
> -			/* Double check that they didn't give us the same CPU
> -			 * more than once */
> -			for (cpu = 0; cpu < num_cpus_to_pin; cpu++) {
> -				if (CPU_ISSET_S(cpus_to_pin[cpu], cpu_set_size,
> -						cpu_set)) {
> -					fprintf(stderr, "Any given CPU may "
> -						"only be given once.\n");
> -					exit(1);
> -				} else
> -					CPU_SET_S(cpus_to_pin[cpu],
> -						  cpu_set_size, cpu_set);
> -			}
> -			break;
> -		case 'p':
> -			/*
> -			 * Although we can create a msg queue with a
> -			 * non-absolute path name, unlink will fail.  So,
> -			 * if the name doesn't start with a /, add one
> -			 * when we save it.
> -			 */
> -			option = queue_path;
> -			if (*option != '/') {
> -				queue_path = malloc(strlen(option) + 2);
> -				if (!queue_path) {
> -					perror("malloc()");
> -					exit(1);
> -				}
> -				queue_path[0] = '/';
> -				queue_path[1] = 0;
> -				strcat(queue_path, option);
> -				free(option);
> -			}
> -			break;
> -		}
> -	}
> -
> -	if (continuous_mode && num_cpus_to_pin == 0) {
> -		fprintf(stderr, "Must pass at least one CPU to continuous "
> -			"mode.\n");
> -		poptPrintUsage(popt_context, stderr, 0);
> -		exit(1);
> -	} else if (!continuous_mode) {
> -		num_cpus_to_pin = 1;
> -		cpus_to_pin[0] = cpus_online - 1;
> -	}
> -
> -	if (getuid() != 0) {
> -		fprintf(stderr, "Not running as root, but almost all tests "
> -			"require root in order to modify\nsystem settings.  "
> -			"Exiting.\n");
> -		exit(1);
> -	}
> -
> -	max_msgs = fopen(MAX_MSGS, "r+");
> -	max_msgsize = fopen(MAX_MSGSIZE, "r+");
> -	if (!max_msgs)
> -		shutdown(2, "Failed to open msg_max", __LINE__);
> -	if (!max_msgsize)
> -		shutdown(2, "Failed to open msgsize_max", __LINE__);
> -
> -	/* Load up the current system values for everything we can */
> -	getr(RLIMIT_MSGQUEUE, &saved_limits);
> -	cur_limits = saved_limits;
> -	saved_max_msgs = cur_max_msgs = get(max_msgs);
> -	saved_max_msgsize = cur_max_msgsize = get(max_msgsize);
> -	errno = 0;
> -	cur_nice = getpriority(PRIO_PROCESS, 0);
> -	if (errno)
> -		shutdown(2, "getpriority()", __LINE__);
> -
> -	/* Tell the user our initial state */
> -	printf("\nInitial system state:\n");
> -	printf("\tUsing queue path:\t\t\t%s\n", queue_path);
> -	printf("\tRLIMIT_MSGQUEUE(soft):\t\t\t%ld\n",
> -		(long) saved_limits.rlim_cur);
> -	printf("\tRLIMIT_MSGQUEUE(hard):\t\t\t%ld\n",
> -		(long) saved_limits.rlim_max);
> -	printf("\tMaximum Message Size:\t\t\t%d\n", saved_max_msgsize);
> -	printf("\tMaximum Queue Size:\t\t\t%d\n", saved_max_msgs);
> -	printf("\tNice value:\t\t\t\t%d\n", cur_nice);
> -	printf("\n");
> -
> -	increase_limits();
> -
> -	printf("Adjusted system state for testing:\n");
> -	if (cur_limits.rlim_cur == RLIM_INFINITY) {
> -		printf("\tRLIMIT_MSGQUEUE(soft):\t\t\t(unlimited)\n");
> -		printf("\tRLIMIT_MSGQUEUE(hard):\t\t\t(unlimited)\n");
> -	} else {
> -		printf("\tRLIMIT_MSGQUEUE(soft):\t\t\t%ld\n",
> -		       (long) cur_limits.rlim_cur);
> -		printf("\tRLIMIT_MSGQUEUE(hard):\t\t\t%ld\n",
> -		       (long) cur_limits.rlim_max);
> -	}
> -	printf("\tMaximum Message Size:\t\t\t%d\n", cur_max_msgsize);
> -	printf("\tMaximum Queue Size:\t\t\t%d\n", cur_max_msgs);
> -	printf("\tNice value:\t\t\t\t%d\n", cur_nice);
> -	printf("\tContinuous mode:\t\t\t(%s)\n", continuous_mode ?
> -	       (continuous_mode_fake ? "fake mode" : "enabled") :
> -	       "disabled");
> -	printf("\tCPUs to pin:\t\t\t\t%d", cpus_to_pin[0]);
> -	for (cpu = 1; cpu < num_cpus_to_pin; cpu++)
> -			printf(",%d", cpus_to_pin[cpu]);
> -	printf("\n");
> -
> -	sa.sa_sigaction = sig_action_SIGUSR1;
> -	sigemptyset(&sa.sa_mask);
> -	sigaddset(&sa.sa_mask, SIGHUP);
> -	sigaddset(&sa.sa_mask, SIGINT);
> -	sigaddset(&sa.sa_mask, SIGQUIT);
> -	sigaddset(&sa.sa_mask, SIGTERM);
> -	sa.sa_flags = SA_SIGINFO;
> -	if (sigaction(SIGUSR1, &sa, NULL) == -1)
> -		shutdown(1, "sigaction(SIGUSR1)", __LINE__);
> -	sa.sa_sigaction = sig_action;
> -	if (sigaction(SIGHUP, &sa, NULL) == -1)
> -		shutdown(1, "sigaction(SIGHUP)", __LINE__);
> -	if (sigaction(SIGINT, &sa, NULL) == -1)
> -		shutdown(1, "sigaction(SIGINT)", __LINE__);
> -	if (sigaction(SIGQUIT, &sa, NULL) == -1)
> -		shutdown(1, "sigaction(SIGQUIT)", __LINE__);
> -	if (sigaction(SIGTERM, &sa, NULL) == -1)
> -		shutdown(1, "sigaction(SIGTERM)", __LINE__);
> -
> -	if (!continuous_mode_fake) {
> -		attr.mq_flags = O_NONBLOCK;
> -		attr.mq_maxmsg = cur_max_msgs;
> -		attr.mq_msgsize = MSG_SIZE;
> -		open_queue(&attr);
> -	}
> -	for (i = 0; i < num_cpus_to_pin; i++) {
> -		pthread_attr_t thread_attr;
> -		void *thread_func;
> -
> -		if (continuous_mode_fake)
> -			thread_func = &fake_cont_thread;
> -		else if (continuous_mode)
> -			thread_func = &cont_thread;
> -		else
> -			thread_func = &perf_test_thread;
> -
> -		CPU_ZERO_S(cpu_set_size, cpu_set);
> -		CPU_SET_S(cpus_to_pin[i], cpu_set_size, cpu_set);
> -		pthread_attr_init(&thread_attr);
> -		pthread_attr_setaffinity_np(&thread_attr, cpu_set_size,
> -					    cpu_set);
> -		if (pthread_create(&cpu_threads[i], &thread_attr, thread_func,
> -				   NULL))
> -			shutdown(1, "pthread_create()", __LINE__);
> -		pthread_attr_destroy(&thread_attr);
> -	}
> -
> -	if (!continuous_mode) {
> -		pthread_join(cpu_threads[0], &retval);
> -		shutdown((long)retval, "perf_test_thread()", __LINE__);
> -	} else {
> -		while (1)
> -			sleep(1);
> -	}
> -	shutdown(0, "", 0);
> -}
> 


-- 
Shuah Khan
Sr. Linux Kernel Developer
Open Source Innovation Group
Samsung Research America (Silicon Valley)
shuahkh@....samsung.com | (970) 217-8978
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ