Re: [PATCH BlueZ 1/3] tools/tester: test COMPLETION timestamps

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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
>
>





[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux