mbox series

[rt-tests,v2,00/18] Streamline command line

Message ID 20201007085653.11961-1-dwagner@suse.de
Headers show
Series Streamline command line | expand

Message

Daniel Wagner Oct. 7, 2020, 8:56 a.m. UTC
Hi,

Here the second round getting the some more consistency into the code
base. With this all the commands should at least look the same and use
an consistent option name. I've tried to make it backwards compatible,
except for oslat (--duration).

Thanks,
Daniel

changes since v1:
  - updated all existing tools

Daniel Wagner (18):
  rt-util: Move parse_cpumask from cyclictest
  cyclictest: Use numa library helpers in get_available_cpus()
  cyclicdeadline: Streamline usage output and man page
  cyclicdeadline: Add long command line options
  deadline_test: Streamline usage output and man page
  oslat: Streamline usage output and man page
  oslat: Use string parser utilies
  pip_stress: Add command line parser
  pi_stress: Streamline usage output and man page
  pmqtest: Streamline usage output and man page
  ptsematest: Streamline usage output and man page
  queuelat: Streamline usage and man page
  rt-migrate-test: Streamline usage and man page
  signaltest: Streamline usage and man page
  sigwaittest: Streamline usage and man page
  ssdd: Streamline usage and man page
  svsematest: Streamline usage and man page
  hackbench: Streamline usage and man page

 Makefile                              |  12 +--
 src/cyclictest/cyclictest.c           |  90 +++-------------
 src/hackbench/hackbench.8             |  70 +++++++------
 src/hackbench/hackbench.c             | 102 +++++++++---------
 src/include/rt-utils.h                |   3 +
 src/lib/rt-utils.c                    |  76 ++++++++++++++
 src/oslat/oslat.8                     |   2 +-
 src/oslat/oslat.c                     | 145 +++++++-------------------
 src/pi_tests/pi_stress.8              |  79 +++++++-------
 src/pi_tests/pi_stress.c              | 144 +++++++++++++------------
 src/pi_tests/pip_stress.c             |  34 +++++-
 src/pmqtest/pmqtest.8                 |   5 +-
 src/pmqtest/pmqtest.c                 |  88 ++++++++--------
 src/ptsematest/ptsematest.8           |   5 +-
 src/ptsematest/ptsematest.c           |  76 +++++++-------
 src/queuelat/queuelat.8               |  41 +++-----
 src/queuelat/queuelat.c               |  99 +++++++++---------
 src/rt-migrate-test/rt-migrate-test.8 |  41 ++++----
 src/rt-migrate-test/rt-migrate-test.c |  82 +++++++--------
 src/sched_deadline/cyclicdeadline.8   |  25 ++---
 src/sched_deadline/cyclicdeadline.c   |  67 +++++++-----
 src/sched_deadline/deadline_test.8    |  37 ++++---
 src/sched_deadline/deadline_test.c    |  47 ++++-----
 src/signaltest/signaltest.8           |  13 +--
 src/signaltest/signaltest.c           |  47 +++++----
 src/sigwaittest/sigwaittest.8         |   4 +-
 src/sigwaittest/sigwaittest.c         |  76 ++++++++------
 src/ssdd/ssdd.8                       |  35 +++----
 src/ssdd/ssdd.c                       |  50 +++++----
 src/svsematest/svsematest.8           |   6 +-
 src/svsematest/svsematest.c           |  83 ++++++++-------
 31 files changed, 854 insertions(+), 830 deletions(-)

Comments

John Kacur Oct. 23, 2020, 3:46 p.m. UTC | #1
On Wed, 7 Oct 2020, Daniel Wagner wrote:

> In order to be reuse the cpumask parsing code, move it to libary.
> Several tools implement their own version of this. Let's use one
> global one instead.
> 
> Signed-off-by: Daniel Wagner <dwagner@suse.de>
> ---
>  Makefile                    | 12 +++---
>  src/cyclictest/cyclictest.c | 68 +++++++--------------------------
>  src/include/rt-utils.h      |  3 ++
>  src/lib/rt-utils.c          | 76 +++++++++++++++++++++++++++++++++++++
>  4 files changed, 98 insertions(+), 61 deletions(-)
> 
> diff --git a/Makefile b/Makefile
> index c3ebbd7b2a2e..3627084437c1 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -20,9 +20,14 @@ sources = cyclictest.c \
>  	  ssdd.c \
>  	  oslat.c
>  
> +# You have to have libnuma installed, which is fine to do even if you are
> +# running on non-numa machines
> +CFLAGS += -DNUMA
> +NUMA_LIBS = -lnuma
> +
>  TARGETS = $(sources:.c=)
>  LIBS	= -lrt -lpthread
> -RTTESTLIB = -lrttest -L$(OBJDIR)
> +RTTESTLIB = -lrttest -L$(OBJDIR) $(NUMA_LIBS)

Currently only cyclictest was compiled with NUMA_LIBS, this change will 
compile everything with NUMA_LIBS. I checked the size of the programs, and 
they don't grow that much with this change, but they are small programs to
begin with, do we want to keep this functionality separate?

 
>  EXTRA_LIBS ?= -ldl	# for get_cpu
>  DESTDIR	?=
>  prefix  ?= /usr/local
> @@ -79,11 +84,6 @@ ostype := $(lastword $(subst -, ,$(dumpmachine)))
>  machinetype := $(shell echo $(dumpmachine)| \
>      sed -e 's/-.*//' -e 's/i.86/i386/' -e 's/mips.*/mips/' -e 's/ppc.*/powerpc/')
>  
> -# You have to have libnuma installed, which is fine to do even if you are
> -# running on non-numa machines
> -CFLAGS += -DNUMA
> -NUMA_LIBS = -lnuma
> -
>  include src/arch/android/Makefile
>  
>  VPATH	= src/cyclictest:
> diff --git a/src/cyclictest/cyclictest.c b/src/cyclictest/cyclictest.c
> index b41d42f13f24..02cb92813fb7 100644
> --- a/src/cyclictest/cyclictest.c
> +++ b/src/cyclictest/cyclictest.c
> @@ -908,11 +908,6 @@ static int clocksources[] = {
>  	CLOCK_REALTIME,
>  };
>  
> -static unsigned int is_cpumask_zero(const struct bitmask *mask)
> -{
> -	return (rt_numa_bitmask_count(mask) == 0);
> -}
> -
>  /* Get available cpus according to getaffinity or according to the
>   * intersection of getaffinity and the user specified affinity
>   * in the case of AFFINITY_SPECIFIED, the function has to be called
> @@ -997,52 +992,6 @@ static int cpu_for_thread_ua(int thread_num, int max_cpus)
>  	return 0;
>  }
>  
> -
> -/* After this function is called, affinity_mask is the intersection of the user
> - * supplied affinity mask and the affinity mask from the run time environment */
> -static void use_current_cpuset(const int max_cpus)
> -{
> -	int i;
> -	pid_t pid;
> -	struct bitmask *curmask;
> -
> -	pid = getpid();
> -
> -	curmask = numa_allocate_cpumask();
> -	numa_sched_getaffinity(pid, curmask);
> -
> -	/* Clear bits that are not set in both the cpuset from the environment,
> -	 * and in the user specified affinity for cyclictest */
> -	for (i=0; i < max_cpus; i++) {
> -		if ((!rt_numa_bitmask_isbitset(affinity_mask, i)) || (!rt_numa_bitmask_isbitset(curmask, i))) {
> -			numa_bitmask_clearbit(affinity_mask, i);
> -		}
> -	}
> -
> -	numa_bitmask_free(curmask);
> -}
> -
> -static void parse_cpumask(const char *option, const int max_cpus)
> -{
> -	affinity_mask = rt_numa_parse_cpustring(option, max_cpus);
> -	if (affinity_mask) {
> -		if (is_cpumask_zero(affinity_mask)) {
> -			rt_bitmask_free(affinity_mask);
> -			affinity_mask = NULL;
> -		} else {
> -			use_current_cpuset(max_cpus);
> -		}
> -
> -	}
> -	if (!affinity_mask)
> -		display_help(1);
> -
> -	if (verbose) {
> -		printf("%s: Using %u cpus.\n", __func__,
> -			rt_numa_bitmask_count(affinity_mask));
> -	}
> -}
> -
>  static void handlepolicy(char *polname)
>  {
>  	if (strncasecmp(polname, "other", 5) == 0)
> @@ -1176,15 +1125,24 @@ static void process_options (int argc, char *argv[], int max_cpus)
>  			if (smp)
>  				break;
>  			numa_initialize();
> -			if (optarg != NULL) {
> -				parse_cpumask(optarg, max_cpus);
> +			if (optarg) {
> +				parse_cpumask(optarg, max_cpus, &affinity_mask);
>  				setaffinity = AFFINITY_SPECIFIED;
> -			} else if (optind<argc && (atoi(argv[optind]) || argv[optind][0] == '0' || argv[optind][0] == '!')) {
> -				parse_cpumask(argv[optind], max_cpus);
> +			} else if (optind < argc &&
> +				   (atoi(argv[optind]) ||
> +				    argv[optind][0] == '0' ||
> +				    argv[optind][0] == '!')) {
> +				parse_cpumask(argv[optind], max_cpus, &affinity_mask);
>  				setaffinity = AFFINITY_SPECIFIED;
>  			} else {
>  				setaffinity = AFFINITY_USEALL;
>  			}
> +
> +			if (setaffinity == AFFINITY_SPECIFIED && !affinity_mask)
> +				display_help(1);
> +			if (verbose)
> +				printf("Using %u cpus.\n",
> +					numa_bitmask_weight(affinity_mask));
>  			break;
>  		case 'A':
>  		case OPT_ALIGNED:
> diff --git a/src/include/rt-utils.h b/src/include/rt-utils.h
> index 4ed1cbc53ece..3b97655a20f2 100644
> --- a/src/include/rt-utils.h
> +++ b/src/include/rt-utils.h
> @@ -3,6 +3,7 @@
>  #define __RT_UTILS_H
>  
>  #include <stdint.h>
> +#include <numa.h>
>  
>  #define _STR(x) #x
>  #define STR(x) _STR(x)
> @@ -28,6 +29,8 @@ uint32_t string_to_policy(const char *str);
>  pid_t gettid(void);
>  
>  int parse_time_string(char *val);
> +int parse_mem_string(char *str, uint64_t *val);
> +int parse_cpumask(char *str, int max_cpus, struct bitmask **cpumask);
>  
>  void enable_trace_mark(void);
>  void tracemark(char *fmt, ...) __attribute__((format(printf, 1, 2)));
> diff --git a/src/lib/rt-utils.c b/src/lib/rt-utils.c
> index f786588706cd..302b91388df5 100644
> --- a/src/lib/rt-utils.c
> +++ b/src/lib/rt-utils.c
> @@ -362,6 +362,82 @@ int parse_time_string(char *val)
>  	return t;
>  }
>  
> +int parse_mem_string(char *str, uint64_t *val)
> +{
> +	char *endptr;
> +	int v = strtol(str, &endptr, 10);
> +
> +	if (!*endptr)
> +		return v;
> +
> +	switch (*endptr) {
> +	case 'g':
> +	case 'G':
> +		v *= 1024;
> +	case 'm':
> +	case 'M':
> +		v *= 1024;
> +	case 'k':
> +	case 'K':
> +		v *= 1024;
> +	case 'b':
> +	case 'B':
> +		break;
> +	default:
> +		return -1;
> +	}
> +
> +	*val = v;
> +
> +	return 0;
> +}
> +
> +/*
> + * After this function is called, affinity_mask is the intersection of
> + * the user supplied affinity mask and the affinity mask from the run
> + * time environment
> + */
> +static void use_current_cpuset(int max_cpus, struct bitmask *cpumask)
> +{
> +	struct bitmask *curmask;
> +	int i;
> +
> +	curmask = numa_allocate_cpumask();
> +	numa_sched_getaffinity(getpid(), curmask);
> +
> +	/*
> +	 * Clear bits that are not set in both the cpuset from the
> +	 * environment, and in the user specified affinity.
> +	 */
> +	for (i = 0; i < max_cpus; i++) {
> +		if ((!numa_bitmask_isbitset(cpumask, i)) ||
> +		    (!numa_bitmask_isbitset(curmask, i)))
> +			numa_bitmask_clearbit(cpumask, i);
> +	}
> +
> +	numa_bitmask_free(curmask);
> +}
> +
> +int parse_cpumask(char *str, int max_cpus, struct bitmask **cpumask)
> +{
> +	struct bitmask *mask;
> +
> +	mask = numa_parse_cpustring_all(str);
> +	if (!mask)
> +		return -ENOMEM;
> +
> +	if (numa_bitmask_weight(mask) == 0) {
> +		numa_bitmask_free(mask);
> +		*cpumask = NULL;
> +		return 0;
> +	}
> +
> +	use_current_cpuset(max_cpus, mask);
> +	*cpumask = mask;
> +
> +	return 0;
> +}
> +
>  void open_tracemark_fd(void)
>  {
>  	char path[MAX_PATH];
> -- 
> 2.28.0
> 
> 

This is a good idea, I'd just prefer to keep the libraries separate for 
now.

John
John Kacur Oct. 23, 2020, 3:55 p.m. UTC | #2
On Wed, 7 Oct 2020, Daniel Wagner wrote:

> The numa library has support for counting the bits in the affinity

> mask and how many CPUs are available and usable by the tasks. Let's

> use those helpers.

> 

> Signed-off-by: Daniel Wagner <dwagner@suse.de>

> ---

>  src/cyclictest/cyclictest.c | 22 +++-------------------

>  1 file changed, 3 insertions(+), 19 deletions(-)

> 

> diff --git a/src/cyclictest/cyclictest.c b/src/cyclictest/cyclictest.c

> index 02cb92813fb7..d7477c686435 100644

> --- a/src/cyclictest/cyclictest.c

> +++ b/src/cyclictest/cyclictest.c

> @@ -915,26 +915,10 @@ static int clocksources[] = {

>   */

>  static int get_available_cpus(void)

>  {

> -	int num_cpus = 0;

> -	int res;

> -	pthread_t thread;

> -	cpu_set_t cpuset;

> -

> -

> -	if (affinity_mask != NULL) {

> -		num_cpus = rt_numa_bitmask_count(affinity_mask);

> -	} else {

> -		CPU_ZERO(&cpuset);

> -		thread = pthread_self();

> -		res = pthread_getaffinity_np(thread, sizeof(cpu_set_t), &cpuset);

> -		if (res != 0) {

> -			fatal("pthread_getaffinity_np failed: %s\n", strerror(res));

> -		}

> -		num_cpus = CPU_COUNT(&cpuset);

> -	}

> -

> -	return num_cpus;

> +	if (affinity_mask)

> +		return numa_bitmask_weight(affinity_mask);

>  

> +	return numa_num_task_cpus();

>  }

>  

>  /* cpu_for_thread AFFINITY_SPECIFIED */

> -- 

> 2.28.0

> 

> 

Signed-off-by: John Kacur <jkacur@redhat.com>


Thanks!
John Kacur Oct. 23, 2020, 4:10 p.m. UTC | #3
On Wed, 7 Oct 2020, Daniel Wagner wrote:

> Signed-off-by: Daniel Wagner <dwagner@suse.de>
> ---
>  src/sched_deadline/deadline_test.8 | 37 ++++++++++++-----------
>  src/sched_deadline/deadline_test.c | 47 +++++++++++++++---------------
>  2 files changed, 41 insertions(+), 43 deletions(-)
> 
> diff --git a/src/sched_deadline/deadline_test.8 b/src/sched_deadline/deadline_test.8
> index 5dc99c0bfc63..8f32c5b6feb6 100644
> --- a/src/sched_deadline/deadline_test.8
> +++ b/src/sched_deadline/deadline_test.8
> @@ -19,45 +19,44 @@ deadline_test \- High resolution test program
>  This program is used to test the deadline scheduler (SCHED_DEADLINE tasks)
>  .SH SYNOPSIS
>  .B deadline_test
> -.RI "[ \-hb ] [ \-r prio ] [ \-c cpulist ] [ \-i interval ] [ \-p percent ] [ \-P percent ] [ \-t threads ] [ \-s step[us) ]"
> -
> +.RI "[ \-hb ] [ \-c CPUSET ] [ \-i INTV ] [ \-p PERCENT ] [ \-P PERCENT ] \
> +[ \-r PRIO ]  [ \-s STEP ] [ \-t NUM ]"
>  .SH OPTIONS
>  .TP
> -.B \-h
> -Show this help menu
> -.br
> -.TP
>  .B \-b
>  Bind on the last cpu. (shortcut for -c <lastcpu>)
>  .br
>  .TP
> -.B \-r prio
> -Add an RT task with given prio to stress system
> +.B \-c CPUSET
> +Comma/hyphen separated list of CPUs to run deadline tasks on
>  .br
>  .TP
> -.B \-c cpulist
> -Comma/hyphen separated list of CPUs to run deadline tasks on
> +.B \-h
> +Show this help menu
>  .br
>  .TP
> -.B \-i interval
> +.B \-i INTV
>  The shortest deadline for the tasks
>  .br
>  .TP
> -.B \-p percent
> +.B \-p PERCENT
>  The percent of bandwidth to use (1-90%)
>  .br
>  .TP
> -.B \-P percent
> -The percent of runtime for execution completion
> -              (Default 100%)
> +.B \-P PERCENT
> +The percent of runtime for execution completion (default 100%)
>  .br
>  .TP
> -.B \-t threads
> -The number of threads to run as deadline (default 1)
> +.B \-r PRIO
> +Add an RT task with given prio to stress system
>  .br
>  .TP
> -.B \-s step(us)
> -The amount to increase the deadline for each task (default 500us)
> +.B \-s STEP
> +The amount to increase the deadline for each task in us (default 500us)
> +.br
> +.TP
> +.B \-t NUM
> +The number of threads to run as deadline (default 1)
>  .br
>  .SH AUTHOR
>  Deadline test was written by Steven Rostedt <rostedt@goodmis.org>
> diff --git a/src/sched_deadline/deadline_test.c b/src/sched_deadline/deadline_test.c
> index 4cef2609912e..060ac896aef2 100644
> --- a/src/sched_deadline/deadline_test.c
> +++ b/src/sched_deadline/deadline_test.c
> @@ -46,33 +46,30 @@
>  
>  /**
>   * usage - show the usage of the program and exit.
> - * @argv: The program passed in args
> + * @error: Exit error code to be used
>   *
> - * This is defined here to show people looking at this code how
> + * This is defined here to show peoplde looking at this code how
>   * to use this program as well. 
>   */
> -static void usage(char **argv)
> +static void usage(int error)
>  {
> -	char *arg = argv[0];
> -	char *p = arg+strlen(arg);
> -
> -	while (p >= arg && *p != '/')
> -		p--;
> -	p++;
> -
> -	printf("usage: %s [options]\n"
> -	       " -h - Show this help menu\n"
> -	       " -b - Bind on the last cpu. (shortcut for -c <lastcpu>)\n"
> -	       " -r prio - Add an RT task with given prio to stress system\n"
> -	       " -c cpulist - Comma/hyphen separated list of CPUs to run deadline tasks on\n"
> -	       " -i interval - The shortest deadline for the tasks\n"
> -	       " -p percent - The percent of bandwidth to use (1-90%%)\n"
> -	       " -P percent - The percent of runtime for execution completion\n"
> -	       "              (Default 100%%)\n"
> -	       " -t threads - The number of threads to run as deadline (default 1)\n"
> -	       " -s step(us) - The amount to increase the deadline for each task (default 500us)\n"
> -	       "\n", p);
> -	exit(-1);
> +	printf("deadline_test V %1.2f\n", VERSION);
> +	printf("Usage:\n"
> +	       "deadline_test <options>\n"
> +	       "-b                         Bind on the last cpu. (shortcut for -c <lastcpu>)\n"
> +	       "-c CPUSET                  Comma/hyphen separated list of CPUs to run deadline\n"
> +	       "                           tasks on\n"
> +	       "-h                         Show this help menu\n"
> +	       "-i INTV                    The shortest deadline for the tasks\n"
> +	       "-p PERCENT                 The percent of bandwidth to use (1-90%%)\n"
> +	       "-P PERCENT                 The percent of runtime for execution completion\n"
> +	       "                           (default 100%%)\n"
> +	       "-r PRIO                    Add an RT task with given prio to stress system\n"
> +	       "-s STEP                    The amount to increase the deadline for each task in us\n"
> +	       "                           (default 500us)\n"
> +	       "-t NUM                     The number of threads to run as deadline (default 1)\n"
> +	       );
> +	exit(error);
>  }
>  
>  #define _STR(x) #x
> @@ -1753,8 +1750,10 @@ int main (int argc, char **argv)
>  			rt_task = atoi(optarg);
>  			break;
>  		case 'h':
> +			usage(0);
> +			break;
>  		default:
> -			usage(argv);
> +			usage(1);
>  		}
>  	}
>  
> -- 
> 2.28.0
> 
> 
Signed-off-by: John Kacur <jkacur@redhat.com

Thanks!
John Kacur Oct. 23, 2020, 5:19 p.m. UTC | #4
On Wed, 7 Oct 2020, Daniel Wagner wrote:

> Signed-off-by: Daniel Wagner <dwagner@suse.de>

> ---

>  src/oslat/oslat.8 |  2 +-

>  src/oslat/oslat.c | 78 ++++++++++++++++++++++-------------------------

>  2 files changed, 38 insertions(+), 42 deletions(-)

> 

> diff --git a/src/oslat/oslat.8 b/src/oslat/oslat.8

> index 85f2c5bcdf5c..b481d8d82783 100644

> --- a/src/oslat/oslat.8

> +++ b/src/oslat/oslat.8

> @@ -36,7 +36,7 @@ Total memory usage will be this value multiplies 2*N,

>  because there will be src/dst buffers for each thread, and

>  N is the number of processors for testing.

>  .TP

> -.B \-t, \-\-runtime=SEC

> +.B \-D, \-\-duration=TIME

>  Specify test duration, e.g., 60, 20m, 2H (m/M: minutes, h/H: hours, d/D: days).

>  By default the unit is s/second.

>  .TP

> diff --git a/src/oslat/oslat.c b/src/oslat/oslat.c

> index f1a82f2367d2..fafbdd694326 100644

> --- a/src/oslat/oslat.c

> +++ b/src/oslat/oslat.c

> @@ -507,42 +507,37 @@ static void handle_alarm(int code)

>  	g.cmd = STOP;

>  }

>  

> -const char *helpmsg =

> -"Usage: %s [options]\n"

> -"\n"

> -"This is an OS latency detector by running busy loops on specified cores.\n"

> -"Please run this tool using root.\n"

> -"\n"

> -"Available options:\n"

> -"\n"

> -"  -b, --bucket-size      Specify the number of the buckets (4-1024)\n"

> -"  -B, --bias             Add a bias to all the buckets using the estimated mininum\n"

> -"  -c, --cpu-list         Specify CPUs to run on, e.g. '1,3,5,7-15'\n"

> -"  -C, --cpu-main-thread  Specify which CPU the main thread runs on.  Default is cpu0.\n"

> -"  -f, --rtprio           Using SCHED_FIFO priority (1-99)\n"

> -"  -m, --workload-mem     Size of the memory to use for the workload (e.g., 4K, 1M).\n"

> -"                         Total memory usage will be this value multiplies 2*N,\n"

> -"                         because there will be src/dst buffers for each thread, and\n"

> -"                         N is the number of processors for testing.\n"

> -"  -s, --single-preheat   Use a single thread when measuring latency at preheat stage\n"

> -"                         NOTE: please make sure the CPU frequency on all testing cores\n"

> -"                         are locked before using this parmater.  If you don't know how\n"

> -"                         to lock the freq then please don't use this parameter.\n"

> -"  -t, --runtime          Specify test duration, e.g., 60, 20m, 2H\n"

> -"                         (m/M: minutes, h/H: hours, d/D: days)\n"

> -"  -T, --trace-threshold  Stop the test when threshold triggered (in us),\n"

> -"                         print a marker in ftrace and stop ftrace too.\n"

> -"  -v, --version          Display the version of the software.\n"

> -"  -w, --workload         Specify a kind of workload, default is no workload\n"

> -"                         (options: no, memmove)\n"

> -"  -z, --zero-omit        Don't display buckets in the output histogram if all zeros.\n"

> -"\n"

> -;

> -

> -static void usage(void)

> +static void usage(int error)

>  {

> -	printf(helpmsg, g.app_name);

> -	exit(1);

> +	printf("oslat V %1.2f\n", VERSION);

> +	printf("Usage:\n"

> +	       "oslat <options>\n\n"

> +	       "This is an OS latency detector by running busy loops on specified cores.\n"

> +	       "Please run this tool using root.\n\n"

> +	       "Available options:\n\n"

> +	       "-b, --bucket-size      Specify the number of the buckets (4-1024)\n"

> +	       "-B, --bias             Add a bias to all the buckets using the estimated mininum\n"

> +	       "-c, --cpu-list         Specify CPUs to run on, e.g. '1,3,5,7-15'\n"

> +	       "-C, --cpu-main-thread  Specify which CPU the main thread runs on.  Default is cpu0.\n"

> +	       "-D, --duration         Specify test duration, e.g., 60, 20m, 2H\n"

> +	       "                       (m/M: minutes, h/H: hours, d/D: days)\n"

> +	       "-f, --rtprio           Using SCHED_FIFO priority (1-99)\n"

> +	       "-m, --workload-mem     Size of the memory to use for the workload (e.g., 4K, 1M).\n"

> +	       "                       Total memory usage will be this value multiplies 2*N,\n"

> +	       "                       because there will be src/dst buffers for each thread, and\n"

> +	       "                       N is the number of processors for testing.\n"

> +	       "-s, --single-preheat   Use a single thread when measuring latency at preheat stage\n"

> +	       "                       NOTE: please make sure the CPU frequency on all testing cores\n"

> +	       "                       are locked before using this parmater.  If you don't know how\n"

> +	       "                       to lock the freq then please don't use this parameter.\n"

> +	       "-T, --trace-threshold  Stop the test when threshold triggered (in us),\n"

> +	       "                       print a marker in ftrace and stop ftrace too.\n"

> +	       "-v, --version          Display the version of the software.\n"

> +	       "-w, --workload         Specify a kind of workload, default is no workload\n"

> +	       "                       (options: no, memmove)\n"

> +	       "-z, --zero-omit        Don't display buckets in the output histogram if all zeros.\n"

> +	       );

> +	exit(error);

>  }

>  

>  /* TODO: use libnuma? */

> @@ -661,7 +656,7 @@ static void parse_options(int argc, char *argv[])

>  			{ "bucket-size", required_argument, NULL, 'b' },

>  			{ "cpu-list", required_argument, NULL, 'c' },

>  			{ "cpu-main-thread", required_argument, NULL, 'C'},

> -			{ "runtime", required_argument, NULL, 't' },

> +			{ "duration", required_argument, NULL, 'D' },

>  			{ "rtprio", required_argument, NULL, 'f' },

>  			{ "help", no_argument, NULL, 'h' },

>  			{ "trace-threshold", required_argument, NULL, 'T' },

> @@ -673,7 +668,7 @@ static void parse_options(int argc, char *argv[])

>  			{ "version", no_argument, NULL, 'v'},

>  			{ NULL, 0, NULL, 0 },

>  		};

> -		int i, c = getopt_long(argc, argv, "b:Bc:C:f:hm:st:w:T:vz",

> +		int i, c = getopt_long(argc, argv, "b:Bc:C:D:f:hm:sw:T:vz",

>  				       options, NULL);

>  		long ncores;

>  

> @@ -704,7 +699,7 @@ static void parse_options(int argc, char *argv[])

>  				exit(1);

>  			}

>  			break;

> -		case 't':

> +		case 'D':

>  			g.runtime = parse_runtime(optarg);

>  			if (!g.runtime) {

>  				printf("Illegal runtime: %s\n", optarg);

> @@ -761,8 +756,11 @@ static void parse_options(int argc, char *argv[])

>  		case 'z':

>  			g.output_omit_zero_buckets = 1;

>  			break;

> +		case 'h':

> +			usage(0);

> +			break;

>  		default:

> -			usage();

> +			usage(1);

>  			break;

>  		}

>  	}

> @@ -821,8 +819,6 @@ int main(int argc, char *argv[])

>  	/* Run the main thread on cpu0 by default */

>  	g.cpu_main_thread = 0;

>  

> -	printf("\nVersion: %1.2f\n\n", VERSION);

> -

>  	parse_options(argc, argv);

>  

>  	TEST(mlockall(MCL_CURRENT | MCL_FUTURE) == 0);

> -- 

> 2.28.0

> 

> 


Signed-off-by: John Kacur <jkacur@redhat.com>


Thanks

In the future at least put one line in the text though, not just a title.
John Kacur Oct. 23, 2020, 5:25 p.m. UTC | #5
On Wed, 7 Oct 2020, Daniel Wagner wrote:

> Use available parse_time_string() instead locally implemented
> version. While at it move the mem parser helper to the global utility
> header.
> 
> Signed-off-by: Daniel Wagner <dwagner@suse.de>
> ---
>  src/oslat/oslat.c | 67 ++---------------------------------------------
>  1 file changed, 2 insertions(+), 65 deletions(-)
> 
> diff --git a/src/oslat/oslat.c b/src/oslat/oslat.c
> index fafbdd694326..9df1a58f640d 100644
> --- a/src/oslat/oslat.c
> +++ b/src/oslat/oslat.c
> @@ -570,69 +570,6 @@ static int parse_cpu_list(char *cpu_list, cpu_set_t *cpu_set)
>  	return n_cores;
>  }
>  
> -static int parse_runtime(const char *str)
> -{
> -	char *endptr;
> -	int v = strtol(str, &endptr, 10);
> -
> -	if (!*endptr)
> -		return v;
> -
> -	switch (*endptr) {
> -	case 'd':
> -	case 'D':
> -		/* Days */
> -		v *= 24;
> -	case 'h':
> -	case 'H':
> -		/* Hours */
> -		v *= 60;
> -	case 'm':
> -	case 'M':
> -		/* Minutes */
> -		v *= 60;
> -	case 's':
> -	case 'S':
> -		/* Seconds */
> -		break;
> -	default:
> -		printf("Unknown runtime suffix: %s\n", endptr);
> -		v = 0;
> -		break;
> -	}
> -
> -	return v;
> -}
> -
> -static int parse_mem_size(char *str, uint64_t *val)
> -{
> -	char *endptr;
> -	int v = strtol(str, &endptr, 10);
> -
> -	if (!*endptr)
> -		return v;
> -
> -	switch (*endptr) {
> -	case 'g':
> -	case 'G':
> -		v *= 1024;
> -	case 'm':
> -	case 'M':
> -		v *= 1024;
> -	case 'k':
> -	case 'K':
> -		v *= 1024;
> -	case 'b':
> -	case 'B':
> -		break;
> -	default:
> -		return -1;
> -	}
> -
> -	*val = v;
> -
> -	return 0;
> -}
>  
>  static int workload_select(char *name)
>  {
> @@ -700,7 +637,7 @@ static void parse_options(int argc, char *argv[])
>  			}
>  			break;
>  		case 'D':
> -			g.runtime = parse_runtime(optarg);
> +			g.runtime = parse_time_string(optarg);
>  			if (!g.runtime) {
>  				printf("Illegal runtime: %s\n", optarg);
>  				exit(1);
> @@ -734,7 +671,7 @@ static void parse_options(int argc, char *argv[])
>  			}
>  			break;
>  		case 'm':
> -			if (parse_mem_size(optarg, &g.workload_mem_size)) {
> +			if (parse_mem_string(optarg, &g.workload_mem_size)) {
>  				printf("Unknown workload memory size '%s'.\n\n", optarg);
>  				exit(1);
>  			}
> -- 
> 2.28.0
> 
> 

This one is pending either your changes that I requested to the first 
patch, or an argument as to why I should accept the first patch.

Cheers!

John
John Kacur Oct. 23, 2020, 6:25 p.m. UTC | #6
On Wed, 7 Oct 2020, Daniel Wagner wrote:

> Signed-off-by: Daniel Wagner <dwagner@suse.de>
> ---
>  src/ptsematest/ptsematest.8 |  5 ++-
>  src/ptsematest/ptsematest.c | 76 +++++++++++++++++++------------------
>  2 files changed, 44 insertions(+), 37 deletions(-)
> 
> diff --git a/src/ptsematest/ptsematest.8 b/src/ptsematest/ptsematest.8
> index 5ee7d694d50d..05a0cdfd3657 100644
> --- a/src/ptsematest/ptsematest.8
> +++ b/src/ptsematest/ptsematest.8
> @@ -4,7 +4,7 @@
>  \fBptsematest\fR \- Start two threads and measure the latency of interprocess communication with POSIX mutex.
>  .SH "SYNOPSIS"
>  .LP
> -ptsematest [-a|--affinity [PROC]] [-b|--breaktrace USEC] [-d|--distance DIST] [-D|--duration TIME][-i|--interval INTV] [-l|--loops LOOPS] [-p|--prio PRIO] [-S|--smp] [-t|--threads [NUM]]
> +ptsematest [-a|--affinity [PROC]] [-b|--breaktrace USEC] [-d|--distance DIST] [-D|--duration TIME] [-h|--help] [-i|--interval INTV] [-l|--loops LOOPS] [-p|--prio PRIO] [-S|--smp] [-t|--threads [NUM]]
>  .br
>  .SH "DESCRIPTION"
>  .LP
> @@ -26,6 +26,9 @@ Specify a length for the test run.
>  .br
>  Append 'm', 'h', or 'd' to specify minutes, hours or days.
>  .TP
> +.B \-h, \-\-help
> +Print help message.
> +.TP
>  .B \-i, \-\-interval=INTV
>  Set the base interval of the thread(s) in microseconds (default is 1000 us). This sets the interval of the first thread. See also -d.
>  .TP
> diff --git a/src/ptsematest/ptsematest.c b/src/ptsematest/ptsematest.c
> index de8ea2fe1b0c..02919e3f5eef 100644
> --- a/src/ptsematest/ptsematest.c
> +++ b/src/ptsematest/ptsematest.c
> @@ -141,29 +141,31 @@ void *semathread(void *param)
>  }
>  
>  
> -static void display_help(void)
> +static void display_help(int error)
>  {
>  	printf("ptsematest V %1.2f\n", VERSION);
> -	puts("Usage: ptsematest <options>");
> -	puts("Function: test POSIX threads mutex latency");
> -	puts(
> -	"Options:\n"
> -	"-a [NUM] --affinity        run thread #N on processor #N, if possible\n"
> -	"                           with NUM pin all threads to the processor NUM\n"
> -	"-b USEC  --breaktrace=USEC send break trace command when latency > USEC\n"
> -	"-d DIST  --distance=DIST   distance of thread intervals in us default=500\n"
> -	"-D       --duration=TIME   specify a length for the test run.\n"
> -	"                           Append 'm', 'h', or 'd' to specify minutes, hours or days.\n"
> -	"-i INTV  --interval=INTV   base interval of thread in us default=1000\n"
> -	"-l LOOPS --loops=LOOPS     number of loops: default=0(endless)\n"
> -	"-p PRIO  --prio=PRIO       priority\n"
> -	"-S       --smp             SMP testing: options -a -t and same priority\n"
> -        "                           of all threads\n"
> -	"-t       --threads         one thread per available processor\n"
> -	"-t [NUM] --threads=NUM     number of threads:\n"
> -	"                           without NUM, threads = max_cpus\n"
> -	"                           without -t default = 1\n");
> -	exit(1);
> +	printf("Usage:\n"
> +	       "ptsematest <options>\n\n"
> +	       "Function: test POSIX threads mutex latency\n\n"
> +	       "Available options:\n"
> +	       "-a [NUM] --affinity        run thread #N on processor #N, if possible\n"
> +	       "                           with NUM pin all threads to the processor NUM\n"
> +	       "-b USEC  --breaktrace=USEC send break trace command when latency > USEC\n"
> +	       "-d DIST  --distance=DIST   distance of thread intervals in us default=500\n"
> +	       "-D       --duration=TIME   specify a length for the test run.\n"
> +	       "                           Append 'm', 'h', or 'd' to specify minutes, hours or\n"
> +	       "                           days.\n"
> +	       "-i INTV  --interval=INTV   base interval of thread in us default=1000\n"
> +	       "-l LOOPS --loops=LOOPS     number of loops: default=0(endless)\n"
> +	       "-p PRIO  --prio=PRIO       priority\n"
> +	       "-S       --smp             SMP testing: options -a -t and same priority\n"
> +	       "                           of all threads\n"
> +	       "-t       --threads         one thread per available processor\n"
> +	       "-t [NUM] --threads=NUM     number of threads:\n"
> +	       "                           without NUM, threads = max_cpus\n"
> +	       "                           without -t default = 1\n"
> +	       );
> +	exit(0);
>  }
>  
>  
> @@ -188,16 +190,16 @@ static void process_options (int argc, char *argv[])
>  		int option_index = 0;
>  		/** Options for getopt */
>  		static struct option long_options[] = {
> -			{"affinity", optional_argument, NULL, 'a'},
> -			{"breaktrace", required_argument, NULL, 'b'},
> -			{"distance", required_argument, NULL, 'd'},
> -			{"interval", required_argument, NULL, 'i'},
> -			{"loops", required_argument, NULL, 'l'},
> -			{"duration", required_argument, NULL, 'D'},
> -			{"priority", required_argument, NULL, 'p'},
> -			{"smp", no_argument, NULL, 'S'},
> -			{"threads", optional_argument, NULL, 't'},
> -			{"help", no_argument, NULL, '?'},
> +			{"affinity",	optional_argument,	NULL, 'a'},
> +			{"breaktrace",	required_argument,	NULL, 'b'},
> +			{"distance",	required_argument,	NULL, 'd'},
> +			{"duration",	required_argument,	NULL, 'D'},
> +			{"help",	no_argument,		NULL, 'h'},
> +			{"interval",	required_argument,	NULL, 'i'},
> +			{"loops",	required_argument,	NULL, 'l'},
> +			{"priority",	required_argument,	NULL, 'p'},
> +			{"smp",		no_argument,		NULL, 'S'},
> +			{"threads",	optional_argument,	NULL, 't'},
>  			{NULL, 0, NULL, 0}
>  		};
>  		int c = getopt_long (argc, argv, "a::b:d:i:l:D:p:St::h",
> @@ -222,9 +224,11 @@ static void process_options (int argc, char *argv[])
>  			break;
>  		case 'b': tracelimit = atoi(optarg); break;
>  		case 'd': distance = atoi(optarg); break;
> +		case 'D': duration = parse_time_string(optarg); break;
>  		case 'i': interval = atoi(optarg); break;
> +		case '?':
> +		case 'h': display_help(0); break;
>  		case 'l': max_cycles = atoi(optarg); break;
> -		case 'D': duration = parse_time_string(optarg); break;
>  		case 'p': priority = atoi(optarg); break;
>  		case 'S':
>  			smp = 1;
> @@ -243,9 +247,9 @@ static void process_options (int argc, char *argv[])
>  			else
>  				num_threads = max_cpus;
>  			break;
> -		case 'h':
> -			display_help();
> -		case '?': error = 1; break;
> +		default:
> +			display_help(1);
> +			break;
>  		}
>  	}
>  
> @@ -275,7 +279,7 @@ static void process_options (int argc, char *argv[])
>  		sameprio = 1;
>  
>  	if (error)
> -		display_help();
> +		display_help(error);
>  }
>  
>  
> -- 
> 2.28.0
> 
> 
Signed-off-by: John Kacur <jkacur@redhat.com>
John Kacur Oct. 23, 2020, 6:47 p.m. UTC | #7
On Wed, 7 Oct 2020, Daniel Wagner wrote:

> Signed-off-by: Daniel Wagner <dwagner@suse.de>
> ---
>  src/rt-migrate-test/rt-migrate-test.8 | 41 +++++++-------
>  src/rt-migrate-test/rt-migrate-test.c | 82 +++++++++++++--------------
>  2 files changed, 59 insertions(+), 64 deletions(-)
> 
> diff --git a/src/rt-migrate-test/rt-migrate-test.8 b/src/rt-migrate-test/rt-migrate-test.8
> index b9c07f1ed80a..5bbacb5333b8 100644
> --- a/src/rt-migrate-test/rt-migrate-test.8
> +++ b/src/rt-migrate-test/rt-migrate-test.8
> @@ -1,11 +1,11 @@
>  .\"
> -.TH RT-MIGRATE-TEST 8 "April 21, 2016"
> +.TH RT-MIGRATE-TEST 8 "September 18, 2020"
>  .\" Please adjust this date whenever editing this manpage
>  .SH NAME
>  rt-migrate-test \- real-time task migration program
>  .SH SYNOPSIS
> -.B rt-migrate-test 
> -.RI "[\-ceh] [\-p prio] [\-r time] [\-s time] [\-m time] [\-l loops] [nr_tasks]
> +.LP
> +rt-migrate-test [-c|--check] [-D|--duration TIME] [-e|--equal] [-h|--help] [-l|--loops LOOPS] [-m|--maxerr TIME] [-p|--prio PRIO] [-r|--run-time TIME] [-s|--sleep-time TIME] [NR_TASKS]
>  .SH DESCRIPTION
>  Test real-time multiprocessor scheduling of tasks to ensure the highest priority tasks are running on all available CPUs
>  .SH OPTIONS
> @@ -15,44 +15,43 @@ This program follows the usual GNU command line syntax, with long options starti
>  In the summary of options, a value in brackets (), indicates a default value
>  .br
>  .TP
> +.B \-c, \-\-check
> +Stop if lower prio task is quicker than higher (off)
> +.TP
>  .B \-D, \-\-duration=TIME
>  Specify a length for the test run.
>  .br
>  Append 'm', 'h', or 'd' to specify minutes, hours or days.
>  .TP
> -.B \-p, \-\-prio=prio
> -base priority to start RT tasks with (2)
> +.B \-e, \-\-equal
> +Use equal prio for #CPU-1 tasks (requires > 2 CPUS)
>  .br
>  .TP
> -.B \-r, \-\-run\-time=time
> -Run time (ms) to busy loop the threads (20)
> +.B \-h, \-\-help
> +Display usage
>  .br
>  .TP
> -.B \-s, \-\-sleep\-time=time
> -Sleep time (ms) between intervals (100)
> +.B \-l \-\-loops=LOOPS
> +Number of iterations to run (50)
>  .br
>  .TP
> -.B \-m, \-\-maxerr=time
> +.B \-m, \-\-maxerr=TIME
>  Max allowed error (microsecs)
>  .br
>  .TP
> -.B \-l \-\-loops=loops
> -Number of iterations to run (50)
> -.br
> -.TP
> -.B \-e
> -Use equal prio for #CPU-1 tasks (requires > 2 CPUS)
> +.B \-p, \-\-prio=PRIO
> +base priority to start RT tasks with (2)
>  .br
>  .TP
> -.B \-c, \-\-check
> -Stop if lower prio task is quicker than higher (off)
> +.B \-r, \-\-run\-time=TIME
> +Run time (ms) to busy loop the threads (20)
>  .br
>  .TP
> -.B \-h, \-\-help
> -Display usage
> +.B \-s, \-\-sleep\-time=TIME
> +Sleep time (ms) between intervals (100)
>  .br
>  .TP
> -.B [nr\-tasks]
> +.B [NR_TASKS]
>  number of tasks to run (number of cpus + 1)
>  .br
>  .SH AUTHOR
> diff --git a/src/rt-migrate-test/rt-migrate-test.c b/src/rt-migrate-test/rt-migrate-test.c
> index 4863238edeb4..68824606faf1 100644
> --- a/src/rt-migrate-test/rt-migrate-test.c
> +++ b/src/rt-migrate-test/rt-migrate-test.c
> @@ -146,71 +146,67 @@ static void print_progress_bar(int percent)
>  	fflush(stderr);
>  }
>  
> -static void usage(char **argv)
> +static void usage(int error)
>  {
> -	char *arg = argv[0];
> -	char *p = arg+strlen(arg);
> -
> -	while (p >= arg && *p != '/')
> -		p--;
> -	p++;
> -
> -	printf("%s %1.2f\n", p, VERSION);
> +	printf("rt-migrate-test %1.2f\n", VERSION);
>  	printf("Usage:\n"
> -	       "%s <options> nr_tasks\n\n"
> -	       "-p prio --prio  prio        base priority to start RT tasks with (2)\n"
> -	       "-r time --run-time time     Run time (ms) to busy loop the threads (20)\n"
> -	       "-s time --sleep-time time   Sleep time (ms) between intervals (100)\n"
> -	       "-m time --maxerr time       Max allowed error (microsecs)\n"
> -	       "-l loops --loops loops      Number of iterations to run (50)\n"
> -	       "-D       --duration=TIME    specify a length for the test run.\n"
> -	       "                            Append 'm', 'h', or 'd' to specify minutes, hours or days.\n"
> -	       "-e                          Use equal prio for #CPU-1 tasks (requires > 2 CPUS)\n"
> -	       "-c    --check               Stop if lower prio task is quicker than higher (off)\n"
> -	       "-h    --help\n"
> -	       "  () above are defaults \n",
> -		p);
> -	exit(0);
> +	       "rt-migrate-test <options> [NR_TASKS]\n\n"
> +	       "-c       --check           Stop if lower prio task is quicker than higher (off)\n"
> +	       "-D TIME  --duration=TIME   Specify a length for the test run.\n"
> +	       "                           Append 'm', 'h', or 'd' to specify minutes, hours or\n"
> +	       "                           days.\n"
> +	       "-e       --equal           Use equal prio for #CPU-1 tasks (requires > 2 CPUS)\n"
> +	       "-h       --help            Print this help message\n"
> +	       "-l LOOPS --loops=LOOPS     Number of iterations to run (50)\n"
> +	       "-m TIME  --maxerr=TIME     Max allowed error (microsecs)\n"
> +	       "-p PRIO  --prio=PRIO       base priority to start RT tasks with (2)\n"
> +	       "-r TIME  --run-time=TIME   Run time (ms) to busy loop the threads (20)\n"
> +	       "-s TIME  --sleep-time=TIME Sleep time (ms) between intervals (100)\n\n"
> +	       "  () above are defaults \n"
> +	       );
> +	exit(error);
>  }
>  
> -static void parse_options (int argc, char *argv[])
> +static void parse_options(int argc, char *argv[])
>  {
>  	for (;;) {
>  		int option_index = 0;
>  		/** Options for getopt */
>  		static struct option long_options[] = {
> -			{"prio", required_argument, NULL, 'p'},
> -			{"run-time", required_argument, NULL, 'r'},
> -			{"sleep-time", required_argument, NULL, 's'},
> -			{"maxerr", required_argument, NULL, 'm'},
> -			{"loops", required_argument, NULL, 'l'},
> -			{"duration", required_argument, NULL, 'D'},
> -			{"check", no_argument, NULL, 'c'},
> -			{"help", no_argument, NULL, '?'},
> +			{"check",	no_argument,		NULL, 'c'},
> +			{"duration",	required_argument,	NULL, 'D'},
> +			{"equal",	no_argument,		NULL, 'e'},
> +			{"help",	no_argument,		NULL, 'h'},
> +			{"loops",	required_argument,	NULL, 'l'},
> +			{"maxerr",	required_argument,	NULL, 'm'},
> +			{"prio",	required_argument,	NULL, 'p'},
> +			{"run-time",	required_argument,	NULL, 'r'},
> +			{"sleep-time",	required_argument,	NULL, 's'},
>  			{NULL, 0, NULL, 0}
>  		};
> -		int c = getopt_long (argc, argv, "p:r:s:m:l:D:ech",
> +		int c = getopt_long(argc, argv, "cD:ehl:m:p:r:s:",
>  			long_options, &option_index);
>  		if (c == -1)
>  			break;
>  		switch (c) {
> -		case 'p': prio_start = atoi(optarg); break;
> -		case 'r':
> -			run_interval = atoi(optarg);
> -			break;
> -		case 's': interval = atoi(optarg); break;
> -		case 'l': nr_runs = atoi(optarg); break;
> +		case 'c': check = 1; break;
>  		case 'D': duration = parse_time_string(optarg); break;
> -		case 'm': max_err = usec2nano(atoi(optarg)); break;
>  		case 'e': equal = 1; break;
> -		case 'c': check = 1; break;
>  		case '?':
>  		case 'h':
> -			usage(argv);
> +			usage(0);
>  			break;
> +		case 'l': nr_runs = atoi(optarg); break;
> +		case 'm': max_err = usec2nano(atoi(optarg)); break;
> +		case 'p': prio_start = atoi(optarg); break;
> +		case 'r':
> +			run_interval = atoi(optarg);
> +			break;
> +		case 's': interval = atoi(optarg); break;
> +		default:
> +			usage(1);
>  		}
>  	}
> -
>  }
>  
>  static unsigned long long get_time(void)
> -- 
> 2.28.0
> 
> 
Signed-off-by: John Kacur <jkacur@redhat.com>
John Kacur Oct. 23, 2020, 6:57 p.m. UTC | #8
On Wed, 7 Oct 2020, Daniel Wagner wrote:

> Signed-off-by: Daniel Wagner <dwagner@suse.de>

> ---

>  src/ssdd/ssdd.8 | 35 +++++++++++++++++-----------------

>  src/ssdd/ssdd.c | 50 +++++++++++++++++++++++++++----------------------

>  2 files changed, 45 insertions(+), 40 deletions(-)

> 

> diff --git a/src/ssdd/ssdd.8 b/src/ssdd/ssdd.8

> index 99f30145d079..5c29d0abb732 100644

> --- a/src/ssdd/ssdd.8

> +++ b/src/ssdd/ssdd.8

> @@ -1,31 +1,30 @@

> -.TH SSDD 8 "June 13, 2019"

> +.TH SSDD 8 "September 19, 2020"

>  .SH NAME

>  ssdd \- have a tracer do a bunch of PTRACE_SINGLESTEPs

>  .SH SYNOPSIS

> -.B ssdd

> -.RI "<options>"

> +.LP

> +ssdd [-f|--forks NUM] [-h|--help] [-i|--iters NUM]

>  .SH DESCRIPTION

> -Have a tracer do a bunch of PTRACE_SINGLESTEPs against

> -a tracee as fast as possible.  Create several of these

> -tracer/tracee pairs and see if they can be made to

> -interfere with each other.

> -The tracer waits on each PTRACE_SINGLESTEP with a waitpid(2)

> -and checks that waitpid's return values for correctness.

> +Have a tracer do a bunch of PTRACE_SINGLESTEPs against a tracee as

> +fast as possible. Create several of these tracer/tracee pairs and

> +see if they can be made to interfere with each other. The tracer

> +waits on each PTRACE_SINGLESTEP with a waitpid(2) and checks that

> +waitpid's return values for correctness.

>  .SH OPTIONS

> -.B \-f, \-\-forks

> -number of tracer/tracee pairs to fork off.

> -Default is 10.

> -.br

>  .TP

> -.B \-i, \-\-iters

> -number of PTRACE_SINGLESTEP iterations to

> -do before declaring success, for each tracer/

> -tracee pair set up. Default is 10,000.

> +.B \-f, \-\-forks=NUM

> +number of tracer/tracee pairs to fork off.

>  .br

> +Default is 10.

>  .TP

>  .B \-h, \-\-help

>  Display usage

> -

> +.TP

> +.B \-i, \-\-iters=NUM

> +number of PTRACE_SINGLESTEP iterations to do before declaring

> +success, for each tracer tracee pair set up.

> +.br

> +Default is 10,000.

>  .SH AUTHOR

>  ssdd was written by Joe Korty <joe.korty@concurrent-rt.com>

>  .PP

> diff --git a/src/ssdd/ssdd.c b/src/ssdd/ssdd.c

> index f165da96e23a..66d6009dc572 100644

> --- a/src/ssdd/ssdd.c

> +++ b/src/ssdd/ssdd.c

> @@ -68,13 +68,16 @@ static int got_sigchld;

>  

>  enum option_value { OPT_NFORKS=1, OPT_NITERS, OPT_HELP };

>  

> -static void usage()

> +static void usage(int error)

>  {

> -	printf("ssdd <options>\n");

> -	printf("\t-f --forks=<number of forks>\n");

> -	printf("\t-i --iters=<number of iterations>\n");

> -	printf("\t-h --help\n");

> -	exit(0);

> +	printf("ssdd V %1.2f\n", VERSION);

> +	printf("Usage:\n"

> +	       "ssdd <options>\n\n"

> +	       "-f       --forks=NUM       number of forks\n"

> +	       "-h       --help            print this message\n"

> +	       "-i       --iters=NUM       number of iterations\n"

> +	       );

> +	exit(error);

>  }

>  

>  static int do_wait(pid_t *wait_pid, int *ret_sig)

> @@ -292,27 +295,30 @@ int main(int argc, char **argv)

>  		int option_index = 0;

>  

>  		static struct option long_options[] = {

> -			{"forks", required_argument, NULL, OPT_NFORKS},

> -			{"iters", required_argument, NULL, OPT_NITERS},

> -			{"help", no_argument, NULL, OPT_HELP},

> +			{"forks",		required_argument,	NULL, OPT_NFORKS},

> +			{"help",		no_argument,		NULL, OPT_HELP},

> +			{"iters",		required_argument,	NULL, OPT_NITERS},

>  			{NULL, 0, NULL, 0},

>  		};

> -		int c = getopt_long(argc, argv, "f:i:h", long_options, &option_index);

> +		int c = getopt_long(argc, argv, "f:hi:", long_options, &option_index);

>  		if (c == -1)

>  			break;

>  		switch(c) {

> -			case 'f':

> -			case OPT_NFORKS:

> -				nforks = atoi(optarg);

> -				break;

> -			case 'i':

> -			case OPT_NITERS:

> -				nsteps = atoi(optarg);

> -				break;

> -			case 'h':

> -			case OPT_HELP:

> -				usage();

> -				break;

> +		case 'f':

> +		case OPT_NFORKS:

> +			nforks = atoi(optarg);

> +			break;

> +		case 'h':

> +		case OPT_HELP:

> +			usage(0);

> +			break;

> +		case 'i':

> +		case OPT_NITERS:

> +			nsteps = atoi(optarg);

> +			break;

> +		default:

> +			usage(1);

> +			break;

>  		}

>  	}

>  

> -- 

> 2.28.0

> 

> 

Signed-off-by: John Kacur <jkacur@redhat.com>
John Kacur Oct. 23, 2020, 7:03 p.m. UTC | #9
On Wed, 7 Oct 2020, Daniel Wagner wrote:

> Signed-off-by: Daniel Wagner <dwagner@suse.de>

> ---

>  src/hackbench/hackbench.8 |  70 ++++++++++++++------------

>  src/hackbench/hackbench.c | 102 ++++++++++++++++++--------------------

>  2 files changed, 86 insertions(+), 86 deletions(-)

> 

> diff --git a/src/hackbench/hackbench.8 b/src/hackbench/hackbench.8

> index aaf572359704..4c2c8ad9cb1a 100644

> --- a/src/hackbench/hackbench.8

> +++ b/src/hackbench/hackbench.8

> @@ -1,13 +1,17 @@

> -.TH "hackbench" "8" "February  23, 2010" "" ""

> +.TH "hackbench" "8" "September  19, 2020" "" ""

>  .SH "NAME"

>  hackbench \- scheduler benchmark/stress test

>  .SH "SYNOPSIS"

>  .B hackbench

> -.RI "[\-p|\-\-pipe] [\-s|\-\-datasize " <bytes> "] " 

> -.RI "[\-l|\-\-loops " <num\-loops> "] "

> -.RI "[\-g|\-\-groups "<num\-groups> "] "

> -.RI "[\-f|\-\-fds <num\-fds>] "

> -.RI "[\-T|\-\-threads] [\-P|\-\-process] [\-F|\-\-fifo] [\-\-help]"

> +.RI "[\-f|\-\-fds NUM] "

> +.RI "[\-F|\-\-fifo] "

> +.RI "[\-g|\-\-groups NUM] "

> +.RI "[\-h|\-\-help] "

> +.RI "[\-l|\-\-loops LOOPS] "

> +.RI "[\-p|\-\-pipe] "

> +.RI "[\-s|\-\-datasize SIZE] "

> +.RI "[\-T|\-\-threads]"

> +.RI "[\-P|\-\-process]"

>  

>  .SH "DESCRIPTION"

>  Hackbench is both a benchmark and a stress test for the Linux kernel

> @@ -19,45 +23,45 @@ each pair to send data back and forth.

>  .SH "OPTIONS"

>  These programs follow the usual GNU command line syntax, with long

>  options starting with two dashes ("\-\-").

> -.br 

> +.br

>  A summary of options is included below.

> -.TP 

> +.TP

> +.B \-f, \-\-fds=NUM

> +Defines how many file descriptors each child should use.

> +Note that the effective number will be twice the amount you set here,

> +as the sender and receiver children will each open the given amount of

> +file descriptors.

> +.TP

> +.B \-F,\-\-fifo

> +Change the main thread to SCHED_FIFO after creating workers.

> +This allows the management thread to run after many workers are created.

> +.TP

> +.B \-g, \-\-groups=NUM

> +Defines how many groups of senders and receivers should be started

> +.TP

> +.B \-h, \-\-help

> +.TP

> +.B \-l, \-\-loops=LOOPS

> +How many messages each sender/receiver pair should send

> +.TP

>  .B \-p, \-\-pipe

>  Sends the data via a pipe instead of the socket (default)

> -.TP 

> -.B \-s, \-\-datasize=<size in bytes>

> +.TP

> +.B \-s, \-\-datasize=SIZE

>  Sets the amount of data to send in each message

> -.TP 

> -.B \-l, \-\-loops=<number of loops>

> -How many messages each sender/receiver pair should send

> -.TP 

> -.B \-g, \-\-groups=<number of groups>

> -Defines how many groups of senders and receivers should be started

> -.TP 

> -.B \-f, \-\-fds=<number of file descriptors>

> -Defines how many file descriptors each child should use. 

> -Note that the effective number will be twice the amount you set here,

> -as the sender and receiver children will each open the given amount of 

> -file descriptors.

> -.TP 

> +.TP

>  .B \-T, \-\-threads

>  Each sender/receiver child will be a POSIX thread of the parent.

> -.TP 

> +.TP

>  .B \-P, \-\-process

>  Hackbench will use fork() on all children (default behaviour)

> -.TP

> -.B \-F,\-\-fifo

> -Change the main thread to SCHED_FIFO after creating workers.

> -This allows the management thread to run after many workers are created.

> -.TP 

> -.B \-\-help

> -.br 

> +.br

>  Shows a simple help screen

>  .SH "EXAMPLES"

> -.LP 

> +.LP

>  Running hackbench without any options will give default behaviour,

>  using fork() and sending data between senders and receivers via sockets.

> -.LP 

> +.LP

>  user@host: ~ $ hackbench

>  .br 

>  Running in process mode with 10 groups using 40 file descriptors each (== 400 tasks)

> diff --git a/src/hackbench/hackbench.c b/src/hackbench/hackbench.c

> index 2cddff654df6..268c23233004 100644

> --- a/src/hackbench/hackbench.c

> +++ b/src/hackbench/hackbench.c

> @@ -88,12 +88,22 @@ static void barf(const char *msg)

>  	exit(1);

>  }

>  

> -static void print_usage_exit()

> +static void print_usage_exit(int error)

>  {

> -	printf("Usage: hackbench [-p|--pipe] [-s|--datasize <bytes>] [-l|--loops <num loops>]\n"

> -	       "\t\t [-g|--groups <num groups] [-f|--fds <num fds>]\n"

> -	       "\t\t [-T|--threads] [-P|--process] [-F|--fifo] [--help]\n");

> -	exit(1);

> +	printf("hackbench V %1.2f\n", VERSION);

> +	printf("Usage:\n"

> +	       "hackbench <options>\n\n"

> +	       "-f       --fds=NUM         number of fds\n"

> +	       "-F       --fifo            use SCHED_FIFO for main thread\n"

> +	       "-g       --groups=NUM      number of groups to be used\n"

> +	       "-h       --help            print this message\n"

> +	       "-l       --loops=LOOPS     how many message should be send\n"

> +	       "-p       --pipe            send data via a pipe\n"

> +	       "-s       --datasize=SIZE   message size\n"

> +	       "-T       --threads         use POSIX threads\n"

> +	       "-P       --process         use fork (default)\n"

> +	       );

> +	exit(error);

>  }

>  

>  static void fdpair(int fds[2])

> @@ -342,86 +352,72 @@ static unsigned int group(childinfo_t *child,

>  	return num_fds * 2;

>  }

>  

> -static void process_options (int argc, char *argv[])

> +static void process_options(int argc, char *argv[])

>  {

> -	int error = 0;

> -

> -	while( 1 ) {

> +	for(;;) {

>  		int optind = 0;

>  

>  		static struct option longopts[] = {

> -			{"pipe",      no_argument,	 NULL, 'p'},

> -			{"datasize",  required_argument, NULL, 's'},

> -			{"loops",     required_argument, NULL, 'l'},

> -			{"groups",    required_argument, NULL, 'g'},

> -			{"fds",	      required_argument, NULL, 'f'},

> -			{"threads",   no_argument,	 NULL, 'T'},

> -			{"processes", no_argument,	 NULL, 'P'},

> -			{"fifo",      no_argument,       NULL, 'F'},

> -			{"help",      no_argument,	 NULL, 'h'},

> +			{"fds",		required_argument,	NULL, 'f'},

> +			{"fifo",	no_argument,		NULL, 'F'},

> +			{"groups",	required_argument,	NULL, 'g'},

> +			{"help",	no_argument,		NULL, 'h'},

> +			{"loops",	required_argument,	NULL, 'l'},

> +			{"pipe",	no_argument,		NULL, 'p'},

> +			{"datasize",	required_argument,	NULL, 's'},

> +			{"threads",	no_argument,		NULL, 'T'},

> +			{"processes",	no_argument,		NULL, 'P'},

>  			{NULL, 0, NULL, 0}

>  		};

>  

> -		int c = getopt_long(argc, argv, "ps:l:g:f:TPFh",

> +		int c = getopt_long(argc, argv, "f:Fg:hl:ps:TP",

>  				    longopts, &optind);

>  		if (c == -1) {

>  			break;

>  		}

>  		switch (c) {

> -		case 'p':

> -			use_pipes = 1;

> +		case 'f':

> +			if (!(argv[optind] && (num_fds = atoi(optarg)) > 0)) {

> +				fprintf(stderr, "%s: --fds|-f requires an integer > 0\n", argv[0]);

> +				print_usage_exit(1);

> +			}

>  			break;

> -

> -		case 's':

> -			if (!(argv[optind] && (datasize = atoi(optarg)) > 0)) {

> -				fprintf(stderr, "%s: --datasize|-s requires an integer > 0\n", argv[0]);

> -				error = 1;

> +		case 'F':

> +			fifo = 1;

> +			break;

> +		case 'g':

> +			if (!(argv[optind] && (num_groups = atoi(optarg)) > 0)) {

> +				fprintf(stderr, "%s: --groups|-g requires an integer > 0\n", argv[0]);

> +				print_usage_exit(1);

>  			}

>  			break;

> -

> +		case 'h':

> +			print_usage_exit(0);

>  		case 'l':

>  			if (!(argv[optind] && (loops = atoi(optarg)) > 0)) {

>  				fprintf(stderr, "%s: --loops|-l requires an integer > 0\n", argv[0]);

> -				error = 1;

> +				print_usage_exit(1);

>  			}

>  			break;

> -

> -		case 'g':

> -			if (!(argv[optind] && (num_groups = atoi(optarg)) > 0)) {

> -				fprintf(stderr, "%s: --groups|-g requires an integer > 0\n", argv[0]);

> -				error = 1;

> -			}

> +		case 'p':

> +			use_pipes = 1;

>  			break;

> -

> -		case 'f':

> -			if (!(argv[optind] && (num_fds = atoi(optarg)) > 0)) {

> -				fprintf(stderr, "%s: --fds|-f requires an integer > 0\n", argv[0]);

> -				error = 1;

> +		case 's':

> +			if (!(argv[optind] && (datasize = atoi(optarg)) > 0)) {

> +				fprintf(stderr, "%s: --datasize|-s requires an integer > 0\n", argv[0]);

> +				print_usage_exit(1);

>  			}

>  			break;

> -

>  		case 'T':

>  			process_mode = THREAD_MODE;

>  			break;

>  		case 'P':

>  			process_mode = PROCESS_MODE;

>  			break;

> -

> -		case 'F':

> -			fifo = 1;

> -			break;

> -

> -		case 'h':

> -			print_usage_exit();

> -

>  		default:

> -			error = 1;

> +			print_usage_exit(1);

>  		}

>  	}

> -

> -	if( error ) {

> -		exit(1);

> -	}

>  }

>  

>  void sigcatcher(int sig) {

> -- 

> 2.28.0

> 

> 

Signed-off-by: John Kacur <jkacur@redhat.com>
Daniel Wagner Oct. 26, 2020, 6:34 p.m. UTC | #10
Hi John,

On Fri, Oct 23, 2020 at 11:46:54AM -0400, John Kacur wrote:
> >  TARGETS = $(sources:.c=)
> >  LIBS	= -lrt -lpthread
> > -RTTESTLIB = -lrttest -L$(OBJDIR)
> > +RTTESTLIB = -lrttest -L$(OBJDIR) $(NUMA_LIBS)
> 
> Currently only cyclictest was compiled with NUMA_LIBS, this change will 
> compile everything with NUMA_LIBS. I checked the size of the programs, and 
> they don't grow that much with this change, but they are small programs to
> begin with, do we want to keep this functionality separate?

My thinking is, that the most important program for testing seems to be
cyclictest. Everyone will run cyclictest on the target platform. Thus
libnuma will be available. So there wont be any new unresolved
dependencies.

I traded the size increase for simplification in the code base and build
setup. Looking at the actual increase (x86_64, stripped) is not too bad:


program                 old      new     diff
---------------------------------------------------
cyclicdeadline          35488    35552     64 0.18%
cyclictest              57632    57632      0 0.0%
deadline_test           43712    43776     64 0.15%
hackbench               19168    19168      0 0.0%
oslat                   36040    36072     32 0.089%
pip_stress              27296    27360     64 0.23%
pi_stress               44296    48456   4160 9.4%
pmqtest                 31864    31928     64 0.2%
ptsematest              31752    31816     64 0.2%
queuelat                14600    14600      0 0.0%
rt-migrate-test         31696    31728     32 0.1%
signaltest              31712    31776     64 0.2%
sigwaittest             31792    31856     64 0.2%
ssdd                    14744    14744      0 0.0%
svsematest              31856    31920     64 0.2%


pi_stress is a bit odd though. Not sure what's happening there. Will
look into it.

So I would prefer to go this route and makes things simpler in the code
base.

Thanks,
Daniel
Daniel Wagner Oct. 27, 2020, 8:09 a.m. UTC | #11
On Fri, Oct 23, 2020 at 01:25:56PM -0400, John Kacur wrote:
> This one is pending either your changes that I requested to the first 
> patch, or an argument as to why I should accept the first patch.

Ok. Let me know what you think about my argument in my reply to the
first patch.
John Kacur Oct. 29, 2020, 3:45 p.m. UTC | #12
On Mon, 26 Oct 2020, Daniel Wagner wrote:

> Hi John,

> 

> On Fri, Oct 23, 2020 at 11:46:54AM -0400, John Kacur wrote:

> > >  TARGETS = $(sources:.c=)

> > >  LIBS	= -lrt -lpthread

> > > -RTTESTLIB = -lrttest -L$(OBJDIR)

> > > +RTTESTLIB = -lrttest -L$(OBJDIR) $(NUMA_LIBS)

> > 

> > Currently only cyclictest was compiled with NUMA_LIBS, this change will 

> > compile everything with NUMA_LIBS. I checked the size of the programs, and 

> > they don't grow that much with this change, but they are small programs to

> > begin with, do we want to keep this functionality separate?

> 

> My thinking is, that the most important program for testing seems to be

> cyclictest. Everyone will run cyclictest on the target platform. Thus

> libnuma will be available. So there wont be any new unresolved

> dependencies.

> 

> I traded the size increase for simplification in the code base and build

> setup. Looking at the actual increase (x86_64, stripped) is not too bad:

> 

> 

> program                 old      new     diff

> ---------------------------------------------------

> cyclicdeadline          35488    35552     64 0.18%

> cyclictest              57632    57632      0 0.0%

> deadline_test           43712    43776     64 0.15%

> hackbench               19168    19168      0 0.0%

> oslat                   36040    36072     32 0.089%

> pip_stress              27296    27360     64 0.23%

> pi_stress               44296    48456   4160 9.4%

> pmqtest                 31864    31928     64 0.2%

> ptsematest              31752    31816     64 0.2%

> queuelat                14600    14600      0 0.0%

> rt-migrate-test         31696    31728     32 0.1%

> signaltest              31712    31776     64 0.2%

> sigwaittest             31792    31856     64 0.2%

> ssdd                    14744    14744      0 0.0%

> svsematest              31856    31920     64 0.2%

> 

> 

> pi_stress is a bit odd though. Not sure what's happening there. Will

> look into it.

> 

> So I would prefer to go this route and makes things simpler in the code

> base.

> 

> Thanks,

> Daniel

> 


You're really just simplifying the Makefile, not the code. :)
Well, that and I guess this means I'm asking you to separate any common
numa functionality into a separate lib. If you want you can just pull out
parse_time_string(), and parse_mem_string() for now until we hash out
what we want to do with the numa functionality later.

Does that work for you?

John
Peter Xu Feb. 10, 2021, 4:08 p.m. UTC | #13
On Wed, Oct 07, 2020 at 10:56:46AM +0200, Daniel Wagner wrote:
> Signed-off-by: Daniel Wagner <dwagner@suse.de>


Hi, Daniel,

This seems to have broken oslat with "oslat -v".  Would you help recover the
old behavior somehow?

Thanks,

-- 
Peter Xu
Peter Xu Feb. 10, 2021, 4:25 p.m. UTC | #14
On Wed, Feb 10, 2021 at 11:08:47AM -0500, Peter Xu wrote:
> On Wed, Oct 07, 2020 at 10:56:46AM +0200, Daniel Wagner wrote:

> > Signed-off-by: Daniel Wagner <dwagner@suse.de>

> 

> Hi, Daniel,

> 

> This seems to have broken oslat with "oslat -v".  Would you help recover the

> old behavior somehow?


To be explicit, I didn't mean only "oslat -v".  It dumps nothing now which
definitely is not right..  Also I explicitly dump version for every oslat run
because I wanted that to be with the output, so when user reports issue with
oslat we'll always know which version is it.  So besides the "oslat -v"
breakage, I'd really appreciate if you can add the version dump back with every
oslat run, too.

Thanks,

-- 
Peter Xu
Daniel Wagner Feb. 10, 2021, 4:30 p.m. UTC | #15
So this is only about oslat, right? I ask because you respone to the
email for ptsematest.
Peter Xu Feb. 10, 2021, 4:33 p.m. UTC | #16
On Wed, Feb 10, 2021 at 05:30:57PM +0100, Daniel Wagner wrote:
> So this is only about oslat, right? I ask because you respone to the

> email for ptsematest.


Sorry I replied to the wrong subject - yes it's about oslat, only.

Thanks,

-- 
Peter Xu
Daniel Wagner Feb. 10, 2021, 4:35 p.m. UTC | #17
--- a/src/oslat/oslat.c
+++ b/src/oslat/oslat.c
@@ -655,16 +655,10 @@ static void parse_options(int argc, char *argv[])
                         */
                        g.single_preheat_thread = true;
                        break;
-               case 'v':
-                       /*
-                        * Because we always dump the version even before parsing options,
-                        * what we need to do is to quit..
-                        */
-                       exit(0);
-                       break;
                case 'z':
                        g.output_omit_zero_buckets = 1;
                        break;
+               case 'v':
                case 'h':
                        usage(0);
                        break;



$ ./oslat -v
oslat V 1.10
Usage:
oslat <options>

This is an OS latency detector by running busy loops on specified cores.
Please run this tool using root.

Available options:

-b, --bucket-size      Specify the number of the buckets (4-1024)
-B, --bias             Add a bias to all the buckets using the estimated mininum
-c, --cpu-list         Specify CPUs to run on, e.g. '1,3,5,7-15'
-C, --cpu-main-thread  Specify which CPU the main thread runs on.  Default is cpu0.
-D, --duration         Specify test duration, e.g., 60, 20m, 2H
                       (m/M: minutes, h/H: hours, d/D: days)
-f, --rtprio           Using SCHED_FIFO priority (1-99)
-m, --workload-mem     Size of the memory to use for the workload (e.g., 4K, 1M).
                       Total memory usage will be this value multiplies 2*N,
                       because there will be src/dst buffers for each thread, and
                       N is the number of processors for testing.
-s, --single-preheat   Use a single thread when measuring latency at preheat stage
                       NOTE: please make sure the CPU frequency on all testing cores
                       are locked before using this parmater.  If you don't know how
                       to lock the freq then please don't use this parameter.
-T, --trace-threshold  Stop the test when threshold triggered (in us),
                       print a marker in ftrace and stop ftrace too.
-v, --version          Display the version of the software.
-w, --workload         Specify a kind of workload, default is no workload
                       (options: no, memmove)
-z, --zero-omit        Don't display buckets in the output histogram if all zeros.



The other tests print also the usage text which included the version if
you provided '--version'. So this would make it behave in the same way.
Good enough?
Peter Xu Feb. 10, 2021, 5 p.m. UTC | #18
On Wed, Feb 10, 2021 at 05:35:37PM +0100, Daniel Wagner wrote:
> --- a/src/oslat/oslat.c

> +++ b/src/oslat/oslat.c

> @@ -655,16 +655,10 @@ static void parse_options(int argc, char *argv[])

>                          */

>                         g.single_preheat_thread = true;

>                         break;

> -               case 'v':

> -                       /*

> -                        * Because we always dump the version even before parsing options,

> -                        * what we need to do is to quit..

> -                        */

> -                       exit(0);

> -                       break;

>                 case 'z':

>                         g.output_omit_zero_buckets = 1;

>                         break;

> +               case 'v':

>                 case 'h':

>                         usage(0);

>                         break;

> 

> 

> 

> $ ./oslat -v

> oslat V 1.10

> Usage:

> oslat <options>

> 

> This is an OS latency detector by running busy loops on specified cores.

> Please run this tool using root.

> 

> Available options:

> 

> -b, --bucket-size      Specify the number of the buckets (4-1024)

> -B, --bias             Add a bias to all the buckets using the estimated mininum

> -c, --cpu-list         Specify CPUs to run on, e.g. '1,3,5,7-15'

> -C, --cpu-main-thread  Specify which CPU the main thread runs on.  Default is cpu0.

> -D, --duration         Specify test duration, e.g., 60, 20m, 2H

>                        (m/M: minutes, h/H: hours, d/D: days)

> -f, --rtprio           Using SCHED_FIFO priority (1-99)

> -m, --workload-mem     Size of the memory to use for the workload (e.g., 4K, 1M).

>                        Total memory usage will be this value multiplies 2*N,

>                        because there will be src/dst buffers for each thread, and

>                        N is the number of processors for testing.

> -s, --single-preheat   Use a single thread when measuring latency at preheat stage

>                        NOTE: please make sure the CPU frequency on all testing cores

>                        are locked before using this parmater.  If you don't know how

>                        to lock the freq then please don't use this parameter.

> -T, --trace-threshold  Stop the test when threshold triggered (in us),

>                        print a marker in ftrace and stop ftrace too.

> -v, --version          Display the version of the software.

> -w, --workload         Specify a kind of workload, default is no workload

>                        (options: no, memmove)

> -z, --zero-omit        Don't display buckets in the output histogram if all zeros.

> 

> 

> 

> The other tests print also the usage text which included the version if

> you provided '--version'. So this would make it behave in the same way.

> Good enough?


It makes sense to make all binaries in rt-tests behave similarly, so regarding
"oslat -v" even if it's not my preference, it's fine to me.

Again - Would you consider also dump the version in the output as before even
for a normal run?

-- 
Peter Xu
Daniel Wagner Feb. 10, 2021, 5:24 p.m. UTC | #19
> It makes sense to make all binaries in rt-tests behave similarly, so regarding

> "oslat -v" even if it's not my preference, it's fine to me.


We could also update all other tools to just print the version string
for '--version'. I don't have a strong preference. My main concern is
that I don't want the tools to differ in the usage pattern. BTW, I think
I would drop '-v' as short command line option as for example cyclictest
uses '-v' for verbose.

> Again - Would you consider also dump the version in the output as before even

> for a normal run?


Again, I don't have a strong opinion here. Just the same argument as
before, all tools should behave in the same way.