diff options
author | Gustavo F. Padovan <padovan@profusion.mobi> | 2010-06-21 17:50:49 -0400 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2010-07-21 13:39:09 -0400 |
commit | e0f66218b3a7d0bcf37ca95186123c257fda0ba5 (patch) | |
tree | 3b7972c417686f3bddbe69af5fdb8c6984c513ee /net/bluetooth | |
parent | 8cb8e6f1684be13b51f8429b15f39c140326b327 (diff) |
Bluetooth: Remove the send_lock spinlock from ERTM
Using a lock to deal with the ERTM race condition - interruption with
new data from the hci layer - is wrong. We should use the native skb
backlog queue.
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/bluetooth')
-rw-r--r-- | net/bluetooth/l2cap.c | 28 |
1 files changed, 1 insertions, 27 deletions
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index f6e46fdddd2b..dc8601fc2404 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c | |||
@@ -1562,16 +1562,11 @@ static int l2cap_retransmit_frames(struct sock *sk) | |||
1562 | struct l2cap_pinfo *pi = l2cap_pi(sk); | 1562 | struct l2cap_pinfo *pi = l2cap_pi(sk); |
1563 | int ret; | 1563 | int ret; |
1564 | 1564 | ||
1565 | spin_lock_bh(&pi->send_lock); | ||
1566 | |||
1567 | if (!skb_queue_empty(TX_QUEUE(sk))) | 1565 | if (!skb_queue_empty(TX_QUEUE(sk))) |
1568 | sk->sk_send_head = TX_QUEUE(sk)->next; | 1566 | sk->sk_send_head = TX_QUEUE(sk)->next; |
1569 | 1567 | ||
1570 | pi->next_tx_seq = pi->expected_ack_seq; | 1568 | pi->next_tx_seq = pi->expected_ack_seq; |
1571 | ret = l2cap_ertm_send(sk); | 1569 | ret = l2cap_ertm_send(sk); |
1572 | |||
1573 | spin_unlock_bh(&pi->send_lock); | ||
1574 | |||
1575 | return ret; | 1570 | return ret; |
1576 | } | 1571 | } |
1577 | 1572 | ||
@@ -1579,7 +1574,6 @@ static void l2cap_send_ack(struct l2cap_pinfo *pi) | |||
1579 | { | 1574 | { |
1580 | struct sock *sk = (struct sock *)pi; | 1575 | struct sock *sk = (struct sock *)pi; |
1581 | u16 control = 0; | 1576 | u16 control = 0; |
1582 | int nframes; | ||
1583 | 1577 | ||
1584 | control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT; | 1578 | control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT; |
1585 | 1579 | ||
@@ -1590,11 +1584,7 @@ static void l2cap_send_ack(struct l2cap_pinfo *pi) | |||
1590 | return; | 1584 | return; |
1591 | } | 1585 | } |
1592 | 1586 | ||
1593 | spin_lock_bh(&pi->send_lock); | 1587 | if (l2cap_ertm_send(sk) > 0) |
1594 | nframes = l2cap_ertm_send(sk); | ||
1595 | spin_unlock_bh(&pi->send_lock); | ||
1596 | |||
1597 | if (nframes > 0) | ||
1598 | return; | 1588 | return; |
1599 | 1589 | ||
1600 | control |= L2CAP_SUPER_RCV_READY; | 1590 | control |= L2CAP_SUPER_RCV_READY; |
@@ -1789,10 +1779,8 @@ static inline int l2cap_sar_segment_sdu(struct sock *sk, struct msghdr *msg, siz | |||
1789 | size += buflen; | 1779 | size += buflen; |
1790 | } | 1780 | } |
1791 | skb_queue_splice_tail(&sar_queue, TX_QUEUE(sk)); | 1781 | skb_queue_splice_tail(&sar_queue, TX_QUEUE(sk)); |
1792 | spin_lock_bh(&pi->send_lock); | ||
1793 | if (sk->sk_send_head == NULL) | 1782 | if (sk->sk_send_head == NULL) |
1794 | sk->sk_send_head = sar_queue.next; | 1783 | sk->sk_send_head = sar_queue.next; |
1795 | spin_unlock_bh(&pi->send_lock); | ||
1796 | 1784 | ||
1797 | return size; | 1785 | return size; |
1798 | } | 1786 | } |
@@ -1864,14 +1852,9 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct ms | |||
1864 | } | 1852 | } |
1865 | __skb_queue_tail(TX_QUEUE(sk), skb); | 1853 | __skb_queue_tail(TX_QUEUE(sk), skb); |
1866 | 1854 | ||
1867 | if (pi->mode == L2CAP_MODE_ERTM) | ||
1868 | spin_lock_bh(&pi->send_lock); | ||
1869 | |||
1870 | if (sk->sk_send_head == NULL) | 1855 | if (sk->sk_send_head == NULL) |
1871 | sk->sk_send_head = skb; | 1856 | sk->sk_send_head = skb; |
1872 | 1857 | ||
1873 | if (pi->mode == L2CAP_MODE_ERTM) | ||
1874 | spin_unlock_bh(&pi->send_lock); | ||
1875 | } else { | 1858 | } else { |
1876 | /* Segment SDU into multiples PDUs */ | 1859 | /* Segment SDU into multiples PDUs */ |
1877 | err = l2cap_sar_segment_sdu(sk, msg, len); | 1860 | err = l2cap_sar_segment_sdu(sk, msg, len); |
@@ -1887,9 +1870,7 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct ms | |||
1887 | err = len; | 1870 | err = len; |
1888 | break; | 1871 | break; |
1889 | } | 1872 | } |
1890 | spin_lock_bh(&pi->send_lock); | ||
1891 | err = l2cap_ertm_send(sk); | 1873 | err = l2cap_ertm_send(sk); |
1892 | spin_unlock_bh(&pi->send_lock); | ||
1893 | } | 1874 | } |
1894 | 1875 | ||
1895 | if (err >= 0) | 1876 | if (err >= 0) |
@@ -2464,7 +2445,6 @@ static inline void l2cap_ertm_init(struct sock *sk) | |||
2464 | 2445 | ||
2465 | __skb_queue_head_init(SREJ_QUEUE(sk)); | 2446 | __skb_queue_head_init(SREJ_QUEUE(sk)); |
2466 | __skb_queue_head_init(BUSY_QUEUE(sk)); | 2447 | __skb_queue_head_init(BUSY_QUEUE(sk)); |
2467 | spin_lock_init(&l2cap_pi(sk)->send_lock); | ||
2468 | 2448 | ||
2469 | INIT_WORK(&l2cap_pi(sk)->busy_work, l2cap_busy_work); | 2449 | INIT_WORK(&l2cap_pi(sk)->busy_work, l2cap_busy_work); |
2470 | } | 2450 | } |
@@ -3462,9 +3442,7 @@ static inline void l2cap_send_i_or_rr_or_rnr(struct sock *sk) | |||
3462 | if (pi->conn_state & L2CAP_CONN_REMOTE_BUSY) | 3442 | if (pi->conn_state & L2CAP_CONN_REMOTE_BUSY) |
3463 | l2cap_retransmit_frames(sk); | 3443 | l2cap_retransmit_frames(sk); |
3464 | 3444 | ||
3465 | spin_lock_bh(&pi->send_lock); | ||
3466 | l2cap_ertm_send(sk); | 3445 | l2cap_ertm_send(sk); |
3467 | spin_unlock_bh(&pi->send_lock); | ||
3468 | 3446 | ||
3469 | if (!(pi->conn_state & L2CAP_CONN_LOCAL_BUSY) && | 3447 | if (!(pi->conn_state & L2CAP_CONN_LOCAL_BUSY) && |
3470 | pi->frames_sent == 0) { | 3448 | pi->frames_sent == 0) { |
@@ -4066,9 +4044,7 @@ static inline void l2cap_data_channel_rrframe(struct sock *sk, u16 rx_control) | |||
4066 | if (pi->conn_state & L2CAP_CONN_SREJ_SENT) { | 4044 | if (pi->conn_state & L2CAP_CONN_SREJ_SENT) { |
4067 | l2cap_send_ack(pi); | 4045 | l2cap_send_ack(pi); |
4068 | } else { | 4046 | } else { |
4069 | spin_lock_bh(&pi->send_lock); | ||
4070 | l2cap_ertm_send(sk); | 4047 | l2cap_ertm_send(sk); |
4071 | spin_unlock_bh(&pi->send_lock); | ||
4072 | } | 4048 | } |
4073 | } | 4049 | } |
4074 | } | 4050 | } |
@@ -4113,9 +4089,7 @@ static inline void l2cap_data_channel_srejframe(struct sock *sk, u16 rx_control) | |||
4113 | pi->conn_state |= L2CAP_CONN_SEND_FBIT; | 4089 | pi->conn_state |= L2CAP_CONN_SEND_FBIT; |
4114 | l2cap_retransmit_one_frame(sk, tx_seq); | 4090 | l2cap_retransmit_one_frame(sk, tx_seq); |
4115 | 4091 | ||
4116 | spin_lock_bh(&pi->send_lock); | ||
4117 | l2cap_ertm_send(sk); | 4092 | l2cap_ertm_send(sk); |
4118 | spin_unlock_bh(&pi->send_lock); | ||
4119 | 4093 | ||
4120 | if (pi->conn_state & L2CAP_CONN_WAIT_F) { | 4094 | if (pi->conn_state & L2CAP_CONN_WAIT_F) { |
4121 | pi->srej_save_reqseq = tx_seq; | 4095 | pi->srej_save_reqseq = tx_seq; |