From patchwork Sun Feb 9 10:39:13 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pauli Virtanen X-Patchwork-Id: 863918 Received: from lahtoruutu.iki.fi (lahtoruutu.iki.fi [185.185.170.37]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8CC8013DBA0; Sun, 9 Feb 2025 10:39:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=pass smtp.client-ip=185.185.170.37 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739097580; cv=pass; b=WjQWnqFrZMATXGHstGffNXD+HTr5vIG04UgsXcu6yTajabS02pvUpKxc3ABTx0/WkyA0Iq9gZeiGTl1bGLkCSyQIpU6hVst3FrqTrKeRNV07sjiTxOalxZjGHfQvDuXI5SMlj5Dg5g7FPI8YRwpGhtePfJdCyJUCrT2769tfiL0= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739097580; c=relaxed/simple; bh=GdmfCLxoBTTsWWhKlaVHIqC0kMSMOQIhQ7nns+Yvp3c=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=gmpwBtb2jjX7oFSKocGi3f+fRMycisRjyQyjIiEFOZqQHuFU7PvNLBHHRceRr7dxCqKvrMO9hfQ5vzSYp97Y27JRIEey6HXdKlhuucHTWgDXC3LC4Pt666W/UGnMSbL4lYosXunDQPx1BeAjXCX+aSlyPxUJ4MHdG0wJu11ZpzM= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=iki.fi; spf=pass smtp.mailfrom=iki.fi; dkim=pass (2048-bit key) header.d=iki.fi header.i=@iki.fi header.b=YUKNwdDM; arc=pass smtp.client-ip=185.185.170.37 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=iki.fi Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=iki.fi Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=iki.fi header.i=@iki.fi header.b="YUKNwdDM" Received: from monolith.lan (unknown [193.138.7.198]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: pav) by lahtoruutu.iki.fi (Postfix) with ESMTPSA id 4YrPN1551zz49Q6m; Sun, 9 Feb 2025 12:39:29 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=iki.fi; s=lahtoruutu; t=1739097571; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=ljeP4J7Llgjb8lL8F5o81ZU31nRmmAf2Q3QTjVlg3bQ=; b=YUKNwdDM1WKMOZyRwoTBNSg3+ca9lTG9+McVqmJIGOg9rXH/s/PGzdMgylZubO416R4r0z RsRz+hhbVR9rSIe3Nfo8+osU8cvwR4HVimiAVKXAW78G4AWB8F9zjTYad78I7AekM2dZYj oP88fHbnj7uqAqg2Kz01NASOC76IgYZz4MqOs8iP5n4cpvMQs8DdG83pCfkbKMsGGfrL/s HEGQrgg8U+fAnC7TykR7yUBhH6IXmuuE0TAU4sY9h8ZkIJMYJUrW0RUnmDARWh94WTRiG6 480n4/FgjFcjlB5O3Gx9doOu/akg1L2hUs9cw0rvuc5lthGMsb/l7PzazcY72A== ARC-Seal: i=1; s=lahtoruutu; d=iki.fi; t=1739097571; a=rsa-sha256; cv=none; b=fBwiOXG2T8IfxEmDA9lH6fOoNkw2dCN8Ja/BiYRXesCOKuc1wHAv/t1kklNUHC86p8kc6Y Xd/djGA027uxoKS7tNl6JoYoD3uNHuAFjFGpXHy3/dTK7Ht4mli4UJ4roUwKBH73z1aI4X I0D+NcFEewJwj7fx4yJa7PWHQdpqV99izZNRJhBV+EtJuWP+YpyKl5j3vG9gi8yq4xQknr YyRgwqEBP1Af8hFwg9VM+HHnPi2HZTb2FKuIZVEaj6AKvB+wxhQegBEzR2HV2uhUTzUVyy sqkfTN8cjUXVSMwanT0iuIA9fk7kRbRZN1a+sZUyCs1bxWD5xfwqmOZBfK1DIw== ARC-Authentication-Results: i=1; ORIGINATING; auth=pass smtp.auth=pav smtp.mailfrom=pav@iki.fi ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=iki.fi; s=lahtoruutu; t=1739097571; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=ljeP4J7Llgjb8lL8F5o81ZU31nRmmAf2Q3QTjVlg3bQ=; b=qF60aO3nglYg28V0dXxpIePIWtBC/cEf70aaQfQqDbXL1Kg0sXajosCBzuozxK8N/KGWuv +nXac/JREBUzIsA152dXZJgh4SUQnwWKbyHFAui0OrjwrNXji29z6WcNSRUPlLlSSURmwU mGi08+tp35MPR5Jl1cBGRODew1xzUYUO+lnVnrsUw6KCn8eE8cZibmPknXjH9OzDkS01Cl OOjQSu7fSDAqNqTICe7AeaJdGc61z/0s6CAev8OyIcl7kcaOb7R86KLbKZkIC8nVNKCpRF QzIREW4uDNoGDZkHx2NB7TtJX8AU5G6swj11FwKPFijt8QdAKX/zSL5xtx9EPw== From: Pauli Virtanen To: linux-bluetooth@vger.kernel.org Cc: Pauli Virtanen , Luiz Augusto von Dentz , netdev@vger.kernel.org, davem@davemloft.net, kuba@kernel.org, willemdebruijn.kernel@gmail.com Subject: [PATCH v3 1/5] net-timestamp: COMPLETION timestamp on packet tx completion Date: Sun, 9 Feb 2025 12:39:13 +0200 Message-ID: <71b88f509237bcce4139c152b3f624d7532047fd.1739097311.git.pav@iki.fi> X-Mailer: git-send-email 2.48.1 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-bluetooth@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Add SOF_TIMESTAMPING_TX_COMPLETION, for requesting a software timestamp when hardware reports a packet completed. Completion tstamp is useful for Bluetooth, where hardware tx timestamps cannot be obtained except for ISO packets, and the hardware has a queue where packets may wait. In this case the software SND timestamp only reflects the kernel-side part of the total latency (usually small) and queue length (usually 0 unless HW buffers congested), whereas the completion report time is more informative of the true latency. It may also be useful in other cases where HW TX timestamps cannot be obtained and user wants to estimate an upper bound to when the TX probably happened. Signed-off-by: Pauli Virtanen --- Documentation/networking/timestamping.rst | 9 +++++++++ include/linux/skbuff.h | 6 +++++- include/uapi/linux/errqueue.h | 1 + include/uapi/linux/net_tstamp.h | 6 ++++-- net/ethtool/common.c | 1 + net/socket.c | 3 +++ 6 files changed, 23 insertions(+), 3 deletions(-) diff --git a/Documentation/networking/timestamping.rst b/Documentation/networking/timestamping.rst index 61ef9da10e28..de2afed7a516 100644 --- a/Documentation/networking/timestamping.rst +++ b/Documentation/networking/timestamping.rst @@ -140,6 +140,15 @@ SOF_TIMESTAMPING_TX_ACK: cumulative acknowledgment. The mechanism ignores SACK and FACK. This flag can be enabled via both socket options and control messages. +SOF_TIMESTAMPING_TX_COMPLETION: + Request tx timestamps on packet tx completion. The completion + timestamp is generated by the kernel when it receives packet a + completion report from the hardware. Hardware may report multiple + packets at once, and completion timestamps reflect the timing of the + report and not actual tx time. The completion timestamps are + currently implemented only for: Bluetooth L2CAP and ISO. This + flag can be enabled via both socket options and control messages. + 1.3.2 Timestamp Reporting ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index bb2b751d274a..3707c9075ae9 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -489,10 +489,14 @@ enum { /* generate software time stamp when entering packet scheduling */ SKBTX_SCHED_TSTAMP = 1 << 6, + + /* generate software time stamp on packet tx completion */ + SKBTX_COMPLETION_TSTAMP = 1 << 7, }; #define SKBTX_ANY_SW_TSTAMP (SKBTX_SW_TSTAMP | \ - SKBTX_SCHED_TSTAMP) + SKBTX_SCHED_TSTAMP | \ + SKBTX_COMPLETION_TSTAMP) #define SKBTX_ANY_TSTAMP (SKBTX_HW_TSTAMP | \ SKBTX_HW_TSTAMP_USE_CYCLES | \ SKBTX_ANY_SW_TSTAMP) diff --git a/include/uapi/linux/errqueue.h b/include/uapi/linux/errqueue.h index 3c70e8ac14b8..1ea47309d772 100644 --- a/include/uapi/linux/errqueue.h +++ b/include/uapi/linux/errqueue.h @@ -73,6 +73,7 @@ enum { SCM_TSTAMP_SND, /* driver passed skb to NIC, or HW */ SCM_TSTAMP_SCHED, /* data entered the packet scheduler */ SCM_TSTAMP_ACK, /* data acknowledged by peer */ + SCM_TSTAMP_COMPLETION, /* packet tx completion */ }; #endif /* _UAPI_LINUX_ERRQUEUE_H */ diff --git a/include/uapi/linux/net_tstamp.h b/include/uapi/linux/net_tstamp.h index 55b0ab51096c..383213de612a 100644 --- a/include/uapi/linux/net_tstamp.h +++ b/include/uapi/linux/net_tstamp.h @@ -44,8 +44,9 @@ enum { SOF_TIMESTAMPING_BIND_PHC = (1 << 15), SOF_TIMESTAMPING_OPT_ID_TCP = (1 << 16), SOF_TIMESTAMPING_OPT_RX_FILTER = (1 << 17), + SOF_TIMESTAMPING_TX_COMPLETION = (1 << 18), - SOF_TIMESTAMPING_LAST = SOF_TIMESTAMPING_OPT_RX_FILTER, + SOF_TIMESTAMPING_LAST = SOF_TIMESTAMPING_TX_COMPLETION, SOF_TIMESTAMPING_MASK = (SOF_TIMESTAMPING_LAST - 1) | SOF_TIMESTAMPING_LAST }; @@ -58,7 +59,8 @@ enum { #define SOF_TIMESTAMPING_TX_RECORD_MASK (SOF_TIMESTAMPING_TX_HARDWARE | \ SOF_TIMESTAMPING_TX_SOFTWARE | \ SOF_TIMESTAMPING_TX_SCHED | \ - SOF_TIMESTAMPING_TX_ACK) + SOF_TIMESTAMPING_TX_ACK | \ + SOF_TIMESTAMPING_TX_COMPLETION) /** * struct so_timestamping - SO_TIMESTAMPING parameter diff --git a/net/ethtool/common.c b/net/ethtool/common.c index 2bd77c94f9f1..75e3b756012e 100644 --- a/net/ethtool/common.c +++ b/net/ethtool/common.c @@ -431,6 +431,7 @@ const char sof_timestamping_names[][ETH_GSTRING_LEN] = { [const_ilog2(SOF_TIMESTAMPING_BIND_PHC)] = "bind-phc", [const_ilog2(SOF_TIMESTAMPING_OPT_ID_TCP)] = "option-id-tcp", [const_ilog2(SOF_TIMESTAMPING_OPT_RX_FILTER)] = "option-rx-filter", + [const_ilog2(SOF_TIMESTAMPING_TX_COMPLETION)] = "completion-transmit", }; static_assert(ARRAY_SIZE(sof_timestamping_names) == __SOF_TIMESTAMPING_CNT); diff --git a/net/socket.c b/net/socket.c index 4afe31656a2b..22b7f6f50889 100644 --- a/net/socket.c +++ b/net/socket.c @@ -693,6 +693,9 @@ void __sock_tx_timestamp(__u32 tsflags, __u8 *tx_flags) if (tsflags & SOF_TIMESTAMPING_TX_SCHED) flags |= SKBTX_SCHED_TSTAMP; + if (tsflags & SOF_TIMESTAMPING_TX_COMPLETION) + flags |= SKBTX_COMPLETION_TSTAMP; + *tx_flags = flags; } EXPORT_SYMBOL(__sock_tx_timestamp); From patchwork Sun Feb 9 10:39:14 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pauli Virtanen X-Patchwork-Id: 863644 Received: from lahtoruutu.iki.fi (lahtoruutu.iki.fi [185.185.170.37]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6FA8818871F; Sun, 9 Feb 2025 10:39:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=pass smtp.client-ip=185.185.170.37 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739097582; cv=pass; b=JDG5ME0BHlbiXOPHtpYUkFsIIC4lJY05tFtHipBneXqRsAZlEtfEYohvfv8Ks5JIGCH7Kj86avvQpMANV45hZQ1yEgM58R7lIt5FEj6b/4K5E8ZSDGEwEVND1bdp46Bqynt+HxlKgdioGsh8tT0E/6eCMwQXvb/Br+Dw01YyTpw= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739097582; c=relaxed/simple; bh=GGlgHljJvU5OSW5Z+NrOKg0R63Nlx7t5/LdeLWRmc0E=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=jtjtsalqZ2pn/nbkZviLDJOmbwMsg84a1YDS7/TBXDcut1xlucoib2JjzIxzfjX6EvDKizElSagh4AqOQWvQvIcKgNplZ7q68Q0zAtm113uw5hCqPKbu+gOlpSeBazk/gfIqJ7fv1ImTCQe7xdB1QnBObU4Aq4FBkFNPj9GFs2Q= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=iki.fi; spf=pass smtp.mailfrom=iki.fi; dkim=pass (2048-bit key) header.d=iki.fi header.i=@iki.fi header.b=oyv8UY62; arc=pass smtp.client-ip=185.185.170.37 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=iki.fi Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=iki.fi Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=iki.fi header.i=@iki.fi header.b="oyv8UY62" Received: from monolith.lan (unknown [193.138.7.198]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: pav) by lahtoruutu.iki.fi (Postfix) with ESMTPSA id 4YrPN35cyTz49Q8f; Sun, 9 Feb 2025 12:39:31 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=iki.fi; s=lahtoruutu; t=1739097573; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=HD5NN7UschfyAn9AkZJEIsng2Wd5tpJPRq2qTqa1Qn4=; b=oyv8UY62berxYgCqjNIRXF1PCFtnfxBVR9fl5ynJPopNiqiDbwFKqjAjOATebyX49ypgKi 3LB4RkibbbWQBaZBHCSpI6YSqga0ZtcYYRJG+H9Fmb29W2q4YmcrlT0CsdwdguNrcqgtpL ZQZMeBHLaXlpnzZ37XBkC0n1jJ59ergssB2EZyqz2P4BQO72IIXQyEtVRQtkA0S4XQDzkQ M91PkE9ieGzm2eirmgduRsIVQwoelh7j3z0AxZiILixO/p1Rxv80xiOs7XcVHvkzIB2mX7 tA+F1uzj6ISsHTiUde++tSuOVSaxZa7n8mh+MezHn1fp4RG03rcH3JRe1S5BjQ== ARC-Seal: i=1; s=lahtoruutu; d=iki.fi; t=1739097573; a=rsa-sha256; cv=none; b=mcM0OxnEMkeJJYjTb1e6u2WlUHx1wbOdZQtNN2WzoRB86eWTX8HA9cb/Nch8ar2SYCrC3B 030TwUf5ec/vfFTQbfehgb/Nr5kOEc0pt9qaf5pzmE8UOEjiMw8hr04H843bTO3gwMKbD7 U51JCXCF3QMDISc6gCZ8uO9o6RDgkrQLL+Wi29Xdx7HXj94VOjvtFTPRN65b7HdXhkYiLD 7qYVbm4ZeaW3IuaKGMLZi3J9KLkj9sU3jTB7BdQR8YP5IEPTngZYKqZuqgHNNYMOviIuGR 3eMbhPOx53Y6QUc7RcfXLGtnmP148d1rAputo7hXro9GJxqaD6BOzckRcE5qMg== ARC-Authentication-Results: i=1; ORIGINATING; auth=pass smtp.auth=pav smtp.mailfrom=pav@iki.fi ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=iki.fi; s=lahtoruutu; t=1739097573; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=HD5NN7UschfyAn9AkZJEIsng2Wd5tpJPRq2qTqa1Qn4=; b=JipsX5z4iTWNV/MlveVkku30h97leIPCNSOz3TZbhhi1xze5F+pk0lS/3wOTV5u1131HhU IjQfXd5GKFW2WP9tYVSFNlXzJw+ZMsfDplKTQ5/fjZ/ik0kH9Ychujwln1ZqwCjagkLh3Z fubi5pTc/oRi34VrlzbAeKkQIRL33H6+jq/ZNIJAjJ58KbvcTnKTjdOKK90Hz9UD0szfLP SRvdPQmNzY7dOw4PQlKvsQZAkSKoMOnvDfs/xPI1wlhMRJpnffxIswZAeV2FjhO5yvcpPF Rn34yl/hzoeGav20zgBm5TzzwY8Q2qAToWubOXep/mV1Aml+MHPSsTMyy2gjGQ== From: Pauli Virtanen To: linux-bluetooth@vger.kernel.org Cc: Pauli Virtanen , Luiz Augusto von Dentz , netdev@vger.kernel.org, davem@davemloft.net, kuba@kernel.org, willemdebruijn.kernel@gmail.com Subject: [PATCH v3 2/5] Bluetooth: add support for skb TX SND/COMPLETION timestamping Date: Sun, 9 Feb 2025 12:39:14 +0200 Message-ID: <8a23a01e5d323df4907b5f5d08995d4bee86a391.1739097311.git.pav@iki.fi> X-Mailer: git-send-email 2.48.1 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-bluetooth@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Support enabling TX timestamping for some skbs, and track them until packet completion. Generate software SCM_TSTAMP_COMPLETION when getting completion report from hardware. Generate software SCM_TSTAMP_SND before sending to driver. Sending from driver requires changes in the driver API, and drivers mostly are going to send the skb immediately. Make the default situation with no COMPLETION TX timestamping more efficient by only counting packets in the queue when there is nothing to track. When there is something to track, we need to make clones, since the driver may modify sent skbs. The tx_q queue length is bounded by the hdev flow control, which will not send new packets before it has got completion reports for old ones. Signed-off-by: Pauli Virtanen --- include/net/bluetooth/hci_core.h | 13 ++++ net/bluetooth/hci_conn.c | 117 +++++++++++++++++++++++++++++++ net/bluetooth/hci_core.c | 17 +++-- net/bluetooth/hci_event.c | 4 ++ 4 files changed, 146 insertions(+), 5 deletions(-) diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 05919848ea95..1f539a9881ad 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -261,6 +261,12 @@ struct adv_info { struct delayed_work rpa_expired_cb; }; +struct tx_queue { + struct sk_buff_head queue; + unsigned int extra; + unsigned int tracked; +}; + #define HCI_MAX_ADV_INSTANCES 5 #define HCI_DEFAULT_ADV_DURATION 2 @@ -733,6 +739,8 @@ struct hci_conn { struct sk_buff_head data_q; struct list_head chan_list; + struct tx_queue tx_q; + struct delayed_work disc_work; struct delayed_work auto_accept_work; struct delayed_work idle_work; @@ -1571,6 +1579,11 @@ void hci_conn_enter_active_mode(struct hci_conn *conn, __u8 force_active); void hci_conn_failed(struct hci_conn *conn, u8 status); u8 hci_conn_set_handle(struct hci_conn *conn, u16 handle); +void hci_conn_tx_queue(struct hci_conn *conn, struct sk_buff *skb); +void hci_conn_tx_dequeue(struct hci_conn *conn); +void hci_setup_tx_timestamp(struct sk_buff *skb, size_t key_offset, + const struct sockcm_cookie *sockc); + /* * hci_conn_get() and hci_conn_put() are used to control the life-time of an * "hci_conn" object. They do not guarantee that the hci_conn object is running, diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index d097e308a755..e437290d8b70 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -27,6 +27,7 @@ #include #include +#include #include #include @@ -1002,6 +1003,7 @@ static struct hci_conn *__hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t } skb_queue_head_init(&conn->data_q); + skb_queue_head_init(&conn->tx_q.queue); INIT_LIST_HEAD(&conn->chan_list); INIT_LIST_HEAD(&conn->link_list); @@ -1155,6 +1157,7 @@ void hci_conn_del(struct hci_conn *conn) } skb_queue_purge(&conn->data_q); + skb_queue_purge(&conn->tx_q.queue); /* Remove the connection from the list and cleanup its remaining * state. This is a separate function since for some cases like @@ -3064,3 +3067,117 @@ int hci_abort_conn(struct hci_conn *conn, u8 reason) */ return hci_cmd_sync_run_once(hdev, abort_conn_sync, conn, NULL); } + +void hci_setup_tx_timestamp(struct sk_buff *skb, size_t key_offset, + const struct sockcm_cookie *sockc) +{ + struct sock *sk = skb ? skb->sk : NULL; + + /* This shall be called on a single skb of those generated by user + * sendmsg(), and only when the sendmsg() does not return error to + * user. This is required for keeping the tskey that increments here in + * sync with possible sendmsg() counting by user. + * + * Stream sockets shall set key_offset to sendmsg() length in bytes + * and call with the last fragment, others to 1 and first fragment. + */ + + if (!skb || !sockc || !sk || !key_offset) + return; + + sock_tx_timestamp(sk, sockc, &skb_shinfo(skb)->tx_flags); + + if (sockc->tsflags & SOF_TIMESTAMPING_OPT_ID && + sockc->tsflags & SOF_TIMESTAMPING_TX_RECORD_MASK) { + if (sockc->tsflags & SOCKCM_FLAG_TS_OPT_ID) { + skb_shinfo(skb)->tskey = sockc->ts_opt_id; + } else { + int key = atomic_add_return(key_offset, &sk->sk_tskey); + + skb_shinfo(skb)->tskey = key - 1; + } + } +} + +void hci_conn_tx_queue(struct hci_conn *conn, struct sk_buff *skb) +{ + struct tx_queue *comp = &conn->tx_q; + bool track = false; + + /* Emit SND now, ie. just before sending to driver */ + if (skb->sk && (skb_shinfo(skb)->tx_flags & SKBTX_SW_TSTAMP)) + __skb_tstamp_tx(skb, NULL, NULL, skb->sk, SCM_TSTAMP_SND); + + /* COMPLETION tstamp is emitted for tracked skb later in Number of + * Completed Packets event. Available only for flow controlled cases. + * + * TODO: SCO support (needs to be done in drivers) + */ + switch (conn->type) { + case ISO_LINK: + case ACL_LINK: + case LE_LINK: + break; + default: + return; + } + + if (skb->sk && (skb_shinfo(skb)->tx_flags & SKBTX_COMPLETION_TSTAMP)) + track = true; + + /* If nothing is tracked, just count extra skbs at the queue head */ + if (!track && !comp->tracked) { + comp->extra++; + return; + } + + if (track) { + skb = skb_clone_sk(skb); + if (!skb) + goto count_only; + + comp->tracked++; + } else { + skb = skb_clone(skb, GFP_KERNEL); + if (!skb) + goto count_only; + } + + skb_queue_tail(&comp->queue, skb); + return; + +count_only: + /* Stop tracking skbs, and only count. This will not emit timestamps for + * the packets, but if we get here something is more seriously wrong. + */ + comp->tracked = 0; + comp->extra += skb_queue_len(&comp->queue) + 1; + skb_queue_purge(&comp->queue); +} + +void hci_conn_tx_dequeue(struct hci_conn *conn) +{ + struct tx_queue *comp = &conn->tx_q; + struct sk_buff *skb; + + /* If there are tracked skbs, the counted extra go before dequeuing real + * skbs, to keep ordering. When nothing is tracked, the ordering doesn't + * matter so dequeue real skbs first to get rid of them ASAP. + */ + if (comp->extra && (comp->tracked || skb_queue_empty(&comp->queue))) { + comp->extra--; + return; + } + + skb = skb_dequeue(&comp->queue); + if (!skb) + return; + + if (skb->sk) { + comp->tracked--; + __skb_tstamp_tx(skb, NULL, NULL, skb->sk, + SCM_TSTAMP_COMPLETION); + } + + kfree_skb(skb); +} diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index e7ec12437c8b..e0845188f626 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -3025,6 +3025,13 @@ static int hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb) return 0; } +static int hci_send_conn_frame(struct hci_dev *hdev, struct hci_conn *conn, + struct sk_buff *skb) +{ + hci_conn_tx_queue(conn, skb); + return hci_send_frame(hdev, skb); +} + /* Send HCI command */ int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, const void *param) @@ -3562,7 +3569,7 @@ static void hci_sched_sco(struct hci_dev *hdev) while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, "e))) { while (quote-- && (skb = skb_dequeue(&conn->data_q))) { BT_DBG("skb %p len %d", skb, skb->len); - hci_send_frame(hdev, skb); + hci_send_conn_frame(hdev, conn, skb); conn->sent++; if (conn->sent == ~0) @@ -3586,7 +3593,7 @@ static void hci_sched_esco(struct hci_dev *hdev) "e))) { while (quote-- && (skb = skb_dequeue(&conn->data_q))) { BT_DBG("skb %p len %d", skb, skb->len); - hci_send_frame(hdev, skb); + hci_send_conn_frame(hdev, conn, skb); conn->sent++; if (conn->sent == ~0) @@ -3620,7 +3627,7 @@ static void hci_sched_acl_pkt(struct hci_dev *hdev) hci_conn_enter_active_mode(chan->conn, bt_cb(skb)->force_active); - hci_send_frame(hdev, skb); + hci_send_conn_frame(hdev, chan->conn, skb); hdev->acl_last_tx = jiffies; hdev->acl_cnt--; @@ -3676,7 +3683,7 @@ static void hci_sched_le(struct hci_dev *hdev) skb = skb_dequeue(&chan->data_q); - hci_send_frame(hdev, skb); + hci_send_conn_frame(hdev, chan->conn, skb); hdev->le_last_tx = jiffies; (*cnt)--; @@ -3710,7 +3717,7 @@ static void hci_sched_iso(struct hci_dev *hdev) while (*cnt && (conn = hci_low_sent(hdev, ISO_LINK, "e))) { while (quote-- && (skb = skb_dequeue(&conn->data_q))) { BT_DBG("skb %p len %d", skb, skb->len); - hci_send_frame(hdev, skb); + hci_send_conn_frame(hdev, conn, skb); conn->sent++; if (conn->sent == ~0) diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 2cc7a9306350..144b442180f7 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -4405,6 +4405,7 @@ static void hci_num_comp_pkts_evt(struct hci_dev *hdev, void *data, struct hci_comp_pkts_info *info = &ev->handles[i]; struct hci_conn *conn; __u16 handle, count; + unsigned int i; handle = __le16_to_cpu(info->handle); count = __le16_to_cpu(info->count); @@ -4415,6 +4416,9 @@ static void hci_num_comp_pkts_evt(struct hci_dev *hdev, void *data, conn->sent -= count; + for (i = 0; i < count; ++i) + hci_conn_tx_dequeue(conn); + switch (conn->type) { case ACL_LINK: hdev->acl_cnt += count; From patchwork Sun Feb 9 10:39:15 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pauli Virtanen X-Patchwork-Id: 863646 Received: from lahtoruutu.iki.fi (lahtoruutu.iki.fi [185.185.170.37]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 68A5A13BC0C; Sun, 9 Feb 2025 10:39:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=pass smtp.client-ip=185.185.170.37 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739097579; cv=pass; b=rFA8aZflPOa9Q7YVnMQbYguTKQWsyztY+/bd1qjPnQVDT7DL6/W6dxkOSXiciOJ45GpMo7PFHjZb9KE4JiVoQGbTkJs2kjB8nG+aYNw11TiJUrNkK3dhMN1CX0KdjtkIOwWpAXb2AXEothYnB21JOR2yGIyaV0tEjfkcS7UKi7Q= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739097579; c=relaxed/simple; bh=YgFPnBlAjdJ7kKacFYw8oZRvMTNxV7hsmxrUOCel/Lo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=BmHpw1ej1U6N9Atr4akCLdv23OkEnsoZBKumtQ6mvyikiZdtzOQiAHIeJs+ycZ4RpuwbSUvpMJ//xNJO3jRhketfUBef//qg2F2CP0xOGsm1pTLy9Je301rSmf7q5en+9BXq/Sdk5JN72LSd5KPgsi60YI/t8/BbvVIJWUyD0+w= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=iki.fi; spf=pass smtp.mailfrom=iki.fi; dkim=pass (2048-bit key) header.d=iki.fi header.i=@iki.fi header.b=bOQQMdeL; arc=pass smtp.client-ip=185.185.170.37 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=iki.fi Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=iki.fi Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=iki.fi header.i=@iki.fi header.b="bOQQMdeL" Received: from monolith.lan (unknown [193.138.7.198]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: pav) by lahtoruutu.iki.fi (Postfix) with ESMTPSA id 4YrPN54dZ1z49Q94; Sun, 9 Feb 2025 12:39:33 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=iki.fi; s=lahtoruutu; t=1739097575; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=SDcfYIgWirj2irWZu5yqgLL8XZKsytvOPvE0gOE+0Zo=; b=bOQQMdeLHu8LqkFERaAs3xneQMfUftMZzsN9x1nwF1FfsJoetyIhwHVdmR86oJjftbOeKr 3j/2LYjhC7ymKUL6My768kiSehEoqbi0+kSirK6aPRTn9Z+4Ee4uoyCF5KMCfhzogjMwH5 upRt+JlPLHLdX/B9q514b8gBc5kH7ekEd2cvdQ33LgzPRYYLIAEV5w+PlfTvU9y5dMsln6 dbAl9UTZGEtIXSDUguz9daG0YxW69Vk/oeiw9+wPByGyS2Zrz/eZjrfgN1RxKw6uZzJC0M 9eBY75EBUm6CMHTvhq6+AidmLTkX1HKzWZL88fDHkZTNCJmsHWiZwKlRsvWRTw== ARC-Seal: i=1; s=lahtoruutu; d=iki.fi; t=1739097575; a=rsa-sha256; cv=none; b=KOl7Bf01802qaKjP55YzcYhdxlmDgIzGPjTLXM+pBFSIIE4hFoD8MHRObnfGUw7IvJuGVk y7z5HWfFC2VM2wEvafhoCysCUDVk3Xvny4VuvgSxFGLLqM2YFdJI0KqZ+2YwOZYN/pQZdM hOIuavXyz4jMI11cg9yDroreY+UzDr8xdB/HtOU5rffgtKnmCUVDqr9Vl/257Fu4NWoGqd IJLf6+WcDJAysmOCWtBvefNhx3U6+mpxp1hTVEJT72MoAwfqMu4k38ds8jLKcEl1HW/xdz hHDfdp3Rf8fddLK3MnvUYc7DaUSwJPjXaKrLnOZJkFzxx2FNq6jB8Me0Rg9UeQ== ARC-Authentication-Results: i=1; ORIGINATING; auth=pass smtp.auth=pav smtp.mailfrom=pav@iki.fi ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=iki.fi; s=lahtoruutu; t=1739097575; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=SDcfYIgWirj2irWZu5yqgLL8XZKsytvOPvE0gOE+0Zo=; b=lZ1kN3rq4LzA/HJ0Q4iT6EDJUJ02hDsTkyx3dmhxehPhshzhdKOvbl+R+YlHsIZ2yTbUWv EmAc70t+GUDFh4vYOiPdD4QhyX2v+63qRdBp+qTVJk5RIMqX5O6wSqntjlPHx03bkqfLlZ 3CeB+5dcZC/xwaO1JKzja6uLekrIPzbsx6VP+9tOcH/rXLRSbZSVqf0REpODgQT5Dz7mZ3 kPOGI+CQ4k9BK1PY0jiAOwqr/ZP4GrU4z13PWgdNXg441KeOVR79Z4FQhLcmCJJR/i6sWD J2mR2ZOxVz8D77RPszvhO32pgaSEy0l4qGNE1HcNmV01QVdkkT/2HHDkTgmRsw== From: Pauli Virtanen To: linux-bluetooth@vger.kernel.org Cc: Pauli Virtanen , Luiz Augusto von Dentz , netdev@vger.kernel.org, davem@davemloft.net, kuba@kernel.org, willemdebruijn.kernel@gmail.com Subject: [PATCH v3 3/5] Bluetooth: ISO: add TX timestamping Date: Sun, 9 Feb 2025 12:39:15 +0200 Message-ID: X-Mailer: git-send-email 2.48.1 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-bluetooth@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Add BT_SCM_ERROR socket CMSG type. Support TX timestamping in ISO sockets. Support MSG_ERRQUEUE in ISO recvmsg. If a packet from sendmsg() is fragmented, only the first ACL fragment is timestamped. Signed-off-by: Pauli Virtanen --- include/net/bluetooth/bluetooth.h | 1 + net/bluetooth/iso.c | 24 ++++++++++++++++++++---- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h index 435250c72d56..bbefde319f95 100644 --- a/include/net/bluetooth/bluetooth.h +++ b/include/net/bluetooth/bluetooth.h @@ -156,6 +156,7 @@ struct bt_voice { #define BT_PKT_STATUS 16 #define BT_SCM_PKT_STATUS 0x03 +#define BT_SCM_ERROR 0x04 #define BT_ISO_QOS 17 diff --git a/net/bluetooth/iso.c b/net/bluetooth/iso.c index 44acddf58a0c..f497759a2af5 100644 --- a/net/bluetooth/iso.c +++ b/net/bluetooth/iso.c @@ -518,7 +518,8 @@ static struct bt_iso_qos *iso_sock_get_qos(struct sock *sk) return &iso_pi(sk)->qos; } -static int iso_send_frame(struct sock *sk, struct sk_buff *skb) +static int iso_send_frame(struct sock *sk, struct sk_buff *skb, + const struct sockcm_cookie *sockc) { struct iso_conn *conn = iso_pi(sk)->conn; struct bt_iso_qos *qos = iso_sock_get_qos(sk); @@ -538,10 +539,12 @@ 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) + if (sk->sk_state == BT_CONNECTED) { + hci_setup_tx_timestamp(skb, 1, sockc); hci_send_iso(conn->hcon, skb); - else + } else { len = -ENOTCONN; + } return len; } @@ -1348,6 +1351,7 @@ static int iso_sock_sendmsg(struct socket *sock, struct msghdr *msg, { struct sock *sk = sock->sk; struct sk_buff *skb, **frag; + struct sockcm_cookie sockc; size_t mtu; int err; @@ -1360,6 +1364,14 @@ static int iso_sock_sendmsg(struct socket *sock, struct msghdr *msg, if (msg->msg_flags & MSG_OOB) return -EOPNOTSUPP; + sockcm_init(&sockc, sk); + + if (msg->msg_controllen) { + err = sock_cmsg_send(sk, msg, &sockc); + if (err) + return err; + } + lock_sock(sk); if (sk->sk_state != BT_CONNECTED) { @@ -1405,7 +1417,7 @@ static int iso_sock_sendmsg(struct socket *sock, struct msghdr *msg, lock_sock(sk); if (sk->sk_state == BT_CONNECTED) - err = iso_send_frame(sk, skb); + err = iso_send_frame(sk, skb, &sockc); else err = -ENOTCONN; @@ -1474,6 +1486,10 @@ static int iso_sock_recvmsg(struct socket *sock, struct msghdr *msg, BT_DBG("sk %p", sk); + if (unlikely(flags & MSG_ERRQUEUE)) + return sock_recv_errqueue(sk, msg, len, SOL_BLUETOOTH, + BT_SCM_ERROR); + if (test_and_clear_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) { sock_hold(sk); lock_sock(sk); From patchwork Sun Feb 9 10:39:16 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pauli Virtanen X-Patchwork-Id: 863645 Received: from lahtoruutu.iki.fi (lahtoruutu.iki.fi [185.185.170.37]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C44E014B086; Sun, 9 Feb 2025 10:39:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=pass smtp.client-ip=185.185.170.37 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739097580; cv=pass; b=i3UNB36NGfo6tZsBrbxT0+ih90WzhAp+uQchd0FAZU/GgabnoX7q4tMNhe8qkBMEGttQ9olSosGwYioAqnNPSrN3kPfx1kULw5xD4ccAY201r83+GHQ9wHRhb8dBpGGeV3vTHvZSc8zkBWtx9EIn2bdHFzOPS3qNklzAb9hx0Qg= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739097580; c=relaxed/simple; bh=yq+PxtCT1XEqM2tclX7zRW5AebbnVCT6qrTXaMIFDwQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=SE4yfdeYg5NICWaFXi60Jar8j5cXXL9LV5dB9dMI2I/2ur3YU0bdvj8E9McowWfBQh085qrT7Szymfnis/s796xiEkF0xRvZAeIiQLNVom/xNTlBAPKlrbpsRZXwLzY+DkvMg37LdGEjZGBKmftbhd1K6mUwNBGrgoaojNKqm70= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=iki.fi; spf=pass smtp.mailfrom=iki.fi; dkim=pass (2048-bit key) header.d=iki.fi header.i=@iki.fi header.b=dgIVmwdJ; arc=pass smtp.client-ip=185.185.170.37 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=iki.fi Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=iki.fi Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=iki.fi header.i=@iki.fi header.b="dgIVmwdJ" Received: from monolith.lan (unknown [193.138.7.198]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: pav) by lahtoruutu.iki.fi (Postfix) with ESMTPSA id 4YrPN74Y20z49Q9m; Sun, 9 Feb 2025 12:39:35 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=iki.fi; s=lahtoruutu; t=1739097577; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=cLdvqv6OII/Bb6c0yRVH3trjPIx8DvbHtZaJMHiBODQ=; b=dgIVmwdJqilunSC/MxUjdUPwD9LYyPLvB0SeZ190DNw/be3m0GExe9fD/X7QFeU6XakExH zzlM4YO9QVYe516cDvnRtLAoEIiDt6xFmuq/u621wF4cTtcNH4mFYVOfMA5JEgQOJ+fGeE 1OWaZtK4iWzezi/p3UuiNadD0kSZsDUWI66nowOONARe/0OHbyJeFb8ULnSeGy1X77qTQ6 fAOw9Q4Uav3JRAjIIx3xNI8AU7sZL67TDSQlXDA08u1r6i54t53Ldil3vVsJH0haZobyEE kOOCW0GWXpyPNcbO89NYHgcqKy1o7SOcKgIHNfWG9YMcbXX9UrIGeLynPNDpeA== ARC-Seal: i=1; s=lahtoruutu; d=iki.fi; t=1739097577; a=rsa-sha256; cv=none; b=Lgedlsximf7oDGtAMh0DDjmvkY3YkUFKcLh9ierCHese8xjLt5mBKYFfE5SOIkSSFJVKyq KfqOOyaoYdesVBOFsXq+jNezirthCaZtdLXI35cyTmRRuQMiwhETUXK2dUOsPavP+lgIKL nzE9Ltfyi0IU2/aGVT6rmtgXUBlUBRwuWYmQNOHOqz3+wraWryVgTXb79hb2rvhTnlqcAX InblwU/5J1vl2IGZmLUJAt/qKFu0cQ47YDjTy8jMI/9+B8iBU+Qw9kjbhycO2Xi2+utOP4 55hEj+1hMpLiUuBiVI55P2KtnYe5Gh5LjckJJ/2MmagGV+vlhkIEpUOHMKF62g== ARC-Authentication-Results: i=1; ORIGINATING; auth=pass smtp.auth=pav smtp.mailfrom=pav@iki.fi ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=iki.fi; s=lahtoruutu; t=1739097577; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=cLdvqv6OII/Bb6c0yRVH3trjPIx8DvbHtZaJMHiBODQ=; b=SoRfRp/xcwmsXuYs61sF0VdMF6I/fraYCcm3kSisFLoZ6ZgiGb6Rt1rE7oxnGxVg4mwjLf OGRlgtkxU4pKECq0dyPZqRZl1NIFV4rXkBm+hZWi4HmAcgeTq61gahHgtzJCQAmo+RtbQ0 18EsO6pK4GlqpHF4SvjTjjE+1cME61Ap5AaTBrgLBABOAL8cQKHimv8mJJCxICvWTTV0DK nF/oqAodpSuizgAzdG1HN0lYvd7RGP3hUrJb003GLi4QnLt4GlQI4AWKhS8sehzzhgjY8X UnXvDewEDWvjPLBP9gau0kNHupiFkZIyuuqzcJaEwSW7PPDmDUiOKtx9B2QWgQ== From: Pauli Virtanen To: linux-bluetooth@vger.kernel.org Cc: Pauli Virtanen , Luiz Augusto von Dentz , netdev@vger.kernel.org, davem@davemloft.net, kuba@kernel.org, willemdebruijn.kernel@gmail.com Subject: [PATCH v3 4/5] Bluetooth: L2CAP: add TX timestamping Date: Sun, 9 Feb 2025 12:39:16 +0200 Message-ID: <815b26d1780ee04095aaeff4f0d43e57b50d1a3f.1739097311.git.pav@iki.fi> X-Mailer: git-send-email 2.48.1 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-bluetooth@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Support TX timestamping in L2CAP sockets. Support MSG_ERRQUEUE recvmsg. For other than SOCK_STREAM L2CAP sockets, if a packet from sendmsg() is fragmented, only the first ACL fragment is timestamped. For SOCK_STREAM L2CAP sockets, use the bytestream convention and timestamp the last fragment and count bytes in tskey. Timestamps are not generated in the Enhanced Retransmission mode, as meaning of COMPLETION stamp is unclear if L2CAP layer retransmits. Signed-off-by: Pauli Virtanen --- include/net/bluetooth/l2cap.h | 3 ++- net/bluetooth/6lowpan.c | 2 +- net/bluetooth/l2cap_core.c | 41 ++++++++++++++++++++++++++++++++--- net/bluetooth/l2cap_sock.c | 15 ++++++++++++- net/bluetooth/smp.c | 2 +- 5 files changed, 56 insertions(+), 7 deletions(-) diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index 9189354c568f..00e182a22720 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -955,7 +955,8 @@ void l2cap_chan_close(struct l2cap_chan *chan, int reason); int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, bdaddr_t *dst, u8 dst_type, u16 timeout); int l2cap_chan_reconfigure(struct l2cap_chan *chan, __u16 mtu); -int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len); +int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len, + const struct sockcm_cookie *sockc); void l2cap_chan_busy(struct l2cap_chan *chan, int busy); void l2cap_chan_rx_avail(struct l2cap_chan *chan, ssize_t rx_avail); int l2cap_chan_check_security(struct l2cap_chan *chan, bool initiator); diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c index 50cfec8ccac4..0eb1ecb54105 100644 --- a/net/bluetooth/6lowpan.c +++ b/net/bluetooth/6lowpan.c @@ -443,7 +443,7 @@ static int send_pkt(struct l2cap_chan *chan, struct sk_buff *skb, memset(&msg, 0, sizeof(msg)); iov_iter_kvec(&msg.msg_iter, ITER_SOURCE, &iv, 1, skb->len); - err = l2cap_chan_send(chan, &msg, skb->len); + err = l2cap_chan_send(chan, &msg, skb->len, NULL); if (err > 0) { netdev->stats.tx_bytes += err; netdev->stats.tx_packets++; diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 6cdc1dc3a7f9..6865a0f51df5 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -2514,7 +2514,33 @@ static void l2cap_le_flowctl_send(struct l2cap_chan *chan) skb_queue_len(&chan->tx_q)); } -int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len) +static void l2cap_tx_timestamp(struct sk_buff *skb, + const struct sockcm_cookie *sockc, + size_t len) +{ + struct sock *sk = skb ? skb->sk : NULL; + + if (sk && sk->sk_type == SOCK_STREAM) + hci_setup_tx_timestamp(skb, len, sockc); + else + hci_setup_tx_timestamp(skb, 1, sockc); +} + +static void l2cap_tx_timestamp_seg(struct sk_buff_head *queue, + const struct sockcm_cookie *sockc, + size_t len) +{ + struct sk_buff *skb = skb_peek(queue); + struct sock *sk = skb ? skb->sk : NULL; + + if (sk && sk->sk_type == SOCK_STREAM) + l2cap_tx_timestamp(skb_peek_tail(queue), sockc, len); + else + l2cap_tx_timestamp(skb, sockc, len); +} + +int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len, + const struct sockcm_cookie *sockc) { struct sk_buff *skb; int err; @@ -2529,6 +2555,8 @@ int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len) if (IS_ERR(skb)) return PTR_ERR(skb); + l2cap_tx_timestamp(skb, sockc, len); + l2cap_do_send(chan, skb); return len; } @@ -2552,6 +2580,8 @@ int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len) if (err) return err; + l2cap_tx_timestamp_seg(&seg_queue, sockc, len); + skb_queue_splice_tail_init(&seg_queue, &chan->tx_q); l2cap_le_flowctl_send(chan); @@ -2573,6 +2603,8 @@ int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len) if (IS_ERR(skb)) return PTR_ERR(skb); + l2cap_tx_timestamp(skb, sockc, len); + l2cap_do_send(chan, skb); err = len; break; @@ -2596,10 +2628,13 @@ int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len) if (err) break; - if (chan->mode == L2CAP_MODE_ERTM) + if (chan->mode == L2CAP_MODE_ERTM) { + /* TODO: ERTM mode timestamping */ l2cap_tx(chan, NULL, &seg_queue, L2CAP_EV_DATA_REQUEST); - else + } else { + l2cap_tx_timestamp_seg(&seg_queue, sockc, len); l2cap_streaming_send(chan, &seg_queue); + } err = len; diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index acd11b268b98..92305530e2e5 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c @@ -1106,6 +1106,7 @@ static int l2cap_sock_sendmsg(struct socket *sock, struct msghdr *msg, { struct sock *sk = sock->sk; struct l2cap_chan *chan = l2cap_pi(sk)->chan; + struct sockcm_cookie sockc; int err; BT_DBG("sock %p, sk %p", sock, sk); @@ -1120,6 +1121,14 @@ static int l2cap_sock_sendmsg(struct socket *sock, struct msghdr *msg, if (sk->sk_state != BT_CONNECTED) return -ENOTCONN; + sockcm_init(&sockc, sk); + + if (msg->msg_controllen) { + err = sock_cmsg_send(sk, msg, &sockc); + if (err) + return err; + } + lock_sock(sk); err = bt_sock_wait_ready(sk, msg->msg_flags); release_sock(sk); @@ -1127,7 +1136,7 @@ static int l2cap_sock_sendmsg(struct socket *sock, struct msghdr *msg, return err; l2cap_chan_lock(chan); - err = l2cap_chan_send(chan, msg, len); + err = l2cap_chan_send(chan, msg, len, &sockc); l2cap_chan_unlock(chan); return err; @@ -1168,6 +1177,10 @@ static int l2cap_sock_recvmsg(struct socket *sock, struct msghdr *msg, struct l2cap_pinfo *pi = l2cap_pi(sk); int err; + if (unlikely(flags & MSG_ERRQUEUE)) + return sock_recv_errqueue(sk, msg, len, SOL_BLUETOOTH, + BT_SCM_ERROR); + lock_sock(sk); if (sk->sk_state == BT_CONNECT2 && test_bit(BT_SK_DEFER_SETUP, diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index 8b9724fd752a..f5e5c2f111b9 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c @@ -608,7 +608,7 @@ static void smp_send_cmd(struct l2cap_conn *conn, u8 code, u16 len, void *data) iov_iter_kvec(&msg.msg_iter, ITER_SOURCE, iv, 2, 1 + len); - l2cap_chan_send(chan, &msg, 1 + len); + l2cap_chan_send(chan, &msg, 1 + len, NULL); if (!chan->data) return; From patchwork Sun Feb 9 10:39:17 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pauli Virtanen X-Patchwork-Id: 863917 Received: from lahtoruutu.iki.fi (lahtoruutu.iki.fi [185.185.170.37]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8047D243370; Sun, 9 Feb 2025 10:39:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=pass smtp.client-ip=185.185.170.37 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739097582; cv=pass; b=NZDyEK+m49qZ6xvZ/JoSkf7Uf3N27dBV3FQl+zzdCcOt+ZjcizrIYf12/OjWHamJay/q4sdeqqlR1GndeeytmCWZkmEw70zEQlz/8dSYAdme7QN39OxqvaoYVOTGtZHgsPDf1w5DFW6UlfNJjHRtZ/1LrrlCYE5MnPVdAAoDSrU= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739097582; c=relaxed/simple; bh=pRj1P6xt5VnRUSC44/bBifRMJtk42pamaKar/KCrJDc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=cvZ2FZsVRFzyZKcWGaBW//p7cVUwCBt+XGKhqsLODORpvx5/7bfx4Vy/dTUSJ005QnSSMhDJFPqBRO6JtPGE5frQ+1VWtO/DFr9Rj6yx1WrSn4umpbPKVoBP9X98/AWVclasJy9ic8fqRPTwC02SHRzx4UikENRGSJ/LEiox6Dk= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=iki.fi; spf=pass smtp.mailfrom=iki.fi; dkim=pass (2048-bit key) header.d=iki.fi header.i=@iki.fi header.b=bj/k046j; arc=pass smtp.client-ip=185.185.170.37 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=iki.fi Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=iki.fi Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=iki.fi header.i=@iki.fi header.b="bj/k046j" Received: from monolith.lan (unknown [193.138.7.198]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: pav) by lahtoruutu.iki.fi (Postfix) with ESMTPSA id 4YrPN93Xffz49QC9; Sun, 9 Feb 2025 12:39:37 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=iki.fi; s=lahtoruutu; t=1739097579; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=XIHlb2ApKngockyPdMNG31MC4jnN36aCmtwjnch4pHo=; b=bj/k046jp96fgsmejo4YCbJlc5FthrP7pJzba9cddr6jFYbc17bw70llsiIrbdbknHD5hW lo2MSFCQKKVD1ppXynxyh2tkL990yrwiNflrvdfhHn3gokeg88c4Y4VndEekkqSCwfGHIz TQk3ZVEFJKir3FYHXSCBA5YSoZqqEI+tqwr0XP506SQ8Np/iNieP13lDw9wBrwYabdK7Wn IyUQLsMLKGlEGejhF1VijeJmrrEDUNn5+Vmx2R0sSu8S/+6NzBP3wkYIlaCzX9u4vqI50s go0hCBu7u2HDy2qZ20EbYgOEOLSez7PFvlMlXunFvHp6xWJb2UX7oh4B3TBlQA== ARC-Seal: i=1; s=lahtoruutu; d=iki.fi; t=1739097578; a=rsa-sha256; cv=none; b=T/rGog2zmcnvO/Ud/IKdQolrBkqqxj8LGDNpJ7dS25oz+AFaSfidN6hAv1AlUeIvXTbLIz 5yiZjtk5z856xJiuKp/bdl7tL7jIG5o3rRIV5EMJKXK9ng4ZRdfs8cjrg8GdIdyqS+tUEK JkjS46aAjaQ01N241LpFErNHgk1/tRULMYAcwiymRBdN+mj9d80GfYmV4sWQ+HG9P7bMSv jr1gWFMvFngu9h5jHrKF4g3kOHymr5r/V02RV+9RyFV2EBR1PwwkGS6PelQ/6CP7VkFiAq P4wWBeZtnEfhhz06ErupR75IUn41rjByBdqMTiVWtvzVEGOu1He06yx4fZ8a5w== ARC-Authentication-Results: i=1; ORIGINATING; auth=pass smtp.auth=pav smtp.mailfrom=pav@iki.fi ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=iki.fi; s=lahtoruutu; t=1739097578; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=XIHlb2ApKngockyPdMNG31MC4jnN36aCmtwjnch4pHo=; b=gyCxm1rtXgkvgil/usJ5hBKXb04yosvg7xglCn7CZ0GCVFBlHL6gUq+GXro9khf6lmnHkX QjgtW9fOOIdvg7pX21y6UiQs2f7C/hJ2X8npEwRRxQETs+7U1EPZgSqF2CxTorCWFlfukE wPYchjPOyDScjMdANjo1BOFeiXK9AfnETj9JJ3eQN/kUjFCXG8V3u4BAXR87p1fI47xI4l y/5s7mWVFSHZV9Hphu6U4c/78Wd5scIRaKzMpFmwnHW2QUt3ISYSVjl+I+2hBFpFzVn++7 QcIK3zBvaRI/C3o/MkJVyWPJo9sD/bxydJTPBiRT8E5Ym6iJXGccfpkp0J//Mw== From: Pauli Virtanen To: linux-bluetooth@vger.kernel.org Cc: Pauli Virtanen , Luiz Augusto von Dentz , netdev@vger.kernel.org, davem@davemloft.net, kuba@kernel.org, willemdebruijn.kernel@gmail.com Subject: [PATCH v3 5/5] Bluetooth: SCO: add TX timestamping socket-level mechanism Date: Sun, 9 Feb 2025 12:39:17 +0200 Message-ID: <5e5ed3e5fd972b1f1f191045a890e5e23b8a1276.1739097311.git.pav@iki.fi> X-Mailer: git-send-email 2.48.1 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-bluetooth@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Support TX timestamping in SCO sockets. Support MSG_ERRQUEUE in SCO recvmsg. Signed-off-by: Pauli Virtanen --- net/bluetooth/sco.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index aa7bfe26cb40..f39c57ac594f 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c @@ -370,7 +370,8 @@ static int sco_connect(struct sock *sk) return err; } -static int sco_send_frame(struct sock *sk, struct sk_buff *skb) +static int sco_send_frame(struct sock *sk, struct sk_buff *skb, + const struct sockcm_cookie *sockc) { struct sco_conn *conn = sco_pi(sk)->conn; int len = skb->len; @@ -381,6 +382,7 @@ static int sco_send_frame(struct sock *sk, struct sk_buff *skb) BT_DBG("sk %p len %d", sk, len); + hci_setup_tx_timestamp(skb, 1, sockc); hci_send_sco(conn->hcon, skb); return len; @@ -776,6 +778,7 @@ static int sco_sock_sendmsg(struct socket *sock, struct msghdr *msg, { struct sock *sk = sock->sk; struct sk_buff *skb; + struct sockcm_cookie sockc; int err; BT_DBG("sock %p, sk %p", sock, sk); @@ -787,6 +790,14 @@ static int sco_sock_sendmsg(struct socket *sock, struct msghdr *msg, if (msg->msg_flags & MSG_OOB) return -EOPNOTSUPP; + sockcm_init(&sockc, sk); + + if (msg->msg_controllen) { + err = sock_cmsg_send(sk, msg, &sockc); + if (err) + return err; + } + skb = bt_skb_sendmsg(sk, msg, len, len, 0, 0); if (IS_ERR(skb)) return PTR_ERR(skb); @@ -794,7 +805,7 @@ static int sco_sock_sendmsg(struct socket *sock, struct msghdr *msg, lock_sock(sk); if (sk->sk_state == BT_CONNECTED) - err = sco_send_frame(sk, skb); + err = sco_send_frame(sk, skb, &sockc); else err = -ENOTCONN; @@ -860,6 +871,10 @@ static int sco_sock_recvmsg(struct socket *sock, struct msghdr *msg, struct sock *sk = sock->sk; struct sco_pinfo *pi = sco_pi(sk); + if (unlikely(flags & MSG_ERRQUEUE)) + return sock_recv_errqueue(sk, msg, len, SOL_BLUETOOTH, + BT_SCM_ERROR); + lock_sock(sk); if (sk->sk_state == BT_CONNECT2 &&