linux-bluetooth.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/3] Bluetooth: L2CAP: Improve credits logic
@ 2018-09-04 10:39 Luiz Augusto von Dentz
  2018-09-04 10:39 ` [PATCH v2 1/3] Bluetooth: L2CAP: Derive MPS from connection MTU Luiz Augusto von Dentz
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Luiz Augusto von Dentz @ 2018-09-04 10:39 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

These changes replace the existing threshold logic with a limpler logic
that gives back credits after receiving an SDU. It also removes the
debugfs entries to configure the MPS and credits with auto selected one
derived from the MTU and MPS.

v2: Account from the SDU length when adjusting the MPS.

Luiz Augusto von Dentz (3):
  Bluetooth: L2CAP: Derive MPS from connection MTU
  Bluetooth: L2CAP: Derive rx credits from MTU and MPS
  Bluetooth: L2CAP: Detect if remote is not able to use the whole MPS

 include/net/bluetooth/l2cap.h |  3 --
 net/bluetooth/l2cap_core.c    | 66 +++++++++++++++++++++++------------
 2 files changed, 44 insertions(+), 25 deletions(-)

-- 
2.17.1

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH v2 1/3] Bluetooth: L2CAP: Derive MPS from connection MTU
  2018-09-04 10:39 [PATCH v2 0/3] Bluetooth: L2CAP: Improve credits logic Luiz Augusto von Dentz
@ 2018-09-04 10:39 ` Luiz Augusto von Dentz
  2018-09-04 10:39 ` [PATCH v2 2/3] Bluetooth: L2CAP: Derive rx credits from MTU and MPS Luiz Augusto von Dentz
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Luiz Augusto von Dentz @ 2018-09-04 10:39 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

This ensures the MPS can fit in a single HCI fragment so each
segment don't have to be reassembled at HCI level, in addition to
that also remove the debugfs entry to configure the MPS.

Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
---
 include/net/bluetooth/l2cap.h |  1 -
 net/bluetooth/l2cap_core.c    | 14 +++++++-------
 2 files changed, 7 insertions(+), 8 deletions(-)

diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 0697fd413087..17296675a0b1 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -456,7 +456,6 @@ struct l2cap_conn_param_update_rsp {
 #define L2CAP_CONN_PARAM_REJECTED	0x0001
 
 #define L2CAP_LE_MAX_CREDITS		10
-#define L2CAP_LE_DEFAULT_MPS		230
 
 struct l2cap_le_conn_req {
 	__le16     psm;
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index d17a4736e47c..8a60db6261f7 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -52,7 +52,6 @@ static LIST_HEAD(chan_list);
 static DEFINE_RWLOCK(chan_list_lock);
 
 static u16 le_max_credits = L2CAP_LE_MAX_CREDITS;
-static u16 le_default_mps = L2CAP_LE_DEFAULT_MPS;
 
 static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
 				       u8 code, u8 ident, u16 dlen, void *data);
@@ -520,7 +519,8 @@ static void l2cap_le_flowctl_init(struct l2cap_chan *chan)
 	chan->sdu_len = 0;
 	chan->tx_credits = 0;
 	chan->rx_credits = le_max_credits;
-	chan->mps = min_t(u16, chan->imtu, le_default_mps);
+	/* Derive MPS from connection MTU to stop HCI fragmentation */
+	chan->mps = min_t(u16, chan->imtu, chan->conn->mtu - L2CAP_HDR_SIZE);
 
 	skb_queue_head_init(&chan->tx_q);
 }
@@ -1282,6 +1282,8 @@ static void l2cap_le_connect(struct l2cap_chan *chan)
 	if (test_and_set_bit(FLAG_LE_CONN_REQ_SENT, &chan->flags))
 		return;
 
+	l2cap_le_flowctl_init(chan);
+
 	req.psm     = chan->psm;
 	req.scid    = cpu_to_le16(chan->scid);
 	req.mtu     = cpu_to_le16(chan->imtu);
@@ -5493,8 +5495,6 @@ static int l2cap_le_connect_req(struct l2cap_conn *conn,
 		goto response_unlock;
 	}
 
-	l2cap_le_flowctl_init(chan);
-
 	bacpy(&chan->src, &conn->hcon->src);
 	bacpy(&chan->dst, &conn->hcon->dst);
 	chan->src_type = bdaddr_src_type(conn->hcon);
@@ -5506,6 +5506,9 @@ static int l2cap_le_connect_req(struct l2cap_conn *conn,
 	chan->tx_credits = __le16_to_cpu(req->credits);
 
 	__l2cap_chan_add(conn, chan);
+
+	l2cap_le_flowctl_init(chan);
+
 	dcid = chan->scid;
 	credits = chan->rx_credits;
 
@@ -7102,7 +7105,6 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
 	case L2CAP_MODE_BASIC:
 		break;
 	case L2CAP_MODE_LE_FLOWCTL:
-		l2cap_le_flowctl_init(chan);
 		break;
 	case L2CAP_MODE_ERTM:
 	case L2CAP_MODE_STREAMING:
@@ -7647,8 +7649,6 @@ int __init l2cap_init(void)
 
 	debugfs_create_u16("l2cap_le_max_credits", 0644, bt_debugfs,
 			   &le_max_credits);
-	debugfs_create_u16("l2cap_le_default_mps", 0644, bt_debugfs,
-			   &le_default_mps);
 
 	return 0;
 }
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v2 2/3] Bluetooth: L2CAP: Derive rx credits from MTU and MPS
  2018-09-04 10:39 [PATCH v2 0/3] Bluetooth: L2CAP: Improve credits logic Luiz Augusto von Dentz
  2018-09-04 10:39 ` [PATCH v2 1/3] Bluetooth: L2CAP: Derive MPS from connection MTU Luiz Augusto von Dentz
@ 2018-09-04 10:39 ` Luiz Augusto von Dentz
  2018-09-04 10:39 ` [PATCH v2 3/3] Bluetooth: L2CAP: Detect if remote is not able to use the whole MPS Luiz Augusto von Dentz
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Luiz Augusto von Dentz @ 2018-09-04 10:39 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

Give enough rx credits for a full packet instead of using an arbitrary
number which may not be enough depending on the MTU and MPS which can
cause interruptions while waiting for more credits, also remove
debugfs entry for l2cap_le_max_credits.

With these changes the credits are restored after each SDU is received
instead of using fixed threshold, this way it is garanteed that there
will always be enough credits to send a packet without waiting more
credits to arrive.

Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
---
 include/net/bluetooth/l2cap.h |  2 --
 net/bluetooth/l2cap_core.c    | 42 ++++++++++++++++++++++-------------
 2 files changed, 27 insertions(+), 17 deletions(-)

diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 17296675a0b1..3555440e14fc 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -455,8 +455,6 @@ struct l2cap_conn_param_update_rsp {
 #define L2CAP_CONN_PARAM_ACCEPTED	0x0000
 #define L2CAP_CONN_PARAM_REJECTED	0x0001
 
-#define L2CAP_LE_MAX_CREDITS		10
-
 struct l2cap_le_conn_req {
 	__le16     psm;
 	__le16     scid;
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 8a60db6261f7..3fb2d757df88 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -51,8 +51,6 @@ static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN | L2CAP_FEAT_UCD;
 static LIST_HEAD(chan_list);
 static DEFINE_RWLOCK(chan_list_lock);
 
-static u16 le_max_credits = L2CAP_LE_MAX_CREDITS;
-
 static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
 				       u8 code, u8 ident, u16 dlen, void *data);
 static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
@@ -518,9 +516,10 @@ static void l2cap_le_flowctl_init(struct l2cap_chan *chan)
 	chan->sdu_last_frag = NULL;
 	chan->sdu_len = 0;
 	chan->tx_credits = 0;
-	chan->rx_credits = le_max_credits;
 	/* Derive MPS from connection MTU to stop HCI fragmentation */
 	chan->mps = min_t(u16, chan->imtu, chan->conn->mtu - L2CAP_HDR_SIZE);
+	/* Give enough credits for a full packet */
+	chan->rx_credits = (chan->imtu / chan->mps) + 1;
 
 	skb_queue_head_init(&chan->tx_q);
 }
@@ -6702,13 +6701,10 @@ static void l2cap_chan_le_send_credits(struct l2cap_chan *chan)
 	struct l2cap_le_credits pkt;
 	u16 return_credits;
 
-	/* We return more credits to the sender only after the amount of
-	 * credits falls below half of the initial amount.
-	 */
-	if (chan->rx_credits >= (le_max_credits + 1) / 2)
-		return;
+	return_credits = ((chan->imtu / chan->mps) + 1) - chan->rx_credits;
 
-	return_credits = le_max_credits - chan->rx_credits;
+	if (!return_credits)
+		return;
 
 	BT_DBG("chan %p returning %u credits to sender", chan, return_credits);
 
@@ -6722,6 +6718,21 @@ static void l2cap_chan_le_send_credits(struct l2cap_chan *chan)
 	l2cap_send_cmd(conn, chan->ident, L2CAP_LE_CREDITS, sizeof(pkt), &pkt);
 }
 
+static int l2cap_le_recv(struct l2cap_chan *chan, struct sk_buff *skb)
+{
+	int err;
+
+	BT_DBG("SDU reassemble complete: chan %p skb->len %u", chan, skb->len);
+
+	/* Wait recv to confirm reception before updating the credits */
+	err = chan->ops->recv(chan, skb);
+
+	/* Update credits whenever an SDU is received */
+	l2cap_chan_le_send_credits(chan);
+
+	return err;
+}
+
 static int l2cap_le_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
 {
 	int err;
@@ -6740,7 +6751,11 @@ static int l2cap_le_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
 	chan->rx_credits--;
 	BT_DBG("rx_credits %u -> %u", chan->rx_credits + 1, chan->rx_credits);
 
-	l2cap_chan_le_send_credits(chan);
+	/* Update if remote had run out of credits, this should only happens
+	 * if the remote is not using the entire MPS.
+	 */
+	if (!chan->rx_credits)
+		l2cap_chan_le_send_credits(chan);
 
 	err = 0;
 
@@ -6766,7 +6781,7 @@ static int l2cap_le_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
 		}
 
 		if (skb->len == sdu_len)
-			return chan->ops->recv(chan, skb);
+			return l2cap_le_recv(chan, skb);
 
 		chan->sdu = skb;
 		chan->sdu_len = sdu_len;
@@ -6788,7 +6803,7 @@ static int l2cap_le_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
 	skb = NULL;
 
 	if (chan->sdu->len == chan->sdu_len) {
-		err = chan->ops->recv(chan, chan->sdu);
+		err = l2cap_le_recv(chan, chan->sdu);
 		if (!err) {
 			chan->sdu = NULL;
 			chan->sdu_last_frag = NULL;
@@ -7647,9 +7662,6 @@ int __init l2cap_init(void)
 	l2cap_debugfs = debugfs_create_file("l2cap", 0444, bt_debugfs,
 					    NULL, &l2cap_debugfs_fops);
 
-	debugfs_create_u16("l2cap_le_max_credits", 0644, bt_debugfs,
-			   &le_max_credits);
-
 	return 0;
 }
 
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v2 3/3] Bluetooth: L2CAP: Detect if remote is not able to use the whole MPS
  2018-09-04 10:39 [PATCH v2 0/3] Bluetooth: L2CAP: Improve credits logic Luiz Augusto von Dentz
  2018-09-04 10:39 ` [PATCH v2 1/3] Bluetooth: L2CAP: Derive MPS from connection MTU Luiz Augusto von Dentz
  2018-09-04 10:39 ` [PATCH v2 2/3] Bluetooth: L2CAP: Derive rx credits from MTU and MPS Luiz Augusto von Dentz
@ 2018-09-04 10:39 ` Luiz Augusto von Dentz
  2018-09-20  9:26 ` [PATCH v2 0/3] Bluetooth: L2CAP: Improve credits logic Luiz Augusto von Dentz
  2018-09-27 10:52 ` Marcel Holtmann
  4 siblings, 0 replies; 6+ messages in thread
From: Luiz Augusto von Dentz @ 2018-09-04 10:39 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

If the remote is not able to fully utilize the MPS choosen recalculate
the credits based on the actual amount it is sending that way it can
still send packets of MTU size without credits dropping to 0.

Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
---
 net/bluetooth/l2cap_core.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 3fb2d757df88..514899f7f0d4 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -6787,6 +6787,16 @@ static int l2cap_le_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
 		chan->sdu_len = sdu_len;
 		chan->sdu_last_frag = skb;
 
+		/* Detect if remote is not able to use the selected MPS */
+		if (skb->len + L2CAP_SDULEN_SIZE < chan->mps) {
+			u16 mps_len = skb->len + L2CAP_SDULEN_SIZE;
+
+			/* Adjust the number of credits */
+			BT_DBG("chan->mps %u -> %u", chan->mps, mps_len);
+			chan->mps = mps_len;
+			l2cap_chan_le_send_credits(chan);
+		}
+
 		return 0;
 	}
 
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH v2 0/3] Bluetooth: L2CAP: Improve credits logic
  2018-09-04 10:39 [PATCH v2 0/3] Bluetooth: L2CAP: Improve credits logic Luiz Augusto von Dentz
                   ` (2 preceding siblings ...)
  2018-09-04 10:39 ` [PATCH v2 3/3] Bluetooth: L2CAP: Detect if remote is not able to use the whole MPS Luiz Augusto von Dentz
@ 2018-09-20  9:26 ` Luiz Augusto von Dentz
  2018-09-27 10:52 ` Marcel Holtmann
  4 siblings, 0 replies; 6+ messages in thread
From: Luiz Augusto von Dentz @ 2018-09-20  9:26 UTC (permalink / raw)
  To: linux-bluetooth

Hi,

On Tue, Sep 4, 2018 at 1:39 PM, Luiz Augusto von Dentz
<luiz.dentz@gmail.com> wrote:
> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
>
> These changes replace the existing threshold logic with a limpler logic
> that gives back credits after receiving an SDU. It also removes the
> debugfs entries to configure the MPS and credits with auto selected one
> derived from the MTU and MPS.
>
> v2: Account from the SDU length when adjusting the MPS.
>
> Luiz Augusto von Dentz (3):
>   Bluetooth: L2CAP: Derive MPS from connection MTU
>   Bluetooth: L2CAP: Derive rx credits from MTU and MPS
>   Bluetooth: L2CAP: Detect if remote is not able to use the whole MPS
>
>  include/net/bluetooth/l2cap.h |  3 --
>  net/bluetooth/l2cap_core.c    | 66 +++++++++++++++++++++++------------
>  2 files changed, 44 insertions(+), 25 deletions(-)

Ping.

-- 
Luiz Augusto von Dentz

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v2 0/3] Bluetooth: L2CAP: Improve credits logic
  2018-09-04 10:39 [PATCH v2 0/3] Bluetooth: L2CAP: Improve credits logic Luiz Augusto von Dentz
                   ` (3 preceding siblings ...)
  2018-09-20  9:26 ` [PATCH v2 0/3] Bluetooth: L2CAP: Improve credits logic Luiz Augusto von Dentz
@ 2018-09-27 10:52 ` Marcel Holtmann
  4 siblings, 0 replies; 6+ messages in thread
From: Marcel Holtmann @ 2018-09-27 10:52 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth

Hi Luiz,

> These changes replace the existing threshold logic with a limpler logic
> that gives back credits after receiving an SDU. It also removes the
> debugfs entries to configure the MPS and credits with auto selected one
> derived from the MTU and MPS.
> 
> v2: Account from the SDU length when adjusting the MPS.
> 
> Luiz Augusto von Dentz (3):
>  Bluetooth: L2CAP: Derive MPS from connection MTU
>  Bluetooth: L2CAP: Derive rx credits from MTU and MPS
>  Bluetooth: L2CAP: Detect if remote is not able to use the whole MPS
> 
> include/net/bluetooth/l2cap.h |  3 --
> net/bluetooth/l2cap_core.c    | 66 +++++++++++++++++++++++------------
> 2 files changed, 44 insertions(+), 25 deletions(-)

all 3 patches have been applied to bluetooth-next tree.

Regards

Marcel


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2018-09-27 10:52 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-09-04 10:39 [PATCH v2 0/3] Bluetooth: L2CAP: Improve credits logic Luiz Augusto von Dentz
2018-09-04 10:39 ` [PATCH v2 1/3] Bluetooth: L2CAP: Derive MPS from connection MTU Luiz Augusto von Dentz
2018-09-04 10:39 ` [PATCH v2 2/3] Bluetooth: L2CAP: Derive rx credits from MTU and MPS Luiz Augusto von Dentz
2018-09-04 10:39 ` [PATCH v2 3/3] Bluetooth: L2CAP: Detect if remote is not able to use the whole MPS Luiz Augusto von Dentz
2018-09-20  9:26 ` [PATCH v2 0/3] Bluetooth: L2CAP: Improve credits logic Luiz Augusto von Dentz
2018-09-27 10:52 ` Marcel Holtmann

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).