diff options
author | Andrei Emeltchenko <andrei.emeltchenko@intel.com> | 2012-02-22 10:11:56 -0500 |
---|---|---|
committer | Johan Hedberg <johan.hedberg@intel.com> | 2012-02-23 06:07:02 -0500 |
commit | 6be3655552ee49aa2b5fd20fa1b08f28d0feac86 (patch) | |
tree | 921d44bd7d1ca85df0b36113dec274b269d575f2 /net/bluetooth/l2cap_sock.c | |
parent | 643162a8e2c15a1c1983a0063d9941240b3bde30 (diff) |
Bluetooth: Change sk lock to chan lock in L2CAP core
Change sk lock to chan lock in l2cap core and move sk locks
to l2cap sock code. bh_locks were used because of being RCU
critical section. When needed use explicit socket locks.
Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Reviewed-by: Ulisses Furquim <ulisses@profusion.mobi>
Acked-by: Gustavo F. Padovan <padovan@profusion.mobi>
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Diffstat (limited to 'net/bluetooth/l2cap_sock.c')
-rw-r--r-- | net/bluetooth/l2cap_sock.c | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index 1273fcbeec28..73a06c1b0cd7 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c | |||
@@ -127,6 +127,8 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al | |||
127 | if (err) | 127 | if (err) |
128 | goto done; | 128 | goto done; |
129 | 129 | ||
130 | lock_sock(sk); | ||
131 | |||
130 | err = bt_sock_wait_state(sk, BT_CONNECTED, | 132 | err = bt_sock_wait_state(sk, BT_CONNECTED, |
131 | sock_sndtimeo(sk, flags & O_NONBLOCK)); | 133 | sock_sndtimeo(sk, flags & O_NONBLOCK)); |
132 | done: | 134 | done: |
@@ -810,14 +812,18 @@ static int l2cap_sock_shutdown(struct socket *sock, int how) | |||
810 | if (conn) | 812 | if (conn) |
811 | mutex_lock(&conn->chan_lock); | 813 | mutex_lock(&conn->chan_lock); |
812 | 814 | ||
815 | l2cap_chan_lock(chan); | ||
813 | lock_sock(sk); | 816 | lock_sock(sk); |
817 | |||
814 | if (!sk->sk_shutdown) { | 818 | if (!sk->sk_shutdown) { |
815 | if (chan->mode == L2CAP_MODE_ERTM) | 819 | if (chan->mode == L2CAP_MODE_ERTM) |
816 | err = __l2cap_wait_ack(sk); | 820 | err = __l2cap_wait_ack(sk); |
817 | 821 | ||
818 | sk->sk_shutdown = SHUTDOWN_MASK; | 822 | sk->sk_shutdown = SHUTDOWN_MASK; |
819 | 823 | ||
824 | release_sock(sk); | ||
820 | l2cap_chan_close(chan, 0); | 825 | l2cap_chan_close(chan, 0); |
826 | lock_sock(sk); | ||
821 | 827 | ||
822 | if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime) | 828 | if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime) |
823 | err = bt_sock_wait_state(sk, BT_CLOSED, | 829 | err = bt_sock_wait_state(sk, BT_CLOSED, |
@@ -828,6 +834,7 @@ static int l2cap_sock_shutdown(struct socket *sock, int how) | |||
828 | err = -sk->sk_err; | 834 | err = -sk->sk_err; |
829 | 835 | ||
830 | release_sock(sk); | 836 | release_sock(sk); |
837 | l2cap_chan_unlock(chan); | ||
831 | 838 | ||
832 | if (conn) | 839 | if (conn) |
833 | mutex_unlock(&conn->chan_lock); | 840 | mutex_unlock(&conn->chan_lock); |
@@ -874,8 +881,12 @@ static int l2cap_sock_recv_cb(void *data, struct sk_buff *skb) | |||
874 | struct sock *sk = data; | 881 | struct sock *sk = data; |
875 | struct l2cap_pinfo *pi = l2cap_pi(sk); | 882 | struct l2cap_pinfo *pi = l2cap_pi(sk); |
876 | 883 | ||
877 | if (pi->rx_busy_skb) | 884 | lock_sock(sk); |
878 | return -ENOMEM; | 885 | |
886 | if (pi->rx_busy_skb) { | ||
887 | err = -ENOMEM; | ||
888 | goto done; | ||
889 | } | ||
879 | 890 | ||
880 | err = sock_queue_rcv_skb(sk, skb); | 891 | err = sock_queue_rcv_skb(sk, skb); |
881 | 892 | ||
@@ -894,6 +905,9 @@ static int l2cap_sock_recv_cb(void *data, struct sk_buff *skb) | |||
894 | err = 0; | 905 | err = 0; |
895 | } | 906 | } |
896 | 907 | ||
908 | done: | ||
909 | release_sock(sk); | ||
910 | |||
897 | return err; | 911 | return err; |
898 | } | 912 | } |
899 | 913 | ||