All of lore.kernel.org
 help / color / mirror / Atom feed
From: Pauli Virtanen <pav@iki.fi>
To: linux-bluetooth@vger.kernel.org
Cc: Pauli Virtanen <pav@iki.fi>
Subject: [RFC PATCH 2/3] Bluetooth: ISO: add new ioctl() for reading tx latency
Date: Wed, 28 Feb 2024 22:03:40 +0200	[thread overview]
Message-ID: <8e5df7837d596cbedcfa04d766ce1caba50d853b.1709150574.git.pav@iki.fi> (raw)
In-Reply-To: <cover.1709150574.git.pav@iki.fi>

Add ioctl BTGETTXINFO to read information of a previous packet
completion event concerning a given ISO socket.

It contains sufficient information so the user can know which previous
sendmsg() the packet corresponds to and what was its completion time in
monotonic clock, so latency can be calculated.  The user can then also
know the packet queue length (in units of their sendmsg packets).

Mark submitted skb so that hci_core updates the latency information, and
read it in the ioctl.

Signed-off-by: Pauli Virtanen <pav@iki.fi>
---
 include/net/bluetooth/bluetooth.h | 37 ++++++++++++++++++++
 net/bluetooth/iso.c               | 58 ++++++++++++++++++++++++++++---
 2 files changed, 90 insertions(+), 5 deletions(-)

diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
index f6bdd040adaa..ff4230d15461 100644
--- a/include/net/bluetooth/bluetooth.h
+++ b/include/net/bluetooth/bluetooth.h
@@ -239,6 +239,43 @@ struct bt_codecs {
 
 #define BT_ISO_BASE		20
 
+/* BTGETTXINFO: Transmission latency information.
+ *
+ * Produces information of a previous event when a packet was sent, and the
+ * length of packet queue at that time.
+ *
+ * Applicable to: Bluetooth ISO sockets.
+ *
+ * Input: Zero-initialize reserved flag bits and other fields.
+ *
+ * Output:
+ *
+ * Fails with ENOENT if no packet has been sent.
+ *
+ * - flags: currently always 0, all bits reserved for extensions.
+ *
+ * - queue: total number of packets in queue (controller and socket buffers)
+ *   at the time of the event.
+ *
+ * - time: reference event timestamp (nsec, in system monotonic clock).
+ *
+ * - offset: offset (nsec) of actual packet timing from the reference timestamp.
+ *   Currently always 0.
+ *
+ * For packet latencies in nanoseconds, the application can track timestamps
+ * t[j] when it sent packet j. Then, given t[k] < tx_info.time < t[k + 1],
+ * event packet j = k - tx.queue and ref_latency_nsec = tx_info.time - t[j].
+ */
+
+#define BTGETTXINFO	_IOWR('B', 100, struct bt_tx_info)
+
+struct bt_tx_info {
+	__u32	flags;
+	__u32	queue;
+	__s64	time;
+	__s64	offset;
+} __packed;
+
 __printf(1, 2)
 void bt_info(const char *fmt, ...);
 __printf(1, 2)
diff --git a/net/bluetooth/iso.c b/net/bluetooth/iso.c
index 30c777c469f9..4953c987e4fd 100644
--- a/net/bluetooth/iso.c
+++ b/net/bluetooth/iso.c
@@ -500,6 +500,8 @@ static int iso_send_frame(struct sock *sk, struct sk_buff *skb)
 
 	if (skb->len > qos->ucast.out.sdu)
 		return -EMSGSIZE;
+	if (sk->sk_state != BT_CONNECTED)
+		return -ENOTCONN;
 
 	len = skb->len;
 
@@ -509,10 +511,9 @@ static int iso_send_frame(struct sock *sk, struct sk_buff *skb)
 	hdr->slen = cpu_to_le16(hci_iso_data_len_pack(len,
 						      HCI_ISO_STATUS_VALID));
 
-	if (sk->sk_state == BT_CONNECTED)
-		hci_send_iso(conn->hcon, skb);
-	else
-		len = -ENOTCONN;
+	hci_mark_tx_latency(&conn->hcon->tx_latency, skb);
+
+	hci_send_iso(conn->hcon, skb);
 
 	return len;
 }
@@ -2232,6 +2233,53 @@ void iso_recv(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
 	kfree_skb(skb);
 }
 
+static int iso_sock_ioctl(struct socket *sock, unsigned int cmd,
+			  unsigned long arg)
+{
+	struct sock *sk = sock->sk;
+	struct tx_latency latency;
+	struct bt_tx_info info;
+
+	BT_DBG("sk %p cmd %x arg %lx", sk, cmd, arg);
+
+	switch (cmd) {
+	case BTGETTXINFO:
+		/* Require zero-initialized, to allow later extensions */
+		if (copy_from_user(&info, (void __user *)arg, sizeof(info)))
+			return -EFAULT;
+		if (info.flags || info.queue || info.time || info.offset)
+			return -EINVAL;
+
+		memset(&info, 0, sizeof(info));
+
+		lock_sock(sk);
+
+		if (sk->sk_state != BT_CONNECTED) {
+			release_sock(sk);
+			return -EINVAL;
+		}
+
+		hci_copy_tx_latency(&latency,
+				    &iso_pi(sk)->conn->hcon->tx_latency);
+
+		release_sock(sk);
+
+		if (!latency.now.time)
+			return -ENOENT;
+
+		info.queue = latency.now.queue;
+		info.time = ktime_to_ns(latency.now.time);
+		info.offset = latency.now.offset;
+
+		if (copy_to_user((void __user *)arg, &info, sizeof(info)))
+			return -EFAULT;
+
+		return 0;
+	}
+
+	return bt_sock_ioctl(sock, cmd, arg);
+}
+
 static struct hci_cb iso_cb = {
 	.name		= "ISO",
 	.connect_cfm	= iso_connect_cfm,
@@ -2270,7 +2318,7 @@ static const struct proto_ops iso_sock_ops = {
 	.sendmsg	= iso_sock_sendmsg,
 	.recvmsg	= iso_sock_recvmsg,
 	.poll		= bt_sock_poll,
-	.ioctl		= bt_sock_ioctl,
+	.ioctl		= iso_sock_ioctl,
 	.mmap		= sock_no_mmap,
 	.socketpair	= sock_no_socketpair,
 	.shutdown	= iso_sock_shutdown,
-- 
2.44.0


  parent reply	other threads:[~2024-02-28 20:04 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-02-28 20:03 [RFC PATCH 0/3] Bluetooth: add transmission latency tracking for ISO & L2CAP Pauli Virtanen
2024-02-28 20:03 ` [RFC PATCH 1/3] Bluetooth: add transmission latency tracking for ISO and ACL Pauli Virtanen
2024-02-28 20:34   ` Bluetooth: add transmission latency tracking for ISO & L2CAP bluez.test.bot
2024-02-28 20:03 ` Pauli Virtanen [this message]
2024-02-28 20:03 ` [RFC PATCH 3/3] Bluetooth: L2CAP: add new ioctl() for reading tx latency Pauli Virtanen
2024-02-28 20:31 ` [RFC PATCH 0/3] Bluetooth: add transmission latency tracking for ISO & L2CAP Luiz Augusto von Dentz
2024-02-28 21:01   ` Luiz Augusto von Dentz
2024-02-28 22:15   ` Pauli Virtanen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=8e5df7837d596cbedcfa04d766ce1caba50d853b.1709150574.git.pav@iki.fi \
    --to=pav@iki.fi \
    --cc=linux-bluetooth@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.