diff mbox series

[v2,4/4] trace-cmd: Dump fraction bits from TRACECMD_OPTION_TIME_SHIFT

Message ID 20211014150204.2485499-5-tz.stoyanov@gmail.com (mailing list archive)
State Accepted
Commit 1bff3a301fe5d034b2c1b9b61b19deeb45ff0e69
Headers show
Series trace-cmd: Align guest TSC calculation with the kernel | expand

Commit Message

Tzvetomir Stoyanov (VMware) Oct. 14, 2021, 3:02 p.m. UTC
As the TRACECMD_OPTION_TIME_SHIFT option is extended with new data,
fraction bits used to calculate the guest TSC clock in case of clock
scaling, it will be useful to dump that new information.

Signed-off-by: Tzvetomir Stoyanov (VMware) <tz.stoyanov@gmail.com>
---
 tracecmd/trace-dump.c | 102 ++++++++++++++++++++++++++++++------------
 1 file changed, 73 insertions(+), 29 deletions(-)

Comments

Steven Rostedt Nov. 9, 2021, 4:07 p.m. UTC | #1
On Thu, 14 Oct 2021 18:02:04 +0300
"Tzvetomir Stoyanov (VMware)" <tz.stoyanov@gmail.com> wrote:

> +		read_file_number(fd, &cpus_data[j].count, 4);
> +		size -= 4;
> +		do_print(OPTIONS, "%lld [samples count for CPU %d]\n", cpus_data[j].count, j);
> +		cpus_data[j].times = calloc(cpus_data[j].count, sizeof(long long));
> +		cpus_data[j].offsets = calloc(cpus_data[j].count, sizeof(long long));
> +		cpus_data[j].scalings = calloc(cpus_data[j].count, sizeof(long long));

> +		cpus_data[j].frac = calloc(cpus_data[j].count, sizeof(long long));

> +		if (!cpus_data[j].times || !cpus_data[j].offsets ||
> +		    !cpus_data[j].scalings || !cpus_data[j].frac)
> +			goto out;
> +		for (i = 0; i < cpus_data[j].count; i++) {
> +			if (size < 8)
> +				goto out;
> +			read_file_number(fd, cpus_data[j].times + i, 8);
> +			size -= 8;
> +		}
> +		for (i = 0; i < cpus_data[j].count; i++) {
> +			if (size < 8)
> +				goto out;
> +			read_file_number(fd, cpus_data[j].offsets + i, 8);
> +			size -= 8;
> +		}
> +		for (i = 0; i < cpus_data[j].count; i++) {
> +			if (size < 8)
> +				goto out;
> +			read_file_number(fd, cpus_data[j].scalings + i, 8);
> +			size -= 8;
> +		}
> +	}
>  
> +	if (size > 0) {
> +		for (j = 0; j < cpus; j++) {
> +			if (!cpus_data[j].frac)
> +				goto out;
> +			for (i = 0; i < cpus_data[j].count; i++) {
> +				if (size < 8)
> +					goto out;
> +				read_file_number(fd, cpus_data[j].frac + i, 8);
> +				size -= 8;
> +			}
> +		}
>  	}
> +
> +	for (j = 0; j < cpus; j++) {
> +		for (i = 0; i < cpus_data[j].count; i++)
> +			do_print(OPTIONS, "\t%lld %lld %llu %llu[offset * scaling >> fraction @ time]\n",
> +				 cpus_data[j].offsets[i], cpus_data[j].scalings[i],
> +				 cpus_data[j].frac[i], cpus_data[j].times[i]);
> +
> +	}
> +
>  out:
> -	free(times);
> -	free(offsets);
> -	free(scalings);
> +	if (j < cpus)
> +		do_print(OPTIONS, "Broken time shift option\n");
> +	for (j = 0; j < cpus; j++) {
> +		free(cpus_data[j].times);
> +		free(cpus_data[j].offsets);
> +		free(cpus_data[j].scalings);

Looks like you forgot to add:

		free(cpus_data[j].frac);

This is the only issue I found in this series. I'll just add a patch to fix
it and move on.

Thanks!

-- Steve


> +	}
> +	free(cpus_data);
diff mbox series

Patch

diff --git a/tracecmd/trace-dump.c b/tracecmd/trace-dump.c
index 2334b57e..ed97bd3f 100644
--- a/tracecmd/trace-dump.c
+++ b/tracecmd/trace-dump.c
@@ -376,13 +376,18 @@  static void dump_option_xlong(int fd, int size, char *desc)
 	do_print(OPTIONS, "0x%llX\n", val);
 }
 
+struct time_shift_cpu {
+	unsigned int count;
+	long long *scalings;
+	long long *frac;
+	long long *offsets;
+	unsigned long long *times;
+};
+
 static void dump_option_timeshift(int fd, int size)
 {
-	long long *scalings = NULL;
-	long long *offsets = NULL;
-	unsigned long long *times = NULL;
+	struct time_shift_cpu *cpus_data;
 	long long trace_id;
-	unsigned int count;
 	unsigned int flags;
 	unsigned int cpus;
 	int i, j;
@@ -400,41 +405,80 @@  static void dump_option_timeshift(int fd, int size)
 	}
 	do_print(OPTIONS, "\t\t[Option TimeShift, %d bytes]\n", size);
 	read_file_number(fd, &trace_id, 8);
+	size -= 8;
 	do_print(OPTIONS, "0x%llX [peer's trace id]\n", trace_id);
 	read_file_number(fd, &flags, 4);
+	size -= 4;
 	do_print(OPTIONS, "0x%llX [peer's protocol flags]\n", flags);
 	read_file_number(fd, &cpus, 4);
+	size -= 4;
 	do_print(OPTIONS, "0x%llX [peer's CPU count]\n", cpus);
+	cpus_data = calloc(cpus, sizeof(struct time_shift_cpu));
+	if (!cpus_data)
+		return;
 	for (j = 0; j < cpus; j++) {
-		read_file_number(fd, &count, 4);
-		do_print(OPTIONS, "%lld [samples count for CPU %d]\n", count, j);
-		times = calloc(count, sizeof(long long));
-		offsets = calloc(count, sizeof(long long));
-		scalings = calloc(count, sizeof(long long));
-		if (!times || !offsets || !scalings)
+		if (size < 4)
 			goto out;
-		for (i = 0; i < count; i++)
-			read_file_number(fd, times + i, 8);
-		for (i = 0; i < count; i++)
-			read_file_number(fd, offsets + i, 8);
-		for (i = 0; i < count; i++)
-			read_file_number(fd, scalings + i, 8);
-
-		for (i = 0; i < count; i++)
-			do_print(OPTIONS, "\t%lld %lld %llu [offset * scaling @ time]\n",
-				 offsets[i], scalings[1], times[i]);
-		free(times);
-		free(offsets);
-		free(scalings);
-		times = NULL;
-		offsets = NULL;
-		scalings = NULL;
+		read_file_number(fd, &cpus_data[j].count, 4);
+		size -= 4;
+		do_print(OPTIONS, "%lld [samples count for CPU %d]\n", cpus_data[j].count, j);
+		cpus_data[j].times = calloc(cpus_data[j].count, sizeof(long long));
+		cpus_data[j].offsets = calloc(cpus_data[j].count, sizeof(long long));
+		cpus_data[j].scalings = calloc(cpus_data[j].count, sizeof(long long));
+		cpus_data[j].frac = calloc(cpus_data[j].count, sizeof(long long));
+		if (!cpus_data[j].times || !cpus_data[j].offsets ||
+		    !cpus_data[j].scalings || !cpus_data[j].frac)
+			goto out;
+		for (i = 0; i < cpus_data[j].count; i++) {
+			if (size < 8)
+				goto out;
+			read_file_number(fd, cpus_data[j].times + i, 8);
+			size -= 8;
+		}
+		for (i = 0; i < cpus_data[j].count; i++) {
+			if (size < 8)
+				goto out;
+			read_file_number(fd, cpus_data[j].offsets + i, 8);
+			size -= 8;
+		}
+		for (i = 0; i < cpus_data[j].count; i++) {
+			if (size < 8)
+				goto out;
+			read_file_number(fd, cpus_data[j].scalings + i, 8);
+			size -= 8;
+		}
+	}
 
+	if (size > 0) {
+		for (j = 0; j < cpus; j++) {
+			if (!cpus_data[j].frac)
+				goto out;
+			for (i = 0; i < cpus_data[j].count; i++) {
+				if (size < 8)
+					goto out;
+				read_file_number(fd, cpus_data[j].frac + i, 8);
+				size -= 8;
+			}
+		}
 	}
+
+	for (j = 0; j < cpus; j++) {
+		for (i = 0; i < cpus_data[j].count; i++)
+			do_print(OPTIONS, "\t%lld %lld %llu %llu[offset * scaling >> fraction @ time]\n",
+				 cpus_data[j].offsets[i], cpus_data[j].scalings[i],
+				 cpus_data[j].frac[i], cpus_data[j].times[i]);
+
+	}
+
 out:
-	free(times);
-	free(offsets);
-	free(scalings);
+	if (j < cpus)
+		do_print(OPTIONS, "Broken time shift option\n");
+	for (j = 0; j < cpus; j++) {
+		free(cpus_data[j].times);
+		free(cpus_data[j].offsets);
+		free(cpus_data[j].scalings);
+	}
+	free(cpus_data);
 }
 
 void dump_option_guest(int fd, int size)