diff mbox series

[v2] rtla: Fix -t/--trace[=file]

Message ID 20240510213619.53529-1-jkacur@redhat.com (mailing list archive)
State Handled Elsewhere
Headers show
Series [v2] rtla: Fix -t/--trace[=file] | expand

Commit Message

John Kacur May 10, 2024, 9:36 p.m. UTC
Normally with a short option we don't provide an equals sign like this
-tfile.txt
-t file.txt

But we do provide an equals sign with the long option like this
--trace=file.txt

A good parser should also work with a space instead of an equals sign
--trace file.txt

Most of these are broken!

./rtla timerlat hist -P f:95 -u -c0-11 -E3500 -T50 -tfile.txt
Saving trace to ile.txt
File name truncated

./rtla timerlat hist -P f:95 -u -c0-11 -E3500 -T50 -t file.txt
Saving trace to timerlat_trace.txt
Default file name used instead of the requested one.

./rtla timerlat hist -P f:95 -u -c0-11 -E3500 -T50 -t=file.txt
Saving trace to file.txt
This works, but people normally don't use '=' with a short option

/rtla timerlat hist -P f:95 -u -c0-11 -E3500 -T50 --trace=file.txt
Saving trace to ile.txt
File name truncated

./rtla timerlat hist -P f:95 -u -c0-11 -E3500 -T50 --trace file.txt
timerlat_trace.txt
Default file name used instead of the requested one.

After the fix

./rtla timerlat hist -P f:95 -u -c0-11 -E3500 -T50 -tfile.txt
Saving trace to file.txt

./rtla timerlat hist -P f:95 -u -c0-11 -E3500 -T50 -t file.txt
Saving trace to file.txt

./rtla timerlat hist -P f:95 -u -c0-11 -E3500 -T50 -t=file.txt
Saving trace to file.txt

./rtla timerlat hist -P f:95 -u -c0-11 -E3500 -T50 --trace=file.txt
Saving trace to file.txt

./rtla timerlat hist -P f:95 -u -c0-11 -E3500 -T50 --trace file.txt
Saving trace to file.txt

I also tested -t and --trace without providing a file name both as the
last requested option and with a following long and short option

For example

./rtla timerlat hist -P f:95 -u -c0-11 -E3500 -T50 -t -u
./rtla timerlat hist -P f:95 -u -c0-11 -E3500 -T50 --trace -u
./rtla timerlat hist -P f:95 -u -c0-11 -E3500 -T50 -t
./rtla timerlat hist -P f:95 -u -c0-11 -E3500 -T50 --trace

And all correctly do Saving trace to timerlat_trace.txt as expected

This fix is applied to both timerlat top and hist
and to osnoise top and hist

Version 2

- Remove the '=' from [=file] in the on line help. Do the same thing
for the manpages.

Signed-off-by: John Kacur <jkacur@redhat.com>
---
 Documentation/tools/rtla/common_options.rst       |  4 ----
 .../tools/rtla/common_osnoise_options.rst         |  5 +++++
 .../tools/rtla/common_timerlat_options.rst        |  4 ++++
 tools/tracing/rtla/src/osnoise_hist.c             | 15 ++++++++++-----
 tools/tracing/rtla/src/osnoise_top.c              | 15 ++++++++++-----
 tools/tracing/rtla/src/timerlat_hist.c            | 15 ++++++++++-----
 tools/tracing/rtla/src/timerlat_top.c             | 15 ++++++++++-----
 7 files changed, 49 insertions(+), 24 deletions(-)

Comments

Daniel Bristot de Oliveira May 15, 2024, 1:22 p.m. UTC | #1
Hi John

I was applying it, and doing some small corrections in the log myself,
but I noticed some points we need to address in the code. So I am
replying also with suggestions about the log.

Nothing critical, we do need this patch :-)

On 5/10/24 23:36, John Kacur wrote:
> Normally with a short option we don't provide an equals sign like this
> -tfile.txt
> -t file.txt
> 
> But we do provide an equals sign with the long option like this
> --trace=file.txt
> 
> A good parser should also work with a space instead of an equals sign
> --trace file.txt
> 
> Most of these are broken!

While on discussions some more emphasis is required when people are
not in agreement, I'd prefer to keep the log flat on emphasis. A phrase
without the ! is better.

I generally follow script that Arnaldo once explained me:

1 - decribe the current expected beahvior.
2 - describe the issue - with a reproducer if possible (like you did).
3 - explain the solution
4 - show the expected results.

So, I would write something like this.

The -t option has an optional argument, specified after an = sign.

Ex:

  # rtla timerlat hist -u -T50 -t=file.txt

[ noticed that I removed the non-excential commands, e.g., P:95 is the default ]


Normally with a short option we don't provide an equals sign like this:
-tfile.txt -t file.txt. Moreover some other ways of using it are broken.

For example:

[ your examples ]
> 
> ./rtla timerlat hist -P f:95 -u -c0-11 -E3500 -T50 -tfile.txt
> Saving trace to ile.txt
> File name truncated
> 
> ./rtla timerlat hist -P f:95 -u -c0-11 -E3500 -T50 -t file.txt
> Saving trace to timerlat_trace.txt
> Default file name used instead of the requested one.
> 
> ./rtla timerlat hist -P f:95 -u -c0-11 -E3500 -T50 -t=file.txt
> Saving trace to file.txt
> This works, but people normally don't use '=' with a short option
> 
> /rtla timerlat hist -P f:95 -u -c0-11 -E3500 -T50 --trace=file.txt
> Saving trace to ile.txt
> File name truncated
> 
> ./rtla timerlat hist -P f:95 -u -c0-11 -E3500 -T50 --trace file.txt
> timerlat_trace.txt
> Default file name used instead of the requested one.

Here you should describe the fix, i can be an simple phrase like:

Properly parse the optional argument, considering the cases with and without =.

After the fix:>
> ./rtla timerlat hist -P f:95 -u -c0-11 -E3500 -T50 -tfile.txt
> Saving trace to file.txt
> 
> ./rtla timerlat hist -P f:95 -u -c0-11 -E3500 -T50 -t file.txt
> Saving trace to file.txt
> 
> ./rtla timerlat hist -P f:95 -u -c0-11 -E3500 -T50 -t=file.txt
> Saving trace to file.txt
> 
> ./rtla timerlat hist -P f:95 -u -c0-11 -E3500 -T50 --trace=file.txt
> Saving trace to file.txt
> 
> ./rtla timerlat hist -P f:95 -u -c0-11 -E3500 -T50 --trace file.txt
> Saving trace to file.txt
> 
> I also tested -t and --trace without providing a file name both as the
> last requested option and with a following long and short option

My personal preference is also to speak in third person, about the code, or in imperative
mode. Like:

Tested using...

> For example
For example:
> 
> ./rtla timerlat hist -P f:95 -u -c0-11 -E3500 -T50 -t -u
> ./rtla timerlat hist -P f:95 -u -c0-11 -E3500 -T50 --trace -u
> ./rtla timerlat hist -P f:95 -u -c0-11 -E3500 -T50 -t
> ./rtla timerlat hist -P f:95 -u -c0-11 -E3500 -T50 --trace
> 
> And all correctly do Saving trace to timerlat_trace.txt as expected
> 
> This fix is applied to both timerlat top and hist
> and to osnoise top and hist
> 

To make my life easier: the changes for each version will not show up
in the final log, so it is a good practice to place them after the "---".

> Version 2
> 
> - Remove the '=' from [=file] in the on line help. Do the same thing
> for the manpages.
> 
> Signed-off-by: John Kacur <jkacur@redhat.com>
> ---

[ here you place the changes when it is a single patch, for a patch ]
[ for a patch set it is enough to keep them only at the cover ]

>  Documentation/tools/rtla/common_options.rst       |  4 ----
>  .../tools/rtla/common_osnoise_options.rst         |  5 +++++
>  .../tools/rtla/common_timerlat_options.rst        |  4 ++++
>  tools/tracing/rtla/src/osnoise_hist.c             | 15 ++++++++++-----
>  tools/tracing/rtla/src/osnoise_top.c              | 15 ++++++++++-----
>  tools/tracing/rtla/src/timerlat_hist.c            | 15 ++++++++++-----
>  tools/tracing/rtla/src/timerlat_top.c             | 15 ++++++++++-----
>  7 files changed, 49 insertions(+), 24 deletions(-)
> 
> diff --git a/Documentation/tools/rtla/common_options.rst b/Documentation/tools/rtla/common_options.rst
> index aeb91ff3bd68..5d28ba61245c 100644
> --- a/Documentation/tools/rtla/common_options.rst
> +++ b/Documentation/tools/rtla/common_options.rst
> @@ -14,10 +14,6 @@
>  
>          Print debug info.
>  
> -**-t**, **--trace**\[*=file*]
> -
> -        Save the stopped trace to [*file|osnoise_trace.txt*].
> -
>  **-e**, **--event** *sys:event*
>  
>          Enable an event in the trace (**-t**) session. The argument can be a specific event, e.g., **-e** *sched:sched_switch*, or all events of a system group, e.g., **-e** *sched*. Multiple **-e** are allowed. It is only active when **-t** or **-a** are set.
> diff --git a/Documentation/tools/rtla/common_osnoise_options.rst b/Documentation/tools/rtla/common_osnoise_options.rst
> index f792ca58c211..b05eee23b539 100644
> --- a/Documentation/tools/rtla/common_osnoise_options.rst
> +++ b/Documentation/tools/rtla/common_osnoise_options.rst
> @@ -25,3 +25,8 @@
>  
>          Specify the minimum delta between two time reads to be considered noise.
>          The default threshold is *5 us*.
> +
> +**-t**, **--trace**\[*file*]
> +
> +        Save the pretty stopped trace to [*file|osnoise_trace.txt*].
> +
> diff --git a/Documentation/tools/rtla/common_timerlat_options.rst b/Documentation/tools/rtla/common_timerlat_options.rst
> index d3255ed70195..e4eca500b6a7 100644
> --- a/Documentation/tools/rtla/common_timerlat_options.rst
> +++ b/Documentation/tools/rtla/common_timerlat_options.rst
> @@ -22,6 +22,10 @@
>          Save the stack trace at the *IRQ* if a *Thread* latency is higher than the
>          argument in us.
>  
> +**-t**, **--trace**\[*file*]
> +
> +        Save the pretty stopped trace to [*file|timerlat_trace.txt*].
> +
>  **--dma-latency** *us*
>          Set the /dev/cpu_dma_latency to *us*, aiming to bound exit from idle latencies.
>          *cyclictest* sets this value to *0* by default, use **--dma-latency** *0* to have
> diff --git a/tools/tracing/rtla/src/osnoise_hist.c b/tools/tracing/rtla/src/osnoise_hist.c
> index 01870d50942a..ede8bb44919c 100644
> --- a/tools/tracing/rtla/src/osnoise_hist.c
> +++ b/tools/tracing/rtla/src/osnoise_hist.c
> @@ -436,7 +436,7 @@ static void osnoise_hist_usage(char *usage)
>  	static const char * const msg[] = {
>  		"",
>  		"  usage: rtla osnoise hist [-h] [-D] [-d s] [-a us] [-p us] [-r us] [-s us] [-S us] \\",
> -		"	  [-T us] [-t[=file]] [-e sys[:event]] [--filter <filter>] [--trigger <trigger>] \\",
> +		"	  [-T us] [-t[file]] [-e sys[:event]] [--filter <filter>] [--trigger <trigger>] \\",
>  		"	  [-c cpu-list] [-H cpu-list] [-P priority] [-b N] [-E N] [--no-header] [--no-summary] \\",
>  		"	  [--no-index] [--with-zeros] [-C[=cgroup_name]]",
>  		"",
> @@ -452,7 +452,7 @@ static void osnoise_hist_usage(char *usage)
>  		"	  -C/--cgroup[=cgroup_name]: set cgroup, if no cgroup_name is passed, the rtla's cgroup will be inherited",
>  		"	  -d/--duration time[s|m|h|d]: duration of the session",
>  		"	  -D/--debug: print debug info",
> -		"	  -t/--trace[=file]: save the stopped trace to [file|osnoise_trace.txt]",
> +		"	  -t/--trace[file]: save the stopped trace to [file|osnoise_trace.txt]",
>  		"	  -e/--event <sys:event>: enable the <sys:event> in the trace instance, multiple -e are allowed",
>  		"	     --filter <filter>: enable a trace event filter to the previous -e event",
>  		"	     --trigger <trigger>: enable a trace event trigger to the previous -e event",
> @@ -640,9 +640,14 @@ static struct osnoise_hist_params
>  			params->threshold = get_llong_from_str(optarg);
>  			break;
>  		case 't':
> -			if (optarg)
> -				/* skip = */
> -				params->trace_output = &optarg[1];
> +			if (optarg) {
> +				if (optarg[0] == '=')
> +					params->trace_output = &optarg[1];
> +				else
> +					params->trace_output = &optarg[0];
> +			}
> +			else if (optind < argc && argv[optind][0] != '0')
> +				params->trace_output = argv[optind];


checkpatch complained about these:
	}
	else

i.e.,

  ERROR: else should follow close brace '}'
  #231: FILE: tools/tracing/rtla/src/osnoise_hist.c:649:
  +			}
  +			else if (optind < argc && argv[optind][0] != '0')


it should be:
  +			} else if (optind < argc && argv[optind][0] != '0')

Finally, rebase it on top of:

https://git.kernel.org/pub/scm/linux/kernel/git/bristot/linux.git/log/?h=devel/rtla-for-6.10

Thanks!
-- Daniel
diff mbox series

Patch

diff --git a/Documentation/tools/rtla/common_options.rst b/Documentation/tools/rtla/common_options.rst
index aeb91ff3bd68..5d28ba61245c 100644
--- a/Documentation/tools/rtla/common_options.rst
+++ b/Documentation/tools/rtla/common_options.rst
@@ -14,10 +14,6 @@ 
 
         Print debug info.
 
-**-t**, **--trace**\[*=file*]
-
-        Save the stopped trace to [*file|osnoise_trace.txt*].
-
 **-e**, **--event** *sys:event*
 
         Enable an event in the trace (**-t**) session. The argument can be a specific event, e.g., **-e** *sched:sched_switch*, or all events of a system group, e.g., **-e** *sched*. Multiple **-e** are allowed. It is only active when **-t** or **-a** are set.
diff --git a/Documentation/tools/rtla/common_osnoise_options.rst b/Documentation/tools/rtla/common_osnoise_options.rst
index f792ca58c211..b05eee23b539 100644
--- a/Documentation/tools/rtla/common_osnoise_options.rst
+++ b/Documentation/tools/rtla/common_osnoise_options.rst
@@ -25,3 +25,8 @@ 
 
         Specify the minimum delta between two time reads to be considered noise.
         The default threshold is *5 us*.
+
+**-t**, **--trace**\[*file*]
+
+        Save the pretty stopped trace to [*file|osnoise_trace.txt*].
+
diff --git a/Documentation/tools/rtla/common_timerlat_options.rst b/Documentation/tools/rtla/common_timerlat_options.rst
index d3255ed70195..e4eca500b6a7 100644
--- a/Documentation/tools/rtla/common_timerlat_options.rst
+++ b/Documentation/tools/rtla/common_timerlat_options.rst
@@ -22,6 +22,10 @@ 
         Save the stack trace at the *IRQ* if a *Thread* latency is higher than the
         argument in us.
 
+**-t**, **--trace**\[*file*]
+
+        Save the pretty stopped trace to [*file|timerlat_trace.txt*].
+
 **--dma-latency** *us*
         Set the /dev/cpu_dma_latency to *us*, aiming to bound exit from idle latencies.
         *cyclictest* sets this value to *0* by default, use **--dma-latency** *0* to have
diff --git a/tools/tracing/rtla/src/osnoise_hist.c b/tools/tracing/rtla/src/osnoise_hist.c
index 01870d50942a..ede8bb44919c 100644
--- a/tools/tracing/rtla/src/osnoise_hist.c
+++ b/tools/tracing/rtla/src/osnoise_hist.c
@@ -436,7 +436,7 @@  static void osnoise_hist_usage(char *usage)
 	static const char * const msg[] = {
 		"",
 		"  usage: rtla osnoise hist [-h] [-D] [-d s] [-a us] [-p us] [-r us] [-s us] [-S us] \\",
-		"	  [-T us] [-t[=file]] [-e sys[:event]] [--filter <filter>] [--trigger <trigger>] \\",
+		"	  [-T us] [-t[file]] [-e sys[:event]] [--filter <filter>] [--trigger <trigger>] \\",
 		"	  [-c cpu-list] [-H cpu-list] [-P priority] [-b N] [-E N] [--no-header] [--no-summary] \\",
 		"	  [--no-index] [--with-zeros] [-C[=cgroup_name]]",
 		"",
@@ -452,7 +452,7 @@  static void osnoise_hist_usage(char *usage)
 		"	  -C/--cgroup[=cgroup_name]: set cgroup, if no cgroup_name is passed, the rtla's cgroup will be inherited",
 		"	  -d/--duration time[s|m|h|d]: duration of the session",
 		"	  -D/--debug: print debug info",
-		"	  -t/--trace[=file]: save the stopped trace to [file|osnoise_trace.txt]",
+		"	  -t/--trace[file]: save the stopped trace to [file|osnoise_trace.txt]",
 		"	  -e/--event <sys:event>: enable the <sys:event> in the trace instance, multiple -e are allowed",
 		"	     --filter <filter>: enable a trace event filter to the previous -e event",
 		"	     --trigger <trigger>: enable a trace event trigger to the previous -e event",
@@ -640,9 +640,14 @@  static struct osnoise_hist_params
 			params->threshold = get_llong_from_str(optarg);
 			break;
 		case 't':
-			if (optarg)
-				/* skip = */
-				params->trace_output = &optarg[1];
+			if (optarg) {
+				if (optarg[0] == '=')
+					params->trace_output = &optarg[1];
+				else
+					params->trace_output = &optarg[0];
+			}
+			else if (optind < argc && argv[optind][0] != '0')
+				params->trace_output = argv[optind];
 			else
 				params->trace_output = "osnoise_trace.txt";
 			break;
diff --git a/tools/tracing/rtla/src/osnoise_top.c b/tools/tracing/rtla/src/osnoise_top.c
index 457360db0767..f7794f97aeaa 100644
--- a/tools/tracing/rtla/src/osnoise_top.c
+++ b/tools/tracing/rtla/src/osnoise_top.c
@@ -281,7 +281,7 @@  static void osnoise_top_usage(struct osnoise_top_params *params, char *usage)
 
 	static const char * const msg[] = {
 		" [-h] [-q] [-D] [-d s] [-a us] [-p us] [-r us] [-s us] [-S us] \\",
-		"	  [-T us] [-t[=file]] [-e sys[:event]] [--filter <filter>] [--trigger <trigger>] \\",
+		"	  [-T us] [-t[file]] [-e sys[:event]] [--filter <filter>] [--trigger <trigger>] \\",
 		"	  [-c cpu-list] [-H cpu-list] [-P priority] [-C[=cgroup_name]]",
 		"",
 		"	  -h/--help: print this menu",
@@ -296,7 +296,7 @@  static void osnoise_top_usage(struct osnoise_top_params *params, char *usage)
 		"	  -C/--cgroup[=cgroup_name]: set cgroup, if no cgroup_name is passed, the rtla's cgroup will be inherited",
 		"	  -d/--duration time[s|m|h|d]: duration of the session",
 		"	  -D/--debug: print debug info",
-		"	  -t/--trace[=file]: save the stopped trace to [file|osnoise_trace.txt]",
+		"	  -t/--trace[file]: save the stopped trace to [file|osnoise_trace.txt]",
 		"	  -e/--event <sys:event>: enable the <sys:event> in the trace instance, multiple -e are allowed",
 		"	     --filter <filter>: enable a trace event filter to the previous -e event",
 		"	     --trigger <trigger>: enable a trace event trigger to the previous -e event",
@@ -480,9 +480,14 @@  struct osnoise_top_params *osnoise_top_parse_args(int argc, char **argv)
 			params->stop_total_us = get_llong_from_str(optarg);
 			break;
 		case 't':
-			if (optarg)
-				/* skip = */
-				params->trace_output = &optarg[1];
+			if (optarg){
+				if (optarg[0] == '=')
+					params->trace_output = &optarg[1];
+				else
+					params->trace_output = &optarg[0];
+			}
+			else if (optind < argc && argv[optind][0] != '-')
+				params->trace_output = argv[optind];
 			else
 				params->trace_output = "osnoise_trace.txt";
 			break;
diff --git a/tools/tracing/rtla/src/timerlat_hist.c b/tools/tracing/rtla/src/timerlat_hist.c
index 5b869caed10d..f555d8603b42 100644
--- a/tools/tracing/rtla/src/timerlat_hist.c
+++ b/tools/tracing/rtla/src/timerlat_hist.c
@@ -521,7 +521,7 @@  static void timerlat_hist_usage(char *usage)
 	char *msg[] = {
 		"",
 		"  usage: [rtla] timerlat hist [-h] [-q] [-d s] [-D] [-n] [-a us] [-p us] [-i us] [-T us] [-s us] \\",
-		"         [-t[=file]] [-e sys[:event]] [--filter <filter>] [--trigger <trigger>] [-c cpu-list] [-H cpu-list]\\",
+		"         [-t[file]] [-e sys[:event]] [--filter <filter>] [--trigger <trigger>] [-c cpu-list] [-H cpu-list]\\",
 		"	  [-P priority] [-E N] [-b N] [--no-irq] [--no-thread] [--no-header] [--no-summary] \\",
 		"	  [--no-index] [--with-zeros] [--dma-latency us] [-C[=cgroup_name]] [--no-aa] [--dump-task] [-u]",
 		"",
@@ -537,7 +537,7 @@  static void timerlat_hist_usage(char *usage)
 		"	  -d/--duration time[m|h|d]: duration of the session in seconds",
 		"	     --dump-tasks: prints the task running on all CPUs if stop conditions are met (depends on !--no-aa)",
 		"	  -D/--debug: print debug info",
-		"	  -t/--trace[=file]: save the stopped trace to [file|timerlat_trace.txt]",
+		"	  -t/--trace[file]: save the stopped trace to [file|timerlat_trace.txt]",
 		"	  -e/--event <sys:event>: enable the <sys:event> in the trace instance, multiple -e are allowed",
 		"	     --filter <filter>: enable a trace event filter to the previous -e event",
 		"	     --trigger <trigger>: enable a trace event trigger to the previous -e event",
@@ -744,9 +744,14 @@  static struct timerlat_hist_params
 			params->stop_total_us = get_llong_from_str(optarg);
 			break;
 		case 't':
-			if (optarg)
-				/* skip = */
-				params->trace_output = &optarg[1];
+			if (optarg) {
+				if (optarg[0] == '=')
+					params->trace_output = &optarg[1];
+				else
+					params->trace_output = &optarg[0];
+			}
+			else if (optind < argc && argv[optind][0] != '-')
+				params->trace_output = argv[optind];
 			else
 				params->trace_output = "timerlat_trace.txt";
 			break;
diff --git a/tools/tracing/rtla/src/timerlat_top.c b/tools/tracing/rtla/src/timerlat_top.c
index 8a3fa64319c6..5698dae30ec6 100644
--- a/tools/tracing/rtla/src/timerlat_top.c
+++ b/tools/tracing/rtla/src/timerlat_top.c
@@ -334,7 +334,7 @@  static void timerlat_top_usage(char *usage)
 	static const char *const msg[] = {
 		"",
 		"  usage: rtla timerlat [top] [-h] [-q] [-a us] [-d s] [-D] [-n] [-p us] [-i us] [-T us] [-s us] \\",
-		"	  [[-t[=file]] [-e sys[:event]] [--filter <filter>] [--trigger <trigger>] [-c cpu-list] [-H cpu-list]\\",
+		"	  [[-t[file]] [-e sys[:event]] [--filter <filter>] [--trigger <trigger>] [-c cpu-list] [-H cpu-list]\\",
 		"	  [-P priority] [--dma-latency us] [--aa-only us] [-C[=cgroup_name]] [-u]",
 		"",
 		"	  -h/--help: print this menu",
@@ -350,7 +350,7 @@  static void timerlat_top_usage(char *usage)
 		"	  -d/--duration time[m|h|d]: duration of the session in seconds",
 		"	  -D/--debug: print debug info",
 		"	     --dump-tasks: prints the task running on all CPUs if stop conditions are met (depends on !--no-aa)",
-		"	  -t/--trace[=file]: save the stopped trace to [file|timerlat_trace.txt]",
+		"	  -t/--trace[file]: save the stopped trace to [file|timerlat_trace.txt]",
 		"	  -e/--event <sys:event>: enable the <sys:event> in the trace instance, multiple -e are allowed",
 		"	     --filter <command>: enable a trace event filter to the previous -e event",
 		"	     --trigger <command>: enable a trace event trigger to the previous -e event",
@@ -547,9 +547,14 @@  static struct timerlat_top_params
 			params->stop_total_us = get_llong_from_str(optarg);
 			break;
 		case 't':
-			if (optarg)
-				/* skip = */
-				params->trace_output = &optarg[1];
+			if (optarg) {
+				if (optarg[0] == '=')
+					params->trace_output = &optarg[1];
+				else
+					params->trace_output = &optarg[0];
+			}
+			else if (optind < argc && argv[optind][0] != '-')
+				params->trace_output = argv[optind];
 			else
 				params->trace_output = "timerlat_trace.txt";