Commit 85bef512 authored by Joanne Hugé's avatar Joanne Hugé

Fix histogram printing bugs, add new scripts

Print lost packets in the server histogram
Remove trailing comma in client histogram printing
Prevent user to enable histgrams without enabling timestamps in client wrapper script
Rename scripts by replacing underscores with a dash

Add packet-histogram-start and packet-histogram-stop scripts,
which automates the generation of histograms by ssh'ing on the
boards using expect script
parent f6022349
......@@ -28,7 +28,6 @@
enum TSNTask { SEND_PACKET_TASK, RTT_TASK };
typedef struct rtt_stat {
int min_rtt;
int avg_rtt;
int max_rtt;
......@@ -85,19 +84,33 @@ static struct timespec measures_end;
static char send_data[MAX_BUFFER_SIZE];
static void help(char *argv[]) {
printf("Usage: %s -f IF [-abthgv] [-e ETF_OFFSET] [-d BUF_LEN] [-i USEC] [-l N] [-p PRIO] [-q PACKET_PRIO] [-r USEC]\n\n", argv[0]);
printf(
"Usage: %s -f IF [-abthgv] [-e ETF_OFFSET] [-d BUF_LEN] [-i USEC] [-l "
"N] [-p PRIO] [-q PACKET_PRIO] [-r USEC]\n\n",
argv[0]);
printf(" -a Run the real time thread on CPU1\n");
printf(" -b Measure RTT\n");
printf(" -d BUF_LEN Set the length of tx buffer\n");
printf(" -e ETF_OFFSET Set a txtime with an offset of ETF_OFFSET us (to be used in an ETF qdisc)\n");
printf(
" -e ETF_OFFSET Set a txtime with an offset of ETF_OFFSET "
"us (to be used in an ETF qdisc)\n");
printf(" -f IF Set the network interface to be used\n");
printf(" -g Print histograms to sdtout on exit\n");
printf(" -h Show help\n");
printf(" -i USEC Wake up the real time thread every USEC microseconds (Default: 10ms)\n");
printf(" -l N Wake up the real time thread N times (Default: 0)\n");
printf(" -p PRIO Run the real time thread at priority PRIO\n");
printf(" -q PACKET_PRIO Send packets with PACKET_PRIO priority\n");
printf(" -r USEC Refresh the non real time main thread every USEC microseconds (Default: 50ms)\n");
printf(
" -i USEC Wake up the real time thread every USEC "
"microseconds (Default: 10ms)\n");
printf(
" -l N Wake up the real time thread N times "
"(Default: 0)\n");
printf(
" -p PRIO Run the real time thread at priority "
"PRIO\n");
printf(
" -q PACKET_PRIO Send packets with PACKET_PRIO priority\n");
printf(
" -r USEC Refresh the non real time main thread "
"every USEC microseconds (Default: 50ms)\n");
printf(" -t Enable timestamps\n");
printf(" -v Verbose\n");
printf("\n");
......@@ -149,8 +162,7 @@ static void *packet_sending_thread(void *p) {
add_ns(&next, thread_params.interval);
if (enable_etf)
next_txtime += thread_params.interval;
if (enable_etf) next_txtime += thread_params.interval;
clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &next, NULL);
}
......@@ -198,16 +210,12 @@ int main(int argc, char *argv[]) {
init_signals(sighand, enable_histograms);
// Initialize the UDP packet sending socket
init_udp_send(&egress_params,
&egress_stats,
enable_histograms,
init_udp_send(&egress_params, &egress_stats, enable_histograms,
kernel_latency_hist);
// Initialize the UDP packet receiving socket if RTT is measured
if (tsn_task == RTT_TASK)
init_udp_recv(&ingress_params,
&ingress_stats,
enable_histograms,
init_udp_recv(&ingress_params, &ingress_stats, enable_histograms,
kernel_latency_hist);
// Create the real time thread
......@@ -220,26 +228,20 @@ int main(int argc, char *argv[]) {
if (main_params.verbose) {
if (tsn_task == RTT_TASK) {
printf("%9" PRIu64 ": RTT: %4d %4d %4d\n", nb_cycles, rtt_stats.min_rtt,
rtt_stats.avg_rtt,
rtt_stats.max_rtt);
rtt_stats.avg_rtt, rtt_stats.max_rtt);
printf("\033[%dA", 1);
} else {
printf("%9" PRIu64 ": [%4d, %4d]",
nb_cycles,
(int) egress_stats.invalid_parameter,
(int) egress_stats.missed_deadline);
printf("%9" PRIu64 ": [%4d, %4d]", nb_cycles,
(int)egress_stats.invalid_parameter,
(int)egress_stats.missed_deadline);
if (enable_timestamps) {
printf(", K: %4d %4d %4d [%4d]\n",
egress_stats.min_kernel_latency,
printf(", K: %4d %4d %4d [%4d]\n", egress_stats.min_kernel_latency,
egress_stats.avg_kernel_latency,
egress_stats.max_kernel_latency,
(int) egress_stats.high_kernel_latency);
}
else {
(int)egress_stats.high_kernel_latency);
} else {
printf("\n");
}
printf("\033[%dA", 1);
......@@ -247,12 +249,10 @@ int main(int argc, char *argv[]) {
}
if (thread_params.max_cycles)
if (thread_params.max_cycles == nb_cycles)
break;
if (thread_params.max_cycles == nb_cycles) break;
}
if (enable_histograms)
print_histograms();
if (enable_histograms) print_histograms();
exit(EXIT_SUCCESS);
}
......@@ -264,12 +264,10 @@ static void do_tsn_task(char *data, uint64_t next_txtime) {
// One way packet sending
if (tsn_task == SEND_PACKET_TASK) {
send_udp_packet(data, next_txtime);
// Round Trip Time measurement
} else if (tsn_task == RTT_TASK) {
clock_gettime(CLOCK_MONOTONIC, &t1);
send_udp_packet(data, next_txtime);
recv_udp_packet(0, 0, NULL);
......@@ -279,10 +277,12 @@ static void do_tsn_task(char *data, uint64_t next_txtime) {
rtt_stats.min_rtt = min(rtt_us, rtt_stats.min_rtt);
rtt_stats.max_rtt = max(rtt_us, rtt_stats.max_rtt);
rtt_stats.avg_rtt = (((uint64_t)rtt_stats.avg_rtt) * (nb_cycles - 1) + rtt_us) / nb_cycles;
rtt_stats.avg_rtt =
(((uint64_t)rtt_stats.avg_rtt) * (nb_cycles - 1) + rtt_us) / nb_cycles;
if (rtt_us > MAX_RTT)
fprintf(stderr, "RTT value higher than MAX_RTT : %d ( > %d)\n", rtt_us, MAX_RTT);
fprintf(stderr, "RTT value higher than MAX_RTT : %d ( > %d)\n", rtt_us,
MAX_RTT);
else
rtt_hist[rtt_us]++;
}
......@@ -290,7 +290,6 @@ static void do_tsn_task(char *data, uint64_t next_txtime) {
// Print histograms in .json format
static void print_histograms() {
uint64_t duration;
int duration_hour, duration_minutes, interval;
int max_hist_val;
......@@ -304,29 +303,23 @@ static void print_histograms() {
interval = thread_params.interval / 1000;
if (tsn_task == SEND_PACKET_TASK) {
printf("{\"measure_sets\": [{"
"\"measure_type\": \"packet_send_timestamps\","
"\"props_names\": [\"kernel_space\"],"
"\"units\": [\"us\"],"
"\"props_type\": \"histogram\","
"\"metadata\": {\"i\": \"%dus\", \"duration\": \"%dh%d\", \"etf_offset\": \"%dus\",},"
"\"props\": [[",
interval, duration_hour, duration_minutes, thread_params.etf_offset);
printf(
"{\"measure_sets\": [{"
"\"measure_type\": \"%s\","
"\"props_names\": [\"%s\"],"
"\"units\": [\"us\"],"
"\"props_type\": \"histogram\","
"\"metadata\": {\"i\": \"%dus\", \"duration\": \"%dh%d\", "
"\"etf_offset\": \"%dus\"},"
"\"props\": [[",
(tsn_task == SEND_PACKET_TASK) ? "packet_send_timestamps" : "packet_rtt",
(tsn_task == SEND_PACKET_TASK) ? "kernel_space" : "rtt", interval,
duration_hour, duration_minutes, thread_params.etf_offset);
if (tsn_task == SEND_PACKET_TASK) {
histogram = kernel_latency_hist;
max_hist_val = histogram_max(histogram, MAX_KERNEL_LATENCY - 1);
} else {
printf("{\"measure_sets\": [{"
"\"measure_type\": \"packet_rtt\","
"\"props_names\": [\"rtt\"],"
"\"units\": [\"us\"],"
"\"props_type\": \"histogram\","
"\"metadata\": {\"i\": \"%dus\", \"duration\": \"%dh%d\", \"etf_offset\": \"%dus\",},"
"\"props\": [[",
interval, duration_hour, duration_minutes, thread_params.etf_offset);
histogram = rtt_hist;
max_hist_val = histogram_max(histogram, MAX_RTT - 1);
}
......@@ -344,65 +337,63 @@ static void sighand(int sig_num) {
// Process bash options
static void process_options(int argc, char *argv[]) {
int network_if_specified = 0;
for (;;) {
int c = getopt(argc, argv, "abd:e:f:ghi:l:p:q:r:tv");
if (c == -1)
break;
if (c == -1) break;
switch (c) {
case 'a':
enable_affinity = 1;
break;
case 'b':
tsn_task = RTT_TASK;
break;
case 'd':
egress_params.tx_buffer_len = atoi(optarg);
if (egress_params.tx_buffer_len < 1) {
fprintf(stderr, "BUF_LEN should be greater than 1\n");
exit(EXIT_FAILURE);
}
break;
case 'e':
enable_etf = 1;
thread_params.etf_offset = atoi(optarg) * 1000;
break;
case 'f':
network_if_specified = 1;
strcpy(egress_params.network_if, optarg);
break;
case 'g':
enable_histograms = 1;
break;
case 'h':
help(argv);
exit(EXIT_SUCCESS);
break;
case 'i':
thread_params.interval = atoi(optarg) * 1000;
break;
case 'l':
thread_params.max_cycles = atoi(optarg);
break;
case 'p':
thread_params.priority = atoi(optarg);
break;
case 'q':
egress_params.packet_priority = atoi(optarg);
break;
case 'r':
main_params.refresh_rate = atoi(optarg);
break;
case 't':
enable_timestamps = 1;
break;
case 'v':
main_params.verbose = 1;
break;
case 'a':
enable_affinity = 1;
break;
case 'b':
tsn_task = RTT_TASK;
break;
case 'd':
egress_params.tx_buffer_len = atoi(optarg);
if (egress_params.tx_buffer_len < 1) {
fprintf(stderr, "BUF_LEN should be greater than 1\n");
exit(EXIT_FAILURE);
}
break;
case 'e':
enable_etf = 1;
thread_params.etf_offset = atoi(optarg) * 1000;
break;
case 'f':
network_if_specified = 1;
strcpy(egress_params.network_if, optarg);
break;
case 'g':
enable_histograms = 1;
break;
case 'h':
help(argv);
exit(EXIT_SUCCESS);
break;
case 'i':
thread_params.interval = atoi(optarg) * 1000;
break;
case 'l':
thread_params.max_cycles = atoi(optarg);
break;
case 'p':
thread_params.priority = atoi(optarg);
break;
case 'q':
egress_params.packet_priority = atoi(optarg);
break;
case 'r':
main_params.refresh_rate = atoi(optarg);
break;
case 't':
enable_timestamps = 1;
break;
case 'v':
main_params.verbose = 1;
break;
}
}
......
......@@ -274,9 +274,10 @@ static void print_histograms() {
"\"props_names\": [\"kernel_space\"],"
"\"units\": [\"us\"],"
"\"props_type\": \"histogram\","
"\"metadata\": {\"i\": \"%dus\", \"duration\": \"%dh%d\"},"
"\"metadata\": {\"i\": \"%dus\", \"duration\": \"%dh%d\","
"\"lost_packets\": \"%d\"},"
"\"props\": [[",
interval, duration_hour, duration_minutes);
interval, duration_hour, duration_minutes, ingress_stats.lost_packets);
max_latency = histogram_max(kernel_latency_hist, MAX_KERNEL_LATENCY - 1);
......@@ -295,9 +296,11 @@ static void print_histograms() {
"\"units\": [\"us\"],"
"\"props_type\": \"histogram\","
"\"middle\": \"%d\","
"\"metadata\": {\"i\": \"%dus\", \"duration\": \"%dh%d\"},"
"\"metadata\": {\"i\": \"%dus\", \"duration\": \"%dh%d\","
"\"lost_packets\": \"%d\"},"
"\"props\": [[",
MAX_JITTER / 2 - min_jitter, interval, duration_hour, duration_minutes);
MAX_JITTER / 2 - min_jitter, interval, duration_hour, duration_minutes,
ingress_stats.lost_packets);
for (int j = min_jitter; j < max_jitter; j++)
printf("%" PRIi64 "%s", jitter_hist[j], (j + 1 < max_jitter ? ", " : ""));
......
#!/bin/bash
usage() {
echo "Usage: $0 OPTIONS -c OUTPUT CLIENT_BOARD SERVER_BOARD" 1>&2;
echo " $0 OPTIONS -s OUTPUT [-t] (-p | (-e DELTA -o ETF_OFFSET)) CLIENT_BOARD SERVER_BOARD" 1>&2;
echo " $0 OPTIONS -C OUTPUT [-l]" 1>&2;
echo "OPTIONS: [-h] [-i INTERVAL]" 1>&2;
exit 1;
}
script_dir=$(dirname $(realpath $0))
interval=1000
while getopts "hb:i:c:s:tjpe:o:C:l" opt; do
case "${opt}" in
h )
usage
;;
b )
board=${OPTARG}
;;
i )
interval=${OPTARG}
;;
c )
client_histogram=1
output=${OPTARG}
;;
s )
server_histogram=1
output=${OPTARG}
;;
t )
server_timestamps=1
;;
p )
server_pfifo=1
;;
e )
server_etf=1
etf_delta=${OPTARG}
;;
o )
etf_offset=${OPTARG}
;;
C )
cyclictest_histogram=1
output=${OPTARG}
;;
l )
stop_load=1
;;
* )
usage
;;
esac
done
shift $((OPTIND-1))
if [ -n "$client_histogram" ] || [ -n "$server_histogram" ]; then
if [ $# -ne 2 ]; then
echo "Wrong number of arguments";
usage
else
client_board=$1
server_board=$2
fi
elif [ -n "$cyclictest_histogram" ]; then
if [ $# -ne 1 ]; then
echo "Wrong number of arguments";
usage
else
board=$1
fi
else
echo "You need to choose between client, server or cyclictest histogram";
usage
fi
if [ -n "$client_histogram" ]; then
ssh -t $client_board "echo olimex | sudo -S killall client";
ssh -t $server_board "echo olimex | sudo -S killall server";
scp $client_board:$output $script_dir/;
cd $script_dir/../measure-analysis;
./measure-analysis.py -i $script_dir/$output;
./measure-analysis.py -R;
elif [ -n "$server_histogram" ]; then
ssh -t $server_board "echo olimex | sudo -S killall server";
ssh -t $client_board "echo olimex | sudo -S killall client";
scp $server_board:$output $script_dir/;
cd $script_dir/../measure-analysis;
./measure-analysis.py -i $script_dir/$output;
./measure-analysis.py -R;
elif [ -n "$cyclictest_histogram" ]; then
ssh -t $board "echo olimex | sudo -S killall cyclictest";
if [ -n "$stop_load" ]; then
ssh -t $board "echo olimex | sudo -S killall run-cyclictest";
ssh -t $board "echo olimex | sudo -S killall hackbench";
fi
scp $board:$output $script_dir/;
cd $script_dir/../measure-analysis;
./measure-analysis.py -i $script_dir/$output -c;
./measure-analysis.py -R;
fi
#!/bin/expect
spawn ssh [lindex $argv 0]
expect "oli@"
send -- "sudo echo\r"
expect "assword"
send -- "olimex\r"
expect "oli@"
send -- "sudo nohup [lindex $argv 1] > /dev/null > /dev/null &\r"
expect "stdout\r"
send -- \x03
expect "oli@"
#!/bin/bash
usage() {
echo "Usage: $0 OPTIONS -c CLIENT_BOARD SERVER_BOARD" 1>&2;
echo " $0 OPTIONS -s [-t] (-p | (-e DELTA -o ETF_OFFSET)) CLIENT_BOARD SERVER_BOARD" 1>&2;
echo " $0 OPTIONS -C [-l] BOARD" 1>&2;
echo "OPTIONS: [-h] [-i INTERVAL]" 1>&2;
exit 1;
}
script_dir=$(dirname $(realpath $0))
interval=1000
server_opts=""
cyclictest_opts=""
etf_offset=600
while getopts "hi:csCtpe:o:l" opt; do
case "${opt}" in
h )
usage
;;
i )
interval=${OPTARG}
;;
c )
client_histogram=1
;;
s )
server_histogram=1
;;
t )
server_opts+=" -t"
;;
p )
server_pfifo=1
;;
e )
server_etf=1
etf_delta=${OPTARG}
;;
o )
etf_offset=${OPTARG}
;;
C )
cyclictest_histogram=1
;;
l )
cyclictest_opts+=" -l"
;;
* )
usage
;;
esac
done
shift $((OPTIND-1))
if [ -n "$client_histogram" ] || [ -n "$server_histogram" ]; then
if [ $# -ne 2 ]; then
echo "Wrong number of arguments";
usage
else
client_board=$1
server_board=$2
fi
elif [ -n "$cyclictest_histogram" ]; then
if [ $# -ne 1 ]; then
echo "Wrong number of arguments";
usage
else
board=$1
fi
else
echo "You need to choose between client, server or cyclictest histogram";
usage
fi
# Client histogram
if [ -n "$client_histogram" ]; then
$script_dir/exec-ssh-nohup $server_board "run-server";
$script_dir/exec-ssh-nohup $client_board "run-client -p -i $interval -t -g $server_board";
echo "-c client_i${interval}_pfast -i $interval $client_board $server_board" > $script_dir/packet-histogram-stop_options;
# Server histogram
elif [ -n "$server_histogram" ]; then
# Server pfifo_fast qdisc histogram
if [ -n "$server_pfifo" ]; then
$script_dir/exec-ssh-nohup $server_board "run-server -g ${interval}$server_opts";
$script_dir/exec-ssh-nohup $client_board "run-client -p -i $interval $server_board";
echo "-i $interval -s server_i${interval} $server_opts -p $client_board $server_board" > $script_dir/packet-histogram-stop_options;
# Server ETF qdisc histogram
elif [ -n "$server_etf" ]; then
$script_dir/exec-ssh-nohup $server_board "run-server -g ${interval}$server_opts";
$script_dir/exec-ssh-nohup $client_board "run-client -e $etf_delta -o $etf_offset -i $interval $server_board";
echo "-i $interval -s server_i${interval} $server_opts -e $etf_delta -o $etf_offset $client_board $server_board" > $script_dir/packet-histogram-stop_options;
else
echo "Server histogram requires choosing between pfifo_fast or etf qdisc";
usage
fi
# cyclictest histogram
elif [ -n "$cyclictest_histogram" ]; then
$script_dir/exec-ssh-nohup $board "run-cyclictest -g $cyclictest_opts -i $interval";
echo "-i $interval -C cyclictest_hist $cyclictest_opts $board" > $script_dir/packet-histogram-stop_options;
fi
#!/bin/bash
script_dir=$(dirname $(realpath $0))
$script_dir/_packet-histogram-stop `cat packet-histogram-stop_options`;
rm packet-histogram-stop_options
......@@ -49,6 +49,7 @@ while getopts "bd:e:o:ghi:pt" opt; do
qdisc_options+="-p"
;;
t )
use_timestamps=1
client_options+=" -t"
;;
* )
......@@ -84,6 +85,9 @@ fi
if [ -z "${use_histogram}" ]; then
client_options+=" -v"
else
if [ -z "${use_timestamps}" ]; then
client_options+=" -t"
fi
output="client_i${interval}"
if [ -n "${use_pfast}" ]; then
output+="_pfast"
......
#!/bin/bash
usage() {
echo "Usage: $0 -hgl -i INTERVAL" 1>&2;
exit 1;
}
interval=1000
cyclictest_opts="-a1 -n -t1 -p99 -mlocakall"
while getopts "hgli:" opt; do
case "${opt}" in
h )
usage
;;
g )
generate_histogram=1
;;
l )
create_load=1
;;
i )
interval=${OPTARG}
;;
* )
usage
;;
esac
done
shift $((OPTIND-1))
cyclictest_opts+=" -i $interval"
if [ -n "$create_load" ]; then
while :
do
hackbench
done&
fi
if [ -n "$generate_histogram" ]; then
sudo cyclictest $cyclictest_opts -h 400 -q > cyclictest_hist
else
sudo cyclictest $cyclictest_opts
fi
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment