diff mbox series

[BlueZ,v2,1/2] audio: actually try to enable MTU auto-tuning

Message ID 20250129084950.41987-1-pchelkin@ispras.ru
State New
Headers show
Series [BlueZ,v2,1/2] audio: actually try to enable MTU auto-tuning | expand

Commit Message

Fedor Pchelkin Jan. 29, 2025, 8:49 a.m. UTC
A "0" for the input MTU passed to the underlying socket is supposed to
indicate that its value should be determined by the L2CAP layer.
However, the current code treats a zero imtu just as if there is
nothing to change.

Introduce an additional flag to indicate that the zero imtu is
explicitly requested by the caller for the purpose of auto-tuning.
Otherwise, the similar behavior remains.

Found by Linux Verification Center (linuxtesting.org).

Fixes: ae5be371a9f5 ("avdtp: Enable MTU auto tunning")
---
v1->v2: incorporate error handling in case the kernel still doesn't
support MTU auto-tuning

 btio/btio.c | 34 ++++++++++++++++++++++------------
 1 file changed, 22 insertions(+), 12 deletions(-)

Comments

Fedor Pchelkin Jan. 31, 2025, 11:16 a.m. UTC | #1
On Thu, 30. Jan 12:51, Luiz Augusto von Dentz wrote:
> > Here is the summary with links:
> >   - [BlueZ,v2,1/2] audio: actually try to enable MTU auto-tuning
> >     (no matching commit)
> 
> Ive done quite a few modifications to the above change, so instead of
> using a auto_mtu it now checks if -1 for not set, Ive checked with a
> couple headsets I have and it seem to work fine but perhaps you want
> to check as well just to make sure I didn't screw something up.

It works okay for my setup, too. Thanks!
diff mbox series

Patch

diff --git a/btio/btio.c b/btio/btio.c
index 2d277e409..7b38bc819 100644
--- a/btio/btio.c
+++ b/btio/btio.c
@@ -66,6 +66,7 @@  struct set_opts {
 	uint16_t imtu;
 	uint16_t omtu;
 	int central;
+	uint8_t auto_mtu;
 	uint8_t mode;
 	int flushable;
 	uint32_t priority;
@@ -610,7 +611,7 @@  static uint8_t mode_l2mode(uint8_t mode)
 }
 
 static gboolean set_l2opts(int sock, uint16_t imtu, uint16_t omtu,
-						uint8_t mode, GError **err)
+				uint8_t auto_mtu, uint8_t mode, GError **err)
 {
 	struct l2cap_options l2o;
 	socklen_t len;
@@ -622,7 +623,7 @@  static gboolean set_l2opts(int sock, uint16_t imtu, uint16_t omtu,
 		return FALSE;
 	}
 
-	if (imtu)
+	if (imtu || auto_mtu)
 		l2o.imtu = imtu;
 	if (omtu)
 		l2o.omtu = omtu;
@@ -666,17 +667,24 @@  static gboolean set_le_mode(int sock, uint8_t mode, GError **err)
 }
 
 static gboolean l2cap_set(int sock, uint8_t src_type, int sec_level,
-				uint16_t imtu, uint16_t omtu, uint8_t mode,
-				int central, int flushable, uint32_t priority,
-				GError **err)
+				uint16_t imtu, uint16_t omtu, uint8_t auto_mtu,
+				uint8_t mode, int central, int flushable,
+				uint32_t priority, GError **err)
 {
-	if (imtu || omtu || mode) {
+	if (imtu || omtu || auto_mtu || mode) {
 		gboolean ret = FALSE;
 
-		if (src_type == BDADDR_BREDR)
-			ret = set_l2opts(sock, imtu, omtu, mode, err);
-		else {
-			if (imtu)
+		if (src_type == BDADDR_BREDR) {
+			ret = set_l2opts(sock, imtu, omtu, auto_mtu, mode, err);
+
+			/* Back to default behavior in case the first call fails:
+			 * it may happen if the used kernel still doesn't support
+			 * auto-tuning the MTU 
+			 */
+			if (!ret && auto_mtu)
+				ret = set_l2opts(sock, imtu, omtu, 0, mode, err);
+		} else {
+			if (imtu || auto_mtu)
 				ret = set_le_imtu(sock, imtu, err);
 
 			if (ret && mode)
@@ -986,6 +994,8 @@  static gboolean parse_set_opts(struct set_opts *opts, GError **err,
 			opts->imtu = va_arg(args, int);
 			if (!opts->mtu)
 				opts->mtu = opts->imtu;
+			if (!opts->imtu)
+				opts->auto_mtu = 1;
 			break;
 		case BT_IO_OPT_CENTRAL:
 			opts->central = va_arg(args, gboolean);
@@ -1890,7 +1900,7 @@  gboolean bt_io_set(GIOChannel *io, GError **err, BtIOOption opt1, ...)
 	switch (type) {
 	case BT_IO_L2CAP:
 		return l2cap_set(sock, opts.src_type, opts.sec_level, opts.imtu,
-					opts.omtu, opts.mode, opts.central,
+					opts.omtu, opts.auto_mtu, opts.mode, opts.central,
 					opts.flushable, opts.priority, err);
 	case BT_IO_RFCOMM:
 		return rfcomm_set(sock, opts.sec_level, opts.central, err);
@@ -1941,7 +1951,7 @@  static GIOChannel *create_io(gboolean server, struct set_opts *opts,
 				server ? opts->psm : 0, opts->cid, err) < 0)
 			goto failed;
 		if (!l2cap_set(sock, opts->src_type, opts->sec_level,
-				opts->imtu, opts->omtu, opts->mode,
+				opts->imtu, opts->omtu, opts->auto_mtu, opts->mode,
 				opts->central, opts->flushable, opts->priority,
 				err))
 			goto failed;