Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
T
tsn-measures
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
tsn-measures
Commits
6c2dd397
Commit
6c2dd397
authored
Oct 03, 2020
by
Joanne Hugé
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add option to send packets to two servers
parent
7a42d58b
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
202 additions
and
103 deletions
+202
-103
packet-exchange/src/client.c
packet-exchange/src/client.c
+43
-9
packet-exchange/src/send_packet.c
packet-exchange/src/send_packet.c
+57
-53
packet-exchange/src/send_packet.h
packet-exchange/src/send_packet.h
+48
-5
packet-exchange/src/server.c
packet-exchange/src/server.c
+24
-20
scripts/run-client
scripts/run-client
+30
-16
No files found.
packet-exchange/src/client.c
View file @
6c2dd397
...
@@ -81,16 +81,27 @@ static uint64_t rtt_hist[MAX_RTT];
...
@@ -81,16 +81,27 @@ static uint64_t rtt_hist[MAX_RTT];
static
uint64_t
nb_cycles
;
static
uint64_t
nb_cycles
;
static
main_param_t
main_params
;
static
main_param_t
main_params
;
static
thread_param_t
thread_params
;
static
thread_param_t
thread_params
;
static
egress_param_t
egress_params
;
static
ingress_param_t
ingress_params
;
static
ingress_param_t
ingress_params
;
static
rtt_stat_t
rtt_stats
=
{.
min_rtt
=
INT_MAX
};
static
rtt_stat_t
rtt_stats
=
{.
min_rtt
=
INT_MAX
};
static
egress_stat_t
egress_stats
=
{.
min_kernel_latency
=
INT_MAX
,
static
egress_param_t
egress_params
;
static
egress_param_t
egress_params2
;
static
egress_stat_t
egress_stats
=
{.
packets_sent
=
0
,
.
min_kernel_latency
=
INT_MAX
,
.
min_interval
=
INT_MAX
};
.
min_interval
=
INT_MAX
};
static
egress_stat_t
egress_stats2
=
{.
packets_sent
=
0
,
.
min_kernel_latency
=
INT_MAX
,
.
min_interval
=
INT_MAX
};
static
ingress_stat_t
ingress_stats
=
{.
min_kernel_latency
=
INT_MAX
,
static
ingress_stat_t
ingress_stats
=
{.
min_kernel_latency
=
INT_MAX
,
.
min_interval
=
INT_MAX
};
.
min_interval
=
INT_MAX
};
static
egress_info_t
egress_info
;
static
egress_info_t
egress_info2
;
static
int
enable_histograms
;
static
int
enable_histograms
;
static
int
enable_etf
;
static
int
enable_etf
;
static
int
enable_timestamps
;
static
int
enable_timestamps
;
static
int
two_servers
=
0
;
static
enum
TSNTask
tsn_task
;
static
enum
TSNTask
tsn_task
;
static
struct
timespec
measures_start
;
static
struct
timespec
measures_start
;
static
struct
timespec
measures_end
;
static
struct
timespec
measures_end
;
...
@@ -99,7 +110,7 @@ static char send_data[MAX_BUFFER_SIZE];
...
@@ -99,7 +110,7 @@ static char send_data[MAX_BUFFER_SIZE];
static
void
help
(
char
*
argv
[])
{
static
void
help
(
char
*
argv
[])
{
printf
(
printf
(
"Usage: %s [-a CPU -p PRIO -i USEC -r USEC -l N] [-d BUF_LEN | -c "
"Usage: %s [-a CPU -p PRIO -i USEC -r USEC -l N] [-d BUF_LEN | -c "
"DELAY -s NS] [-b -e OFFSET -q PK_PRIO -gtvT] IF IP
\n\n
"
"DELAY -s NS] [-b -e OFFSET -q PK_PRIO -gtvT] IF IP
IF2 IP2
\n\n
"
" -h Show help
\n
"
" -h Show help
\n
"
" -f IF Set the network interface to be used
\n
"
" -f IF Set the network interface to be used
\n
"
" -a CPU Pin the real time thread to CPU
\n
"
" -a CPU Pin the real time thread to CPU
\n
"
...
@@ -173,10 +184,12 @@ static void *packet_sending_thread(void *p) {
...
@@ -173,10 +184,12 @@ static void *packet_sending_thread(void *p) {
if
(
thread_params
.
start_ts
)
{
if
(
thread_params
.
start_ts
)
{
if
(
thread_params
.
start_ts
<
ts_to_uint
(
next
))
{
if
(
thread_params
.
start_ts
<
ts_to_uint
(
next
))
{
fprintf
(
stderr
,
"start timestamp is in the past, aborting...
\n
"
);
fprintf
(
stderr
,
"start timestamp is in the past, aborting...
\n
"
);
fflush
(
stdout
);
exit
(
EXIT_FAILURE
);
exit
(
EXIT_FAILURE
);
}
}
if
(
thread_params
.
start_ts
>
(
ts_to_uint
(
next
)
+
UINT64_C
(
3600000000000
)))
{
if
(
thread_params
.
start_ts
>
(
ts_to_uint
(
next
)
+
UINT64_C
(
3600000000000
)))
{
fprintf
(
stderr
,
"start timestamp is too high, aborting...
\n
"
);
fprintf
(
stderr
,
"start timestamp is too high, aborting...
\n
"
);
fflush
(
stdout
);
exit
(
EXIT_FAILURE
);
exit
(
EXIT_FAILURE
);
}
}
next
=
uint_to_ts
(
thread_params
.
start_ts
);
next
=
uint_to_ts
(
thread_params
.
start_ts
);
...
@@ -353,6 +366,8 @@ int main(int argc, char *argv[]) {
...
@@ -353,6 +366,8 @@ int main(int argc, char *argv[]) {
main_params
.
interval_input
=
0
;
main_params
.
interval_input
=
0
;
egress_params
.
packet_priority
=
3
;
egress_params
.
packet_priority
=
3
;
egress_params
.
tx_buffer_len
=
1024
;
egress_params
.
tx_buffer_len
=
1024
;
egress_params2
.
packet_priority
=
3
;
egress_params2
.
tx_buffer_len
=
1024
;
enable_etf
=
0
;
enable_etf
=
0
;
enable_timestamps
=
0
;
enable_timestamps
=
0
;
enable_histograms
=
0
;
enable_histograms
=
0
;
...
@@ -368,10 +383,20 @@ int main(int argc, char *argv[]) {
...
@@ -368,10 +383,20 @@ int main(int argc, char *argv[]) {
// Process bash options
// Process bash options
process_options
(
argc
,
argv
);
process_options
(
argc
,
argv
);
main_params
.
target_interval
=
thread_params
.
interval
/
1000
;
set_latency_target
();
set_latency_target
();
egress_params
.
use_etf
=
enable_etf
;
egress_params
.
use_etf
=
enable_etf
;
egress_params
.
use_timestamps
=
enable_timestamps
;
egress_params
.
use_timestamps
=
enable_timestamps
;
egress_params2
.
use_etf
=
enable_etf
;
egress_params2
.
use_timestamps
=
enable_timestamps
;
egress_info
.
params
=
&
egress_params
;
egress_info
.
stats
=
&
egress_stats
;
egress_info
.
stats
->
kernel_latency_hist
=
kernel_latency_hist
;
egress_info2
.
params
=
&
egress_params2
;
egress_info2
.
stats
=
&
egress_stats2
;
if
(
enable_histograms
)
{
if
(
enable_histograms
)
{
// Init histograms
// Init histograms
...
@@ -388,8 +413,9 @@ int main(int argc, char *argv[]) {
...
@@ -388,8 +413,9 @@ int main(int argc, char *argv[]) {
init_signals
(
sighand
);
init_signals
(
sighand
);
// Initialize the UDP packet sending socket
// Initialize the UDP packet sending socket
init_udp_send
(
&
egress_params
,
&
egress_stats
,
enable_histograms
,
init_udp_send
(
&
egress_info
,
enable_histograms
,
thread_params
.
enable_etf_tracing
);
thread_params
.
enable_etf_tracing
,
kernel_latency_hist
);
if
(
two_servers
)
init_udp_send
(
&
egress_info2
,
enable_histograms
,
thread_params
.
enable_etf_tracing
);
// Initialize the UDP packet receiving socket if RTT is measured
// Initialize the UDP packet receiving socket if RTT is measured
if
(
tsn_task
==
RTT_TASK
)
if
(
tsn_task
==
RTT_TASK
)
...
@@ -489,12 +515,14 @@ static void do_tsn_task(char *data, uint64_t next_txtime) {
...
@@ -489,12 +515,14 @@ static void do_tsn_task(char *data, uint64_t next_txtime) {
// One way packet sending
// One way packet sending
if
(
tsn_task
==
SEND_PACKET_TASK
)
{
if
(
tsn_task
==
SEND_PACKET_TASK
)
{
send_udp_packet
(
data
,
next_txtime
);
send_udp_packet
(
data
,
next_txtime
,
&
egress_info
);
if
(
two_servers
)
send_udp_packet
(
data
,
next_txtime
,
&
egress_info2
);
// Round Trip Time measurement
// Round Trip Time measurement
}
else
if
(
tsn_task
==
RTT_TASK
)
{
}
else
if
(
tsn_task
==
RTT_TASK
)
{
clock_gettime
(
CLOCK_MONOTONIC
,
&
t1
);
clock_gettime
(
CLOCK_MONOTONIC
,
&
t1
);
send_udp_packet
(
data
,
next_txtime
);
send_udp_packet
(
data
,
next_txtime
,
&
egress_info
);
recv_udp_packet
();
recv_udp_packet
();
clock_gettime
(
CLOCK_MONOTONIC
,
&
t2
);
clock_gettime
(
CLOCK_MONOTONIC
,
&
t2
);
...
@@ -634,15 +662,21 @@ static void process_options(int argc, char *argv[]) {
...
@@ -634,15 +662,21 @@ static void process_options(int argc, char *argv[]) {
}
}
}
}
if
(
argc
!=
optind
+
2
)
{
if
(
argc
!=
optind
+
2
&&
argc
!=
optind
+
4
)
{
if
(
argc
<
optind
+
2
)
if
(
argc
<
optind
+
2
)
fprintf
(
stderr
,
"You need to specifiy an interface and IP address
\n
"
);
fprintf
(
stderr
,
"You need to specifiy an interface and IP address
\n
"
);
else
else
fprintf
(
stderr
,
"
Too many arguments
\n
"
);
fprintf
(
stderr
,
"
Wrong number of arguments
"
);
help
(
argv
);
help
(
argv
);
exit
(
EXIT_FAILURE
);
exit
(
EXIT_FAILURE
);
}
}
strcpy
(
egress_params
.
network_if
,
argv
[
optind
]);
strcpy
(
egress_params
.
network_if
,
argv
[
optind
]);
strcpy
(
egress_params
.
server_ip
,
argv
[
optind
+
1
]);
strcpy
(
egress_params
.
server_ip
,
argv
[
optind
+
1
]);
if
(
argc
==
optind
+
4
)
{
two_servers
=
1
;
strcpy
(
egress_params2
.
network_if
,
argv
[
optind
+
2
]);
strcpy
(
egress_params2
.
server_ip
,
argv
[
optind
+
3
]);
}
}
}
packet-exchange/src/send_packet.c
View file @
6c2dd397
...
@@ -40,76 +40,67 @@
...
@@ -40,76 +40,67 @@
#include "tracer.h"
#include "tracer.h"
static
void
*
poll_thread
(
void
*
p
);
static
void
*
poll_thread
(
void
*
p
);
static
void
process_error_queue
();
static
void
process_error_queue
(
egress_info_t
*
info
);
static
void
init_tx_buffer
();
static
void
init_tx_buffer
(
egress_info_t
*
info
);
static
int
set_if
();
static
int
set_if
(
egress_info_t
*
info
);
static
int
so_timestamping_flags
=
static
int
so_timestamping_flags
=
SOF_TIMESTAMPING_TX_SOFTWARE
|
SOF_TIMESTAMPING_SOFTWARE
;
SOF_TIMESTAMPING_TX_SOFTWARE
|
SOF_TIMESTAMPING_SOFTWARE
;
static
egress_param_t
*
params
;
static
egress_stat_t
*
stats
;
static
uint64_t
*
kernel_latency_hist
;
static
int
use_histogram
;
static
int
use_histogram
;
static
int
stop_tracing
;
static
int
stop_tracing
;
static
uint64_t
packets_sent
=
0
;
static
struct
sock_txtime
sk_txtime
;
static
char
*
tx_buffer
;
static
int
sock_fd
;
static
int64_t
timestamps_buffer
[
TIMESTAMP_BUFFER_SIZE
];
static
int
ts_buf_read_index
=
0
;
static
int
ts_buf_write_index
=
0
;
/*
/*
* Init UDP socket
* Init UDP socket
*/
*/
void
init_udp_send
(
egress_param_t
*
_params
,
egress_stat_t
*
_stats
,
void
init_udp_send
(
egress_info_t
*
info
,
int
_use_histogram
,
int
_stop_tracing
)
{
int
_use_histogram
,
int
_stop_tracing
,
uint64_t
*
_kernel_latency_hist
)
{
int
set_if_err
;
int
set_if_err
;
pthread_t
thread
;
pthread_t
thread
;
params
=
_params
;
egress_param_t
*
params
=
info
->
params
;
stats
=
_stats
;
egress_stat_t
*
stats
=
info
->
stats
;
kernel_latency_hist
=
_kernel_latency_hist
;
stats
->
packets_sent
=
0
;
stats
->
ts_buf_read_index
=
0
;
stats
->
ts_buf_write_index
=
0
;
use_histogram
=
_use_histogram
;
use_histogram
=
_use_histogram
;
stop_tracing
=
_stop_tracing
;
stop_tracing
=
_stop_tracing
;
init_tx_buffer
();
init_tx_buffer
(
info
);
sock_fd
=
socket
(
PF_INET
,
SOCK_DGRAM
,
IPPROTO_UDP
);
info
->
sock_fd
=
socket
(
PF_INET
,
SOCK_DGRAM
,
IPPROTO_UDP
);
if
(
sock_fd
<
0
)
error
(
EXIT_FAILURE
,
errno
,
"Socket creation failed
\n
"
);
if
(
info
->
sock_fd
<
0
)
error
(
EXIT_FAILURE
,
errno
,
"Socket creation failed
\n
"
);
set_if_err
=
set_if
();
set_if_err
=
set_if
(
info
);
if
(
set_if_err
<
0
)
error
(
EXIT_FAILURE
,
errno
,
"Couldn't set interface
\n
"
);
if
(
set_if_err
<
0
)
error
(
EXIT_FAILURE
,
errno
,
"Couldn't set interface
\n
"
);
if
(
setsockopt
(
sock_fd
,
SOL_SOCKET
,
SO_PRIORITY
,
&
params
->
packet_priority
,
if
(
setsockopt
(
info
->
sock_fd
,
SOL_SOCKET
,
SO_PRIORITY
,
&
params
->
packet_priority
,
sizeof
(
params
->
packet_priority
)))
sizeof
(
params
->
packet_priority
)))
error
(
EXIT_FAILURE
,
errno
,
"Couldn't set socket priority
\n
"
);
error
(
EXIT_FAILURE
,
errno
,
"Couldn't set socket priority
\n
"
);
if
(
setsockopt
(
sock_fd
,
SOL_SOCKET
,
SO_BINDTODEVICE
,
params
->
network_if
,
if
(
setsockopt
(
info
->
sock_fd
,
SOL_SOCKET
,
SO_BINDTODEVICE
,
params
->
network_if
,
strlen
(
params
->
network_if
)))
strlen
(
params
->
network_if
)))
error
(
EXIT_FAILURE
,
errno
,
"setsockopt SO_BINDTODEVICE failed
\n
"
);
error
(
EXIT_FAILURE
,
errno
,
"setsockopt SO_BINDTODEVICE failed
\n
"
);
if
(
params
->
use_etf
)
{
if
(
params
->
use_etf
)
{
sk_txtime
.
clockid
=
CLOCK_REALTIME
;
info
->
sk_txtime
.
clockid
=
CLOCK_REALTIME
;
sk_txtime
.
flags
=
SOF_TXTIME_REPORT_ERRORS
;
info
->
sk_txtime
.
flags
=
SOF_TXTIME_REPORT_ERRORS
;
if
(
setsockopt
(
sock_fd
,
SOL_SOCKET
,
SO_TXTIME
,
&
sk_txtime
,
if
(
setsockopt
(
info
->
sock_fd
,
SOL_SOCKET
,
SO_TXTIME
,
&
info
->
sk_txtime
,
sizeof
(
sk_txtime
)))
sizeof
(
info
->
sk_txtime
)))
error
(
EXIT_FAILURE
,
errno
,
"setsockopt SO_TXTIME failed
\n
"
);
error
(
EXIT_FAILURE
,
errno
,
"setsockopt SO_TXTIME failed
\n
"
);
}
}
if
(
params
->
use_timestamps
)
{
if
(
params
->
use_timestamps
)
{
if
(
setsockopt
(
sock_fd
,
SOL_SOCKET
,
SO_TIMESTAMPING
,
&
so_timestamping_flags
,
if
(
setsockopt
(
info
->
sock_fd
,
SOL_SOCKET
,
SO_TIMESTAMPING
,
&
so_timestamping_flags
,
sizeof
(
so_timestamping_flags
)))
sizeof
(
so_timestamping_flags
)))
error
(
EXIT_FAILURE
,
errno
,
"setsockopt SO_TIMESTAMPING failed
\n
"
);
error
(
EXIT_FAILURE
,
errno
,
"setsockopt SO_TIMESTAMPING failed
\n
"
);
}
}
// Create poll thread
// Create poll thread
if
(
pthread_create
(
&
thread
,
NULL
,
poll_thread
,
NULL
))
if
(
pthread_create
(
&
thread
,
NULL
,
poll_thread
,
info
))
error
(
EXIT_FAILURE
,
errno
,
"Couldn't create poll thread"
);
error
(
EXIT_FAILURE
,
errno
,
"Couldn't create poll thread"
);
}
}
...
@@ -117,7 +108,7 @@ void init_udp_send(egress_param_t *_params, egress_stat_t *_stats,
...
@@ -117,7 +108,7 @@ void init_udp_send(egress_param_t *_params, egress_stat_t *_stats,
/*
/*
* Sends udp packets
* Sends udp packets
*/
*/
void
send_udp_packet
(
char
*
data
,
uint64_t
txtime
)
{
void
send_udp_packet
(
char
*
data
,
uint64_t
txtime
,
egress_info_t
*
info
)
{
struct
msghdr
msg
;
// Message hardware, sent to the socket
struct
msghdr
msg
;
// Message hardware, sent to the socket
struct
cmsghdr
*
cmsg
;
// Control message hardware, for txtime
struct
cmsghdr
*
cmsg
;
// Control message hardware, for txtime
char
control
[
CMSG_SPACE
(
sizeof
(
txtime
))]
=
{};
// Stores txtime
char
control
[
CMSG_SPACE
(
sizeof
(
txtime
))]
=
{};
// Stores txtime
...
@@ -126,23 +117,26 @@ void send_udp_packet(char *data, uint64_t txtime) {
...
@@ -126,23 +117,26 @@ void send_udp_packet(char *data, uint64_t txtime) {
struct
sockaddr_in
sin
;
// Server address
struct
sockaddr_in
sin
;
// Server address
struct
timespec
ts
;
// timestamp for userspace timestamping
struct
timespec
ts
;
// timestamp for userspace timestamping
egress_param_t
*
params
=
info
->
params
;
egress_stat_t
*
stats
=
info
->
stats
;
if
(
params
->
use_timestamps
)
{
if
(
params
->
use_timestamps
)
{
clock_gettime
(
CLOCK_REALTIME
,
&
ts
);
clock_gettime
(
CLOCK_REALTIME
,
&
ts
);
timestamps_buffer
[
ts_buf_write_index
]
=
ts_to_uint
(
ts
);
stats
->
timestamps_buffer
[
stats
->
ts_buf_write_index
]
=
ts_to_uint
(
ts
);
ts_buf_write_index
=
(
ts_buf_write_index
+
1
)
%
TIMESTAMP_BUFFER_SIZE
;
stats
->
ts_buf_write_index
=
(
stats
->
ts_buf_write_index
+
1
)
%
TIMESTAMP_BUFFER_SIZE
;
}
}
packets_sent
++
;
stats
->
packets_sent
++
;
for
(
int
i
=
0
;
i
<
(
int
)
params
->
tx_buffer_len
;
i
++
)
for
(
int
i
=
0
;
i
<
(
int
)
params
->
tx_buffer_len
;
i
++
)
tx_buffer
[
i
]
=
data
[
i
];
info
->
tx_buffer
[
i
]
=
data
[
i
];
memset
(
&
sin
,
0
,
sizeof
(
sin
));
memset
(
&
sin
,
0
,
sizeof
(
sin
));
sin
.
sin_family
=
AF_INET
;
sin
.
sin_family
=
AF_INET
;
sin
.
sin_addr
.
s_addr
=
inet_addr
(
params
->
server_ip
);
sin
.
sin_addr
.
s_addr
=
inet_addr
(
params
->
server_ip
);
sin
.
sin_port
=
htons
(
SERVER_PORT_INT
);
sin
.
sin_port
=
htons
(
SERVER_PORT_INT
);
iov
.
iov_base
=
tx_buffer
;
iov
.
iov_base
=
info
->
tx_buffer
;
iov
.
iov_len
=
params
->
tx_buffer_len
;
iov
.
iov_len
=
params
->
tx_buffer_len
;
memset
(
&
msg
,
0
,
sizeof
(
msg
));
memset
(
&
msg
,
0
,
sizeof
(
msg
));
...
@@ -164,29 +158,31 @@ void send_udp_packet(char *data, uint64_t txtime) {
...
@@ -164,29 +158,31 @@ void send_udp_packet(char *data, uint64_t txtime) {
msg
.
msg_controllen
=
cmsg
->
cmsg_len
;
msg
.
msg_controllen
=
cmsg
->
cmsg_len
;
}
}
sendmsgerr
=
sendmsg
(
sock_fd
,
&
msg
,
0
);
sendmsgerr
=
sendmsg
(
info
->
sock_fd
,
&
msg
,
0
);
if
(
sendmsgerr
<
0
)
if
(
sendmsgerr
<
0
)
error
(
EXIT_FAILURE
,
errno
,
"sendmsg failed, ret value: %d
\n
"
,
sendmsgerr
);
error
(
EXIT_FAILURE
,
errno
,
"sendmsg failed, ret value: %d
\n
"
,
sendmsgerr
);
}
}
static
void
*
poll_thread
(
void
*
p
)
{
static
void
*
poll_thread
(
void
*
p
)
{
(
void
)
p
;
egress_info_t
*
info
=
(
egress_info_t
*
)
p
;
// Poll file descriptor
// Poll file descriptor
struct
pollfd
poll_fd
=
{.
fd
=
sock_fd
};
struct
pollfd
poll_fd
=
{.
fd
=
info
->
sock_fd
};
while
(
1
)
{
while
(
1
)
{
int
ret
;
int
ret
;
ret
=
poll
(
&
poll_fd
,
1
,
-
1
);
ret
=
poll
(
&
poll_fd
,
1
,
-
1
);
if
(
ret
==
1
&&
poll_fd
.
revents
&
POLLERR
)
{
if
(
ret
==
1
&&
poll_fd
.
revents
&
POLLERR
)
{
process_error_queue
();
process_error_queue
(
info
);
}
}
}
}
return
NULL
;
return
NULL
;
}
}
static
void
process_error_queue
()
{
static
void
process_error_queue
(
egress_info_t
*
info
)
{
int
recv_ret
;
int
recv_ret
;
// IO vector
// IO vector
...
@@ -206,8 +202,11 @@ static void process_error_queue() {
...
@@ -206,8 +202,11 @@ static void process_error_queue() {
struct
cmsghdr
*
cmsg
;
struct
cmsghdr
*
cmsg
;
egress_stat_t
*
stats
=
info
->
stats
;
// Timestamps and errors are received in the error queue
// Timestamps and errors are received in the error queue
recv_ret
=
recvmsg
(
sock_fd
,
&
msg
,
MSG_ERRQUEUE
|
MSG_DONTWAIT
);
recv_ret
=
recvmsg
(
info
->
sock_fd
,
&
msg
,
MSG_ERRQUEUE
|
MSG_DONTWAIT
);
if
(
recv_ret
==
-
1
)
{
if
(
recv_ret
==
-
1
)
{
fprintf
(
stderr
,
"recvmsg() failed
\n
"
);
fprintf
(
stderr
,
"recvmsg() failed
\n
"
);
return
;
return
;
...
@@ -219,22 +218,22 @@ static void process_error_queue() {
...
@@ -219,22 +218,22 @@ static void process_error_queue() {
struct
timespec
*
stamp
=
(
struct
timespec
*
)
CMSG_DATA
(
cmsg
);
struct
timespec
*
stamp
=
(
struct
timespec
*
)
CMSG_DATA
(
cmsg
);
int
kernel_latency
=
int
kernel_latency
=
(
ts_to_uint
(
*
stamp
)
-
timestamps_buffer
[
ts_buf_read_index
])
/
1000
;
(
ts_to_uint
(
*
stamp
)
-
stats
->
timestamps_buffer
[
stats
->
ts_buf_read_index
])
/
1000
;
ts_buf_read_index
=
(
ts_buf_read_index
+
1
)
%
TIMESTAMP_BUFFER_SIZE
;
stats
->
ts_buf_read_index
=
(
stats
->
ts_buf_read_index
+
1
)
%
TIMESTAMP_BUFFER_SIZE
;
stats
->
min_kernel_latency
=
stats
->
min_kernel_latency
=
_min_
(
kernel_latency
,
stats
->
min_kernel_latency
);
_min_
(
kernel_latency
,
stats
->
min_kernel_latency
);
stats
->
max_kernel_latency
=
stats
->
max_kernel_latency
=
_max_
(
kernel_latency
,
stats
->
max_kernel_latency
);
_max_
(
kernel_latency
,
stats
->
max_kernel_latency
);
stats
->
avg_kernel_latency
=
stats
->
avg_kernel_latency
=
(
stats
->
max_kernel_latency
*
packets_sent
+
kernel_latency
)
/
(
stats
->
max_kernel_latency
*
stats
->
packets_sent
+
kernel_latency
)
/
(
packets_sent
+
1
);
(
stats
->
packets_sent
+
1
);
if
(
use_histogram
)
{
if
(
use_histogram
)
{
if
(
kernel_latency
>
MAX_KERNEL_LATENCY
)
if
(
kernel_latency
>
MAX_KERNEL_LATENCY
)
stats
->
high_kernel_latency
++
;
stats
->
high_kernel_latency
++
;
else
else
kernel_latency_hist
[
kernel_latency
]
++
;
stats
->
kernel_latency_hist
[
kernel_latency
]
++
;
}
}
}
}
...
@@ -264,24 +263,29 @@ static void process_error_queue() {
...
@@ -264,24 +263,29 @@ static void process_error_queue() {
}
}
// Sets the interface
// Sets the interface
static
int
set_if
()
{
static
int
set_if
(
egress_info_t
*
info
)
{
struct
ifreq
ifreq
;
struct
ifreq
ifreq
;
egress_param_t
*
params
=
info
->
params
;
memset
(
&
ifreq
,
0
,
sizeof
(
ifreq
));
memset
(
&
ifreq
,
0
,
sizeof
(
ifreq
));
strncpy
(
ifreq
.
ifr_name
,
params
->
network_if
,
sizeof
(
ifreq
.
ifr_name
)
-
1
);
strncpy
(
ifreq
.
ifr_name
,
params
->
network_if
,
sizeof
(
ifreq
.
ifr_name
)
-
1
);
if
(
ioctl
(
sock_fd
,
SIOCGIFINDEX
,
&
ifreq
))
if
(
ioctl
(
info
->
sock_fd
,
SIOCGIFINDEX
,
&
ifreq
))
error
(
EXIT_FAILURE
,
errno
,
"ioctl SIOCGIFINDEX failed
\n
"
);
error
(
EXIT_FAILURE
,
errno
,
"ioctl SIOCGIFINDEX failed
\n
"
);
return
ifreq
.
ifr_ifindex
;
return
ifreq
.
ifr_ifindex
;
}
}
static
void
init_tx_buffer
()
{
static
void
init_tx_buffer
(
egress_info_t
*
info
)
{
egress_param_t
*
params
=
info
->
params
;
if
(
params
->
tx_buffer_len
<
1
)
{
if
(
params
->
tx_buffer_len
<
1
)
{
fprintf
(
stderr
,
"tx buffer length should be greater than 1
\n
"
);
fprintf
(
stderr
,
"tx buffer length should be greater than 1
\n
"
);
exit
(
EXIT_FAILURE
);
exit
(
EXIT_FAILURE
);
}
}
tx_buffer
=
malloc
(
params
->
tx_buffer_len
);
info
->
tx_buffer
=
malloc
(
params
->
tx_buffer_len
);
}
}
packet-exchange/src/send_packet.h
View file @
6c2dd397
#ifndef SEND_PACKET_H
#ifndef SEND_PACKET_H
#define SEND_PACKET_H
#define SEND_PACKET_H
#include <arpa/inet.h>
#include <errno.h>
#include <error.h>
#include <fcntl.h>
#include <ifaddrs.h>
#include <inttypes.h>
#include <linux/errqueue.h>
#include <linux/ethtool.h>
#include <linux/net_tstamp.h>
#include <linux/sockios.h>
#include <net/if.h>
#include <netdb.h>
#include <netinet/in.h>
#include <poll.h>
#include <pthread.h>
#include <sched.h>
#include <signal.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include "common.h"
#include "common.h"
typedef
struct
egress_param
{
typedef
struct
egress_param
{
...
@@ -16,6 +43,8 @@ typedef struct egress_param {
...
@@ -16,6 +43,8 @@ typedef struct egress_param {
typedef
struct
egress_stat
{
typedef
struct
egress_stat
{
uint64_t
packets_sent
;
uint64_t
high_kernel_latency
;
uint64_t
high_kernel_latency
;
uint64_t
invalid_parameter
;
uint64_t
invalid_parameter
;
uint64_t
missed_deadline
;
uint64_t
missed_deadline
;
...
@@ -28,13 +57,27 @@ typedef struct egress_stat {
...
@@ -28,13 +57,27 @@ typedef struct egress_stat {
int
avg_interval
;
int
avg_interval
;
int
max_interval
;
int
max_interval
;
int
ts_buf_read_index
;
int
ts_buf_write_index
;
uint64_t
*
kernel_latency_hist
;
int64_t
timestamps_buffer
[
TIMESTAMP_BUFFER_SIZE
];
}
egress_stat_t
;
}
egress_stat_t
;
void
init_udp_send
(
egress_param_t
*
_params
,
typedef
struct
egress_info
{
egress_stat_t
*
_stats
,
int
_use_histogram
,
int
_stop_tracing
,
int
sock_fd
;
uint64_t
*
_kernel_latency_hist
);
struct
sock_txtime
sk_txtime
;
char
*
tx_buffer
;
egress_param_t
*
params
;
egress_stat_t
*
stats
;
}
egress_info_t
;
void
send_udp_packet
(
char
*
data
,
uint64_t
txtime
);
void
init_udp_send
(
egress_info_t
*
info
,
int
_use_histogram
,
int
_stop_tracing
);
void
send_udp_packet
(
char
*
data
,
uint64_t
txtime
,
egress_info_t
*
info
);
#endif
#endif
packet-exchange/src/server.c
View file @
6c2dd397
...
@@ -71,6 +71,7 @@ static thread_param_t thread_params;
...
@@ -71,6 +71,7 @@ static thread_param_t thread_params;
static
ingress_param_t
ingress_params
;
static
ingress_param_t
ingress_params
;
static
egress_param_t
egress_params
;
static
egress_param_t
egress_params
;
static
egress_stat_t
egress_stats
=
{.
min_kernel_latency
=
INT_MAX
};
static
egress_stat_t
egress_stats
=
{.
min_kernel_latency
=
INT_MAX
};
static
egress_info_t
egress_info
;
static
ingress_stat_t
ingress_stats
=
{.
min_kernel_latency
=
INT_MAX
,
static
ingress_stat_t
ingress_stats
=
{.
min_kernel_latency
=
INT_MAX
,
.
min_interval
=
INT_MAX
};
.
min_interval
=
INT_MAX
};
static
int
enable_histograms
;
static
int
enable_histograms
;
...
@@ -151,24 +152,24 @@ static void *emit_signal_thread(void *p) {
...
@@ -151,24 +152,24 @@ static void *emit_signal_thread(void *p) {
clock_gettime
(
CLOCK_REALTIME
,
&
current
);
clock_gettime
(
CLOCK_REALTIME
,
&
current
);
// Check if something went wrong
// Check if something went wrong
if
(
i
>
0
)
{
//
if(i > 0) {
emit_diff
=
calcdiff_ns_signed
(
current
,
previous_emit
);
//
emit_diff = calcdiff_ns_signed(current, previous_emit);
ts_diff
=
calcdiff_ns_signed
(
emit_signal_next
,
previous_ts
);
//
ts_diff = calcdiff_ns_signed(emit_signal_next, previous_ts);
if
((
emit_diff
<
((
int64_t
)
thread_params
.
interval
)
-
ERROR_MARGIN_NS
)
||
//
if((emit_diff < ((int64_t)thread_params.interval) - ERROR_MARGIN_NS) ||
(
emit_diff
>
((
int64_t
)
thread_params
.
interval
)
+
ERROR_MARGIN_NS
))
{
//
(emit_diff > ((int64_t)thread_params.interval) + ERROR_MARGIN_NS)) {
fprintf
(
stderr
,
"Signal emission interval reached error threshold: %"
PRIi64
"
\n
"
,
emit_diff
);
//
fprintf(stderr, "Signal emission interval reached error threshold: %" PRIi64 "\n", emit_diff);
latency_spike
=
1
;
//
latency_spike = 1;
}
//
}
if
((
ts_diff
<
((
int64_t
)
thread_params
.
interval
)
-
ERROR_MARGIN_NS
)
||
//
if((ts_diff < ((int64_t)thread_params.interval) - ERROR_MARGIN_NS) ||
(
ts_diff
>
((
int64_t
)
thread_params
.
interval
)
+
ERROR_MARGIN_NS
))
{
//
(ts_diff > ((int64_t)thread_params.interval) + ERROR_MARGIN_NS)) {
fprintf
(
stderr
,
"Timestamp interval reached error threshold: %"
PRIi64
"
\n
"
,
ts_diff
);
//
fprintf(stderr, "Timestamp interval reached error threshold: %" PRIi64 "\n", ts_diff);
latency_spike
=
1
;
//
latency_spike = 1;
}
//
}
if
(
latency_spike
)
{
//
if(latency_spike) {
fprintf
(
stderr
,
"Exiting... Current interval: %d
\n
"
,
interval_us
);
//
fprintf(stderr, "Exiting... Current interval: %d\n", interval_us);
exit
(
EXIT_FAILURE
);
//
exit(EXIT_FAILURE);
}
//
}
}
//
}
previous_emit
=
current
;
previous_emit
=
current
;
previous_ts
=
emit_signal_next
;
previous_ts
=
emit_signal_next
;
}
}
...
@@ -221,7 +222,7 @@ static void *tsn_thread(void *p) {
...
@@ -221,7 +222,7 @@ static void *tsn_thread(void *p) {
// RTT
// RTT
if
(
tsn_task
==
RTT_TASK
)
{
if
(
tsn_task
==
RTT_TASK
)
{
recv_udp_packet
();
recv_udp_packet
();
send_udp_packet
(
""
,
0
);
send_udp_packet
(
""
,
0
,
&
egress_info
);
// Receive packet
// Receive packet
}
else
if
(
tsn_task
==
RECV_PACKET_TASK
||
tsn_task
==
XDP_TASK
)
{
}
else
if
(
tsn_task
==
RECV_PACKET_TASK
||
tsn_task
==
XDP_TASK
)
{
...
@@ -413,6 +414,9 @@ int main(int argc, char *argv[]) {
...
@@ -413,6 +414,9 @@ int main(int argc, char *argv[]) {
ingress_params
.
use_timestamps
=
enable_timestamps
;
ingress_params
.
use_timestamps
=
enable_timestamps
;
ingress_params
.
interval
=
thread_params
.
interval
;
ingress_params
.
interval
=
thread_params
.
interval
;
egress_info
.
params
=
&
egress_params
;
egress_info
.
stats
=
&
egress_stats
;
// Init histograms
// Init histograms
if
(
enable_histograms
)
{
if
(
enable_histograms
)
{
memset
(
kernel_latency_hist
,
0
,
sizeof
(
kernel_latency_hist
));
memset
(
kernel_latency_hist
,
0
,
sizeof
(
kernel_latency_hist
));
...
@@ -435,7 +439,7 @@ int main(int argc, char *argv[]) {
...
@@ -435,7 +439,7 @@ int main(int argc, char *argv[]) {
// Initialize the UDP packet sending socket if RTT is measured
// Initialize the UDP packet sending socket if RTT is measured
if
(
tsn_task
==
RTT_TASK
)
if
(
tsn_task
==
RTT_TASK
)
init_udp_send
(
&
egress_
params
,
&
egress_stats
,
0
,
0
,
NULL
);
init_udp_send
(
&
egress_
info
,
0
,
0
);
if
(
thread_params
.
emit_signal
)
{
if
(
thread_params
.
emit_signal
)
{
pthread_mutex_init
(
&
emit_signal_mutex
,
NULL
);
pthread_mutex_init
(
&
emit_signal_mutex
,
NULL
);
...
...
scripts/run-client
View file @
6c2dd397
...
@@ -4,7 +4,7 @@ script_dir=$(dirname $(realpath $0))
...
@@ -4,7 +4,7 @@ script_dir=$(dirname $(realpath $0))
usage
()
{
usage
()
{
cat
<<
ENDUSAGE
cat
<<
ENDUSAGE
Usage:
$0
[-h] QDISC_OPT [CLIENT_OPTS]
BOARD_HOSTNAME
Usage:
$0
[-h] QDISC_OPT [CLIENT_OPTS]
IF BOARD_HOSTNAME [IF2 BOARD_HOSTNAME2]
-h Show help
-h Show help
QDISC_OPTS: [-e DELTA [-o USEC] -H] [-q]
QDISC_OPTS: [-e DELTA [-o USEC] -H] [-q]
Which qdisc to use (will call create-qdisc script)
Which qdisc to use (will call create-qdisc script)
...
@@ -24,8 +24,8 @@ Usage: $0 [-h] QDISC_OPT [CLIENT_OPTS] BOARD_HOSTNAME
...
@@ -24,8 +24,8 @@ Usage: $0 [-h] QDISC_OPT [CLIENT_OPTS] BOARD_HOSTNAME
(to be used with PTP)
(to be used with PTP)
-d TX_BUF_LEN Length of the data sent in the packets
-d TX_BUF_LEN Length of the data sent in the packets
-i USEC Interval at which the RT thread should send packets
-i USEC Interval at which the RT thread should send packets
-I IF Network interface to use to send the packets
-a CPU CPU on which to pin the program
-a CPU CPU on which to pin the program
-U Interactive interval change
TRACE_OPTS: -T [-P TRACER -E EVENTS -B SIZE]
TRACE_OPTS: -T [-P TRACER -E EVENTS -B SIZE]
Options to trace with trace-cmd until ETF deadline is missed
Options to trace with trace-cmd until ETF deadline is missed
(see trace-cmd man page and ftrace documentation)
(see trace-cmd man page and ftrace documentation)
...
@@ -56,7 +56,7 @@ etf_offset=500
...
@@ -56,7 +56,7 @@ etf_offset=500
tracecmd_events
=
"-e irq -e sched -e net_dev_start_xmit -e net_dev_xmit -e net_dev_xmit_timeout"
tracecmd_events
=
"-e irq -e sched -e net_dev_start_xmit -e net_dev_xmit -e net_dev_xmit_timeout"
tracecmd_opts
=
""
tracecmd_opts
=
""
while
getopts
"a:bc:d:e:o:ghi:qs:tB:E:I:HP:TS:"
opt
;
do
while
getopts
"a:bc:d:e:o:ghi:qs:tB:E:I:HP:TS:
U:
"
opt
;
do
case
"
${
opt
}
"
in
case
"
${
opt
}
"
in
h
)
h
)
usage
usage
...
@@ -106,9 +106,6 @@ while getopts "a:bc:d:e:o:ghi:qs:tB:E:I:HP:TS:" opt; do
...
@@ -106,9 +106,6 @@ while getopts "a:bc:d:e:o:ghi:qs:tB:E:I:HP:TS:" opt; do
E
)
E
)
tracecmd_events
=
${
OPTARG
}
tracecmd_events
=
${
OPTARG
}
;;
;;
I
)
interface
=
"
${
OPTARG
}
"
;;
H
)
H
)
qdisc_options+
=
" -H"
qdisc_options+
=
" -H"
;;
;;
...
@@ -123,20 +120,37 @@ while getopts "a:bc:d:e:o:ghi:qs:tB:E:I:HP:TS:" opt; do
...
@@ -123,20 +120,37 @@ while getopts "a:bc:d:e:o:ghi:qs:tB:E:I:HP:TS:" opt; do
use_tracer
=
1
use_tracer
=
1
client_options+
=
" -S
${
OPTARG
}
"
client_options+
=
" -S
${
OPTARG
}
"
;;
;;
U
)
client_options+
=
" -U
${
OPTARG
}
"
;;
*
)
*
)
usage
usage
;;
;;
esac
esac
done
done
shift
$((
OPTIND-1
))
shift
$((
OPTIND-1
))
if
[
-z
"
$1
"
]
;
then
usage
fi
qdisc_options+
=
" -I
$interface
"
qdisc_options+
=
" -I
$interface
"
client_options+
=
" -a
$cpu
"
client_options+
=
" -a
$cpu
"
board_name
=
$1
if
[
-z
"
$1
"
]
||
[
-z
"
$2
"
]
;
then
usage
fi
board_name
=
$2
board_ip
=
$(
cat
/etc/hosts |
grep
$board_name
|
awk
'{print $1}'
)
board_ip
=
$(
cat
/etc/hosts |
grep
$board_name
|
awk
'{print $1}'
)
interface
=
$1
board2_ip
=
""
interface2
=
""
if
[
-n
"
$3
"
]
;
then
if
[
-z
"
$4
"
]
;
then
usage
fi
interface2
=
$3
board2_name
=
$4
board2_ip
=
$(
cat
/etc/hosts |
grep
$board2_name
|
awk
'{print $1}'
)
fi
if
[
-z
"
${
use_histogram
}
"
]
;
then
if
[
-z
"
${
use_histogram
}
"
]
;
then
client_options+
=
" -v"
client_options+
=
" -v"
...
@@ -174,18 +188,18 @@ cd $script_dir;
...
@@ -174,18 +188,18 @@ cd $script_dir;
if
[
-n
"
${
use_histogram
}
"
]
;
then
if
[
-n
"
${
use_histogram
}
"
]
;
then
echo
"client
$client_options
$interface
$board_ip
>
$output
;mv
$output
~/"
;
echo
"client
$client_options
$interface
$board_ip
$interface2
$board2_ip
>
$output
;mv
$output
~/"
;
$script_dir
/../packet-exchange/build/client
$client_options
$interface
$board_ip
>
$output
;
$script_dir
/../packet-exchange/build/client
$client_options
$interface
$board_ip
$interface2
$board2_ip
>
$output
;
mv
$output
~/
;
mv
$output
~/
;
elif
[
-n
"
${
use_tracer
}
"
]
;
then
elif
[
-n
"
${
use_tracer
}
"
]
;
then
echo
"trace-cmd record
$tracecmd_opts
$tracecmd_events
./client
$client_options
$interface
$board_ip
"
;
echo
"trace-cmd record
$tracecmd_opts
$tracecmd_events
./client
$client_options
$interface
$board_ip
$interface2
$board2_ip
"
;
trace-cmd record
$tracecmd_opts
$tracecmd_events
$script_dir
/../packet-exchange/build/client
$client_options
$interface
$board_ip
;
trace-cmd record
$tracecmd_opts
$tracecmd_events
$script_dir
/../packet-exchange/build/client
$client_options
$interface
$board_ip
$interface2
$board2_ip
;
else
else
echo
"client
$client_options
$interface
$board_ip
"
;
echo
"client
$client_options
$interface
$board_ip
$interface2
$board2_ip
"
;
$script_dir
/../packet-exchange/build/client
$client_options
$interface
$board_ip
;
$script_dir
/../packet-exchange/build/client
$client_options
$interface
$board_ip
$interface2
$board2_ip
;
fi
fi
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment