Commit f8c4c3dc authored by Joanne Hugé's avatar Joanne Hugé

Merge test-ptp program into packet-exchange

parent 2fb08a6d
...@@ -44,10 +44,11 @@ typedef struct thread_param { ...@@ -44,10 +44,11 @@ typedef struct thread_param {
unsigned int max_cycles; unsigned int max_cycles;
int priority; int priority;
int etf_offset; int etf_offset;
uint64_t send_tx_delay; int64_t send_ts_delay;
int affinity_cpu; int affinity_cpu;
uint64_t start_ts; uint64_t start_ts;
int enable_send_ts;
int enable_etf_tracing; int enable_etf_tracing;
int enable_threshold_tracing; int enable_threshold_tracing;
int threshold; int threshold;
...@@ -153,15 +154,15 @@ static void *packet_sending_thread(void *p) { ...@@ -153,15 +154,15 @@ static void *packet_sending_thread(void *p) {
add_ns(&next, thread_params.interval); add_ns(&next, thread_params.interval);
// Set txtime and TX data timestamp if required // Set txtime and TX data timestamp if required
if (enable_etf || thread_params.send_tx_delay) { if (enable_etf || thread_params.enable_send_ts) {
if (enable_etf) { if (enable_etf) {
next_txtime = next.tv_sec * NSEC_PER_SEC + next.tv_nsec; next_txtime = next.tv_sec * NSEC_PER_SEC + next.tv_nsec;
next_txtime += thread_params.etf_offset; next_txtime += thread_params.etf_offset;
} }
if (thread_params.send_tx_delay) { if (thread_params.enable_send_ts) {
tx_data = next.tv_sec * NSEC_PER_SEC + next.tv_nsec; tx_data = next.tv_sec * NSEC_PER_SEC + next.tv_nsec;
tx_data += thread_params.send_tx_delay; tx_data += thread_params.send_ts_delay;
} }
} }
...@@ -172,6 +173,7 @@ static void *packet_sending_thread(void *p) { ...@@ -172,6 +173,7 @@ static void *packet_sending_thread(void *p) {
break; break;
clock_gettime(CLOCK_REALTIME, &current); clock_gettime(CLOCK_REALTIME, &current);
// Sanity check // Sanity check
if(current.tv_sec > next.tv_sec) if(current.tv_sec > next.tv_sec)
goto invalid_ts; goto invalid_ts;
...@@ -185,7 +187,7 @@ static void *packet_sending_thread(void *p) { ...@@ -185,7 +187,7 @@ static void *packet_sending_thread(void *p) {
} }
// TX data // TX data
encode(thread_params.send_tx_delay ? tx_data : 0xdeadbeef, send_data); encode(thread_params.enable_send_ts ? tx_data : 0xdeadbeef, send_data);
// Get timestamp before TSN task for stats // Get timestamp before TSN task for stats
clock_gettime(CLOCK_REALTIME, &current); clock_gettime(CLOCK_REALTIME, &current);
...@@ -194,9 +196,9 @@ static void *packet_sending_thread(void *p) { ...@@ -194,9 +196,9 @@ static void *packet_sending_thread(void *p) {
// Update txtime and TX data timestamp if required // Update txtime and TX data timestamp if required
if (enable_etf) next_txtime += thread_params.interval; if (enable_etf) next_txtime += thread_params.interval;
if (thread_params.send_tx_delay) { if (thread_params.enable_send_ts) {
tx_data = next.tv_sec * NSEC_PER_SEC + next.tv_nsec; tx_data = next.tv_sec * NSEC_PER_SEC + next.tv_nsec;
tx_data += thread_params.send_tx_delay; tx_data += thread_params.send_ts_delay;
} }
// Update statistics // Update statistics
...@@ -247,11 +249,12 @@ int main(int argc, char *argv[]) { ...@@ -247,11 +249,12 @@ int main(int argc, char *argv[]) {
thread_params.interval = 100000 * 1000; thread_params.interval = 100000 * 1000;
thread_params.max_cycles = 0; thread_params.max_cycles = 0;
thread_params.priority = 98; thread_params.priority = 98;
thread_params.send_tx_delay = 0; thread_params.send_ts_delay = 0;
thread_params.affinity_cpu = -1; thread_params.affinity_cpu = -1;
thread_params.start_ts = 0; thread_params.start_ts = 0;
thread_params.enable_etf_tracing = 0; thread_params.enable_etf_tracing = 0;
thread_params.enable_threshold_tracing = 0; thread_params.enable_threshold_tracing = 0;
thread_params.enable_send_ts = 0;
main_params.refresh_rate = 50000; main_params.refresh_rate = 50000;
main_params.verbose = 0; main_params.verbose = 0;
main_params.enable_tracing = 0; main_params.enable_tracing = 0;
...@@ -466,7 +469,8 @@ static void process_options(int argc, char *argv[]) { ...@@ -466,7 +469,8 @@ static void process_options(int argc, char *argv[]) {
tsn_task = RTT_TASK; tsn_task = RTT_TASK;
break; break;
case 'c': case 'c':
thread_params.send_tx_delay = strtoull(optarg, NULL, 10) * 1000; thread_params.send_ts_delay = strtoll(optarg, NULL, 10) * 1000;
thread_params.enable_send_ts = 1;
break; break;
case 'd': case 'd':
egress_params.tx_buffer_len = atoi(optarg); egress_params.tx_buffer_len = atoi(optarg);
......
...@@ -41,6 +41,7 @@ typedef struct thread_param { ...@@ -41,6 +41,7 @@ typedef struct thread_param {
uint64_t latency_threshold; uint64_t latency_threshold;
int emit_signal; int emit_signal;
int enable_diff_ts;
} thread_param_t; } thread_param_t;
...@@ -75,6 +76,10 @@ static struct timespec emit_signal_next; ...@@ -75,6 +76,10 @@ static struct timespec emit_signal_next;
static pthread_mutex_t emit_signal_mutex; static pthread_mutex_t emit_signal_mutex;
static pthread_cond_t emit_signal_ts_received; static pthread_cond_t emit_signal_ts_received;
static int64_t min_diff_ts = INT_MAX;
static int64_t max_diff_ts = 0;
static int64_t avg_diff_ts = 0;
static void help(char *argv[]) { static void help(char *argv[]) {
printf( printf(
"Usage: %s [-f IF -a CPU -p PRIO -i USEC -r USEC] [-b CLIENT_IP] [-d " "Usage: %s [-f IF -a CPU -p PRIO -i USEC -r USEC] [-b CLIENT_IP] [-d "
...@@ -87,6 +92,7 @@ static void help(char *argv[]) { ...@@ -87,6 +92,7 @@ static void help(char *argv[]) {
" -r USEC non-RT main thread refresh interval\n" " -r USEC non-RT main thread refresh interval\n"
" -d BUF_LEN Set the length of tx buffer\n" " -d BUF_LEN Set the length of tx buffer\n"
" -c Receive timestamp and emit signal\n" " -c Receive timestamp and emit signal\n"
" -C Receive timestamp and print difference with current time\n"
" -b CLIENT_IP Server side RTT\n" " -b CLIENT_IP Server side RTT\n"
" -g Print histograms to sdtout on exit\n" " -g Print histograms to sdtout on exit\n"
" -t Enable timestamps\n" " -t Enable timestamps\n"
...@@ -182,6 +188,15 @@ static void *tsn_thread(void *p) { ...@@ -182,6 +188,15 @@ static void *tsn_thread(void *p) {
clock_gettime(CLOCK_REALTIME, &current); clock_gettime(CLOCK_REALTIME, &current);
recv_xdp_cleanup(); recv_xdp_cleanup();
if(thread_params.enable_diff_ts) {
uint64_t send_ts = decode(ingress_stats.data);
int64_t diff_us = (((int64_t) ts_to_uint(current)) - ((int64_t)send_ts)) / 1000;
min_diff_ts = _min_(diff_us, min_diff_ts);
max_diff_ts = _max_(diff_us, max_diff_ts);
avg_diff_ts = (avg_diff_ts * ingress_stats.packets_received + diff_us) / (ingress_stats.packets_received + 1);
}
// Emit signal // Emit signal
if (thread_params.emit_signal) { if (thread_params.emit_signal) {
uint64_t emit_signal_t = decode(ingress_stats.data); uint64_t emit_signal_t = decode(ingress_stats.data);
...@@ -305,6 +320,7 @@ int main(int argc, char *argv[]) { ...@@ -305,6 +320,7 @@ int main(int argc, char *argv[]) {
thread_params.priority = 98; thread_params.priority = 98;
thread_params.emit_signal = 0; thread_params.emit_signal = 0;
thread_params.affinity_cpu = 0; thread_params.affinity_cpu = 0;
thread_params.enable_diff_ts = 0;
main_params.refresh_rate = 50000; main_params.refresh_rate = 50000;
main_params.verbose = 0; main_params.verbose = 0;
main_params.enable_tracing = 0; main_params.enable_tracing = 0;
...@@ -363,10 +379,18 @@ int main(int argc, char *argv[]) { ...@@ -363,10 +379,18 @@ int main(int argc, char *argv[]) {
(tsn_task == RECV_PACKET_TASK || tsn_task == XDP_TASK)) { (tsn_task == RECV_PACKET_TASK || tsn_task == XDP_TASK)) {
int jitter = ingress_stats.max_interval - ingress_stats.min_interval; int jitter = ingress_stats.max_interval - ingress_stats.min_interval;
if (thread_params.enable_diff_ts) {
printf("%9" PRIu64 ": D : %8" PRIi64 " %8" PRIi64 " %17" PRIi64,
ingress_stats.packets_received,
min_diff_ts,
avg_diff_ts,
max_diff_ts);
} else {
printf("%9" PRIu64 ": J: %5d, I (10us): %3d %3d %3d [%3d]", printf("%9" PRIu64 ": J: %5d, I (10us): %3d %3d %3d [%3d]",
ingress_stats.packets_received, jitter, ingress_stats.packets_received, jitter,
ingress_stats.min_interval / 10, ingress_stats.avg_interval / 10, ingress_stats.min_interval / 10, ingress_stats.avg_interval / 10,
ingress_stats.max_interval / 10, (int)ingress_stats.high_jitter); ingress_stats.max_interval / 10, (int)ingress_stats.high_jitter);
}
if (enable_timestamps) if (enable_timestamps)
printf(", K: %4d %4d %4d [%3d]\n", ingress_stats.min_kernel_latency, printf(", K: %4d %4d %4d [%3d]\n", ingress_stats.min_kernel_latency,
...@@ -453,7 +477,7 @@ static void process_options(int argc, char *argv[]) { ...@@ -453,7 +477,7 @@ static void process_options(int argc, char *argv[]) {
int network_if_specified = 0; int network_if_specified = 0;
for (;;) { for (;;) {
int c = getopt(argc, argv, "a:b:cd:f:ghi:p:r:tvx:XT:G"); int c = getopt(argc, argv, "a:b:cCd:f:ghi:p:r:tvx:XT:G");
if (c == -1) break; if (c == -1) break;
...@@ -468,6 +492,9 @@ static void process_options(int argc, char *argv[]) { ...@@ -468,6 +492,9 @@ static void process_options(int argc, char *argv[]) {
case 'c': case 'c':
thread_params.emit_signal = 1; thread_params.emit_signal = 1;
break; break;
case 'C':
thread_params.enable_diff_ts = 1;
break;
case 'd': case 'd':
ingress_params.tx_buffer_len = atoi(optarg); ingress_params.tx_buffer_len = atoi(optarg);
if (ingress_params.tx_buffer_len < 1) { if (ingress_params.tx_buffer_len < 1) {
......
...@@ -15,6 +15,7 @@ Usage: $0 [-h] [-I if] [SERVER] | TCPDUMP [TRACE_OPTS] ...@@ -15,6 +15,7 @@ Usage: $0 [-h] [-I if] [SERVER] | TCPDUMP [TRACE_OPTS]
-b Send back packets for round trip measurements -b Send back packets for round trip measurements
-c Emit a signal on GPIO at the timestamp given in packet -c Emit a signal on GPIO at the timestamp given in packet
(to be used with -c option in client program) (to be used with -c option in client program)
-C Measure difference between current time and timestamp sent in tx data
-t Use SO_TIMESTAMPS to see how much time packet spent in kernel -t Use SO_TIMESTAMPS to see how much time packet spent in kernel
-x POLL Use XDP sockets, with a global libbpf installation -x POLL Use XDP sockets, with a global libbpf installation
-X POLL Use XDP sockets, with libbpf located in \$HOME/libbpf folder -X POLL Use XDP sockets, with libbpf located in \$HOME/libbpf folder
...@@ -52,7 +53,7 @@ tracecmd_events="-e irq -e sched -e net -e napi" ...@@ -52,7 +53,7 @@ tracecmd_events="-e irq -e sched -e net -e napi"
tracecmd_opts="" tracecmd_opts=""
cpu=1 cpu=1
while getopts "a:b:chtx:X:d:i:g:I:T:E:P:B:" opt; do while getopts "a:b:cChtx:X:d:i:g:I:T:E:P:B:" opt; do
case "${opt}" in case "${opt}" in
a ) a )
cpu=${OPTARG} cpu=${OPTARG}
...@@ -64,6 +65,9 @@ while getopts "a:b:chtx:X:d:i:g:I:T:E:P:B:" opt; do ...@@ -64,6 +65,9 @@ while getopts "a:b:chtx:X:d:i:g:I:T:E:P:B:" opt; do
c ) c )
server_options+=" -c" server_options+=" -c"
;; ;;
C )
server_options+=" -C"
;;
d ) d )
use_tcpdump=1 use_tcpdump=1
nb_packets=${OPTARG} nb_packets=${OPTARG}
......
...@@ -32,7 +32,7 @@ typedef struct egress_stat { ...@@ -32,7 +32,7 @@ typedef struct egress_stat {
void init_udp_send(egress_param_t *_params, void init_udp_send(egress_param_t *_params,
egress_stat_t *_stats, egress_stat_t *_stats,
int _use_histogram, int _stop_tracing, int log_timestamps, int _use_histogram, int _stop_tracing, int _send_ts, int log_timestamps,
uint64_t *_kernel_latency_hist); uint64_t *_kernel_latency_hist);
void send_udp_packet(char *data, uint64_t txtime); void send_udp_packet(char *data, uint64_t txtime);
......
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