diff options
author | Gustavo F. Padovan <padovan@profusion.mobi> | 2010-08-30 17:44:44 -0400 |
---|---|---|
committer | Gustavo F. Padovan <padovan@profusion.mobi> | 2010-09-30 11:19:35 -0400 |
commit | ccbb84af28594e19fd4bf27ff2828c80d03b6081 (patch) | |
tree | cfb8b361b73c1bd299f17192e964c3184850e08b /net/bluetooth | |
parent | 8183b775bc5b79b6b1e250019c9dd930554dfa94 (diff) |
Bluetooth: Simplify L2CAP Streaming mode sending
As we don't have any error control on the Streaming mode, i.e., we don't
need to keep a copy of the skb for later resending we don't need to
call skb_clone() on it.
Then we can go one further here, and dequeue the skb before sending it,
that also means we don't need to look to sk->sk_send_head anymore.
The patch saves memory and time when sending Streaming mode data, so
it is good to mainline.
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Diffstat (limited to 'net/bluetooth')
-rw-r--r-- | net/bluetooth/l2cap.c | 24 |
1 files changed, 7 insertions, 17 deletions
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index 9fad312e53f2..f2062aace406 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c | |||
@@ -1441,33 +1441,23 @@ static inline void l2cap_do_send(struct sock *sk, struct sk_buff *skb) | |||
1441 | 1441 | ||
1442 | static void l2cap_streaming_send(struct sock *sk) | 1442 | static void l2cap_streaming_send(struct sock *sk) |
1443 | { | 1443 | { |
1444 | struct sk_buff *skb, *tx_skb; | 1444 | struct sk_buff *skb; |
1445 | struct l2cap_pinfo *pi = l2cap_pi(sk); | 1445 | struct l2cap_pinfo *pi = l2cap_pi(sk); |
1446 | u16 control, fcs; | 1446 | u16 control, fcs; |
1447 | 1447 | ||
1448 | while ((skb = sk->sk_send_head)) { | 1448 | while ((skb = skb_dequeue(TX_QUEUE(sk)))) { |
1449 | tx_skb = skb_clone(skb, GFP_ATOMIC); | 1449 | control = get_unaligned_le16(skb->data + L2CAP_HDR_SIZE); |
1450 | |||
1451 | control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE); | ||
1452 | control |= pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT; | 1450 | control |= pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT; |
1453 | put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE); | 1451 | put_unaligned_le16(control, skb->data + L2CAP_HDR_SIZE); |
1454 | 1452 | ||
1455 | if (pi->fcs == L2CAP_FCS_CRC16) { | 1453 | if (pi->fcs == L2CAP_FCS_CRC16) { |
1456 | fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2); | 1454 | fcs = crc16(0, (u8 *)skb->data, skb->len - 2); |
1457 | put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2); | 1455 | put_unaligned_le16(fcs, skb->data + skb->len - 2); |
1458 | } | 1456 | } |
1459 | 1457 | ||
1460 | l2cap_do_send(sk, tx_skb); | 1458 | l2cap_do_send(sk, skb); |
1461 | 1459 | ||
1462 | pi->next_tx_seq = (pi->next_tx_seq + 1) % 64; | 1460 | pi->next_tx_seq = (pi->next_tx_seq + 1) % 64; |
1463 | |||
1464 | if (skb_queue_is_last(TX_QUEUE(sk), skb)) | ||
1465 | sk->sk_send_head = NULL; | ||
1466 | else | ||
1467 | sk->sk_send_head = skb_queue_next(TX_QUEUE(sk), skb); | ||
1468 | |||
1469 | skb = skb_dequeue(TX_QUEUE(sk)); | ||
1470 | kfree_skb(skb); | ||
1471 | } | 1461 | } |
1472 | } | 1462 | } |
1473 | 1463 | ||