unsubscribe On Sun, Feb 9, 2025 at 6:40 PM Pauli Virtanen <pav@xxxxxx> wrote: > > Add support for SOF_TIMESTAMPING_TX_COMPLETION also in cases where > errqueue.h is old and doesn't define it. > > Support timestamps of different types arriving out of order, as multiple > SND may well arrive before COMPLETION. Also allow TX timestamp arriving > before bthost receives data, as that may well happen. > > Remove tests SCHED timestamps, as those won't be generated for now. > > Don't test COMPLETION for SCO, since it's not supported now either. > --- > configure.ac | 7 +++++++ > tools/iso-tester.c | 36 +++++++++++------------------------- > tools/l2cap-tester.c | 14 ++++++++------ > tools/sco-tester.c | 8 ++++---- > tools/tester.h | 42 +++++++++++++++++++++++++++++++++++------- > 5 files changed, 65 insertions(+), 42 deletions(-) > > diff --git a/configure.ac b/configure.ac > index 6a19487f6..75841e4c9 100644 > --- a/configure.ac > +++ b/configure.ac > @@ -389,6 +389,13 @@ AC_ARG_ENABLE(testing, AS_HELP_STRING([--enable-testing], > [enable_testing=${enableval}]) > AM_CONDITIONAL(TESTING, test "${enable_testing}" = "yes") > > +if (test "${enable_testing}" = "yes"); then > + AC_CHECK_DECLS([SOF_TIMESTAMPING_TX_COMPLETION, SCM_TSTAMP_COMPLETION], > + [], [], [[#include <time.h> > + #include <linux/errqueue.h> > + #include <linux/net_tstamp.h>]]) > +fi > + > AC_ARG_ENABLE(experimental, AS_HELP_STRING([--enable-experimental], > [enable experimental tools]), > [enable_experimental=${enableval}]) > diff --git a/tools/iso-tester.c b/tools/iso-tester.c > index c30c44ce9..b5e638808 100644 > --- a/tools/iso-tester.c > +++ b/tools/iso-tester.c > @@ -1066,20 +1066,10 @@ static const struct iso_client_data connect_send_tx_timestamping = { > .send = &send_16_2_1, > .so_timestamping = (SOF_TIMESTAMPING_SOFTWARE | > SOF_TIMESTAMPING_OPT_ID | > - SOF_TIMESTAMPING_TX_SOFTWARE), > - .repeat_send = 1, > - .repeat_send_pre_ts = 2, > -}; > - > -static const struct iso_client_data connect_send_tx_sched_timestamping = { > - .qos = QOS_16_2_1, > - .expect_err = 0, > - .send = &send_16_2_1, > - .so_timestamping = (SOF_TIMESTAMPING_SOFTWARE | > SOF_TIMESTAMPING_TX_SOFTWARE | > - SOF_TIMESTAMPING_OPT_TSONLY | > - SOF_TIMESTAMPING_TX_SCHED), > + SOF_TIMESTAMPING_TX_COMPLETION), > .repeat_send = 1, > + .repeat_send_pre_ts = 2, > }; > > static const struct iso_client_data connect_send_tx_cmsg_timestamping = { > @@ -1087,7 +1077,8 @@ static const struct iso_client_data connect_send_tx_cmsg_timestamping = { > .expect_err = 0, > .send = &send_16_2_1, > .so_timestamping = (SOF_TIMESTAMPING_SOFTWARE | > - SOF_TIMESTAMPING_TX_SOFTWARE), > + SOF_TIMESTAMPING_OPT_TSONLY | > + SOF_TIMESTAMPING_TX_COMPLETION), > .repeat_send = 1, > .cmsg_timestamping = true, > }; > @@ -1097,7 +1088,7 @@ static const struct iso_client_data connect_send_tx_no_poll_timestamping = { > .expect_err = 0, > .send = &send_16_2_1, > .so_timestamping = (SOF_TIMESTAMPING_SOFTWARE | > - SOF_TIMESTAMPING_TX_SOFTWARE), > + SOF_TIMESTAMPING_TX_COMPLETION), > .repeat_send = 1, > .no_poll_errqueue = true, > }; > @@ -2241,10 +2232,10 @@ static gboolean iso_recv_errqueue(GIOChannel *io, GIOCondition cond, > err = tx_tstamp_recv(&data->tx_ts, sk, isodata->send->iov_len); > if (err > 0) > return TRUE; > - else if (!err && !data->step) > - tester_test_passed(); > - else > + else if (err) > tester_test_failed(); > + else if (!data->step) > + tester_test_passed(); > > data->io_id[2] = 0; > return FALSE; > @@ -2289,7 +2280,7 @@ static void iso_tx_timestamping(struct test_data *data, GIOChannel *io) > int err; > unsigned int count; > > - if (!(isodata->so_timestamping & SOF_TIMESTAMPING_TX_RECORD_MASK)) > + if (!(isodata->so_timestamping & TS_TX_RECORD_MASK)) > return; > > tester_print("Enabling TX timestamping"); > @@ -2336,7 +2327,7 @@ static void iso_tx_timestamping(struct test_data *data, GIOChannel *io) > } > > if (isodata->cmsg_timestamping) > - so &= ~SOF_TIMESTAMPING_TX_RECORD_MASK; > + so &= ~TS_TX_RECORD_MASK; > > err = setsockopt(sk, SOL_SOCKET, SO_TIMESTAMPING, &so, sizeof(so)); > if (err < 0) { > @@ -2374,7 +2365,7 @@ static void iso_send_data(struct test_data *data, GIOChannel *io) > cmsg->cmsg_len = CMSG_LEN(sizeof(uint32_t)); > > *((uint32_t *)CMSG_DATA(cmsg)) = (isodata->so_timestamping & > - SOF_TIMESTAMPING_TX_RECORD_MASK); > + TS_TX_RECORD_MASK); > } > > ret = sendmsg(sk, &msg, 0); > @@ -3645,11 +3636,6 @@ int main(int argc, char *argv[]) > test_iso("ISO Send - TX Timestamping", &connect_send_tx_timestamping, > setup_powered, test_connect); > > - /* Test schedule-time TX timestamps are emitted */ > - test_iso("ISO Send - TX Sched Timestamping", > - &connect_send_tx_sched_timestamping, setup_powered, > - test_connect); > - > /* Test TX timestamping with flags set via per-packet CMSG */ > test_iso("ISO Send - TX CMSG Timestamping", > &connect_send_tx_cmsg_timestamping, setup_powered, > diff --git a/tools/l2cap-tester.c b/tools/l2cap-tester.c > index 1780c9fbd..7f3be6c0f 100644 > --- a/tools/l2cap-tester.c > +++ b/tools/l2cap-tester.c > @@ -381,7 +381,8 @@ static const struct l2cap_data client_connect_tx_timestamping_test = { > .data_len = sizeof(l2_data), > .so_timestamping = (SOF_TIMESTAMPING_SOFTWARE | > SOF_TIMESTAMPING_OPT_ID | > - SOF_TIMESTAMPING_TX_SOFTWARE), > + SOF_TIMESTAMPING_TX_SOFTWARE | > + SOF_TIMESTAMPING_TX_COMPLETION), > .repeat_send = 2, > }; > > @@ -594,7 +595,8 @@ static const struct l2cap_data le_client_connect_tx_timestamping_test = { > .data_len = sizeof(l2_data), > .so_timestamping = (SOF_TIMESTAMPING_SOFTWARE | > SOF_TIMESTAMPING_OPT_ID | > - SOF_TIMESTAMPING_TX_SOFTWARE), > + SOF_TIMESTAMPING_TX_SOFTWARE | > + SOF_TIMESTAMPING_TX_COMPLETION), > }; > > static const struct l2cap_data le_client_connect_adv_success_test_1 = { > @@ -1345,10 +1347,10 @@ static gboolean recv_errqueue(GIOChannel *io, GIOCondition cond, > err = tx_tstamp_recv(&data->tx_ts, sk, l2data->data_len); > if (err > 0) > return TRUE; > - else if (!err && !data->step) > - tester_test_passed(); > - else > + else if (err) > tester_test_failed(); > + else if (!data->step) > + tester_test_passed(); > > data->err_io_id = 0; > return FALSE; > @@ -1362,7 +1364,7 @@ static void l2cap_tx_timestamping(struct test_data *data, GIOChannel *io) > int err; > unsigned int count; > > - if (!(l2data->so_timestamping & SOF_TIMESTAMPING_TX_RECORD_MASK)) > + if (!(l2data->so_timestamping & TS_TX_RECORD_MASK)) > return; > > sk = g_io_channel_unix_get_fd(io); > diff --git a/tools/sco-tester.c b/tools/sco-tester.c > index 6fc26b7af..130ab526d 100644 > --- a/tools/sco-tester.c > +++ b/tools/sco-tester.c > @@ -665,10 +665,10 @@ static gboolean recv_errqueue(GIOChannel *io, GIOCondition cond, > err = tx_tstamp_recv(&data->tx_ts, sk, scodata->data_len); > if (err > 0) > return TRUE; > - else if (!err && !data->step) > - tester_test_passed(); > - else > + else if (err) > tester_test_failed(); > + else if (!data->step) > + tester_test_passed(); > > data->err_io_id = 0; > return FALSE; > @@ -682,7 +682,7 @@ static void sco_tx_timestamping(struct test_data *data, GIOChannel *io) > int err; > unsigned int count; > > - if (!(scodata->so_timestamping & SOF_TIMESTAMPING_TX_RECORD_MASK)) > + if (!(scodata->so_timestamping & TS_TX_RECORD_MASK)) > return; > > sk = g_io_channel_unix_get_fd(io); > diff --git a/tools/tester.h b/tools/tester.h > index b6de084a4..82770014f 100644 > --- a/tools/tester.h > +++ b/tools/tester.h > @@ -20,6 +20,15 @@ > #define SEC_NSEC(_t) ((_t) * 1000000000LL) > #define TS_NSEC(_ts) (SEC_NSEC((_ts)->tv_sec) + (_ts)->tv_nsec) > > +#if !HAVE_DECL_SOF_TIMESTAMPING_TX_COMPLETION > +#define SOF_TIMESTAMPING_TX_COMPLETION (SOF_TIMESTAMPING_LAST << 1) > +#endif > +#if !HAVE_DECL_SCM_TSTAMP_COMPLETION > +#define SCM_TSTAMP_COMPLETION (SCM_TSTAMP_ACK + 1) > +#endif > +#define TS_TX_RECORD_MASK (SOF_TIMESTAMPING_TX_RECORD_MASK | \ > + SOF_TIMESTAMPING_TX_COMPLETION) > + > struct tx_tstamp_data { > struct { > uint32_t id; > @@ -59,6 +68,13 @@ static inline int tx_tstamp_expect(struct tx_tstamp_data *data) > pos++; > } > > + if (data->so_timestamping & SOF_TIMESTAMPING_TX_COMPLETION) { > + g_assert(pos < ARRAY_SIZE(data->expect)); > + data->expect[pos].type = SCM_TSTAMP_COMPLETION; > + data->expect[pos].id = data->sent; > + pos++; > + } > + > data->sent++; > > steps = pos - data->count; > @@ -77,6 +93,7 @@ static inline int tx_tstamp_recv(struct tx_tstamp_data *data, int sk, int len) > struct scm_timestamping *tss = NULL; > struct sock_extended_err *serr = NULL; > struct timespec now; > + unsigned int i; > > iov.iov_base = buf; > iov.iov_len = sizeof(buf); > @@ -89,7 +106,7 @@ static inline int tx_tstamp_recv(struct tx_tstamp_data *data, int sk, int len) > > ret = recvmsg(sk, &msg, MSG_ERRQUEUE); > if (ret < 0) { > - if (ret == EAGAIN || ret == EWOULDBLOCK) > + if (errno == EAGAIN || errno == EWOULDBLOCK) > return data->count - data->pos; > > tester_warn("Failed to read from errqueue: %s (%d)", > @@ -147,18 +164,29 @@ static inline int tx_tstamp_recv(struct tx_tstamp_data *data, int sk, int len) > return -EINVAL; > } > > - if ((data->so_timestamping & SOF_TIMESTAMPING_OPT_ID) && > - serr->ee_data != data->expect[data->pos].id) { > - tester_warn("Bad timestamp id %u", serr->ee_data); > + /* Find first unreceived timestamp of the right type */ > + for (i = 0; i < data->count; ++i) { > + if (data->expect[i].type >= 0xffff) > + continue; > + > + if (serr->ee_info == data->expect[i].type) { > + data->expect[i].type = 0xffff; > + break; > + } > + } > + if (i == data->count) { > + tester_warn("Bad timestamp type %u", serr->ee_info); > return -EINVAL; > } > > - if (serr->ee_info != data->expect[data->pos].type) { > - tester_warn("Bad timestamp type %u", serr->ee_info); > + if ((data->so_timestamping & SOF_TIMESTAMPING_OPT_ID) && > + serr->ee_data != data->expect[i].id) { > + tester_warn("Bad timestamp id %u", serr->ee_data); > return -EINVAL; > } > > - tester_print("Got valid TX timestamp %u", data->pos); > + tester_print("Got valid TX timestamp %u (type %u, id %u)", i, > + serr->ee_info, serr->ee_data); > > ++data->pos; > > -- > 2.48.1 > >