Commit 6be36555 authored by Andrei Emeltchenko's avatar Andrei Emeltchenko Committed by Johan Hedberg

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: default avatarAndrei Emeltchenko <andrei.emeltchenko@intel.com>
Reviewed-by: default avatarUlisses Furquim <ulisses@profusion.mobi>
Acked-by: default avatarGustavo F. Padovan <padovan@profusion.mobi>
Signed-off-by: default avatarJohan Hedberg <johan.hedberg@intel.com>
parent 643162a8
This diff is collapsed.
...@@ -127,6 +127,8 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al ...@@ -127,6 +127,8 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al
if (err) if (err)
goto done; goto done;
lock_sock(sk);
err = bt_sock_wait_state(sk, BT_CONNECTED, err = bt_sock_wait_state(sk, BT_CONNECTED,
sock_sndtimeo(sk, flags & O_NONBLOCK)); sock_sndtimeo(sk, flags & O_NONBLOCK));
done: done:
...@@ -810,14 +812,18 @@ static int l2cap_sock_shutdown(struct socket *sock, int how) ...@@ -810,14 +812,18 @@ static int l2cap_sock_shutdown(struct socket *sock, int how)
if (conn) if (conn)
mutex_lock(&conn->chan_lock); mutex_lock(&conn->chan_lock);
l2cap_chan_lock(chan);
lock_sock(sk); lock_sock(sk);
if (!sk->sk_shutdown) { if (!sk->sk_shutdown) {
if (chan->mode == L2CAP_MODE_ERTM) if (chan->mode == L2CAP_MODE_ERTM)
err = __l2cap_wait_ack(sk); err = __l2cap_wait_ack(sk);
sk->sk_shutdown = SHUTDOWN_MASK; sk->sk_shutdown = SHUTDOWN_MASK;
release_sock(sk);
l2cap_chan_close(chan, 0); l2cap_chan_close(chan, 0);
lock_sock(sk);
if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime) if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime)
err = bt_sock_wait_state(sk, BT_CLOSED, err = bt_sock_wait_state(sk, BT_CLOSED,
...@@ -828,6 +834,7 @@ static int l2cap_sock_shutdown(struct socket *sock, int how) ...@@ -828,6 +834,7 @@ static int l2cap_sock_shutdown(struct socket *sock, int how)
err = -sk->sk_err; err = -sk->sk_err;
release_sock(sk); release_sock(sk);
l2cap_chan_unlock(chan);
if (conn) if (conn)
mutex_unlock(&conn->chan_lock); mutex_unlock(&conn->chan_lock);
...@@ -874,8 +881,12 @@ static int l2cap_sock_recv_cb(void *data, struct sk_buff *skb) ...@@ -874,8 +881,12 @@ static int l2cap_sock_recv_cb(void *data, struct sk_buff *skb)
struct sock *sk = data; struct sock *sk = data;
struct l2cap_pinfo *pi = l2cap_pi(sk); struct l2cap_pinfo *pi = l2cap_pi(sk);
if (pi->rx_busy_skb) lock_sock(sk);
return -ENOMEM;
if (pi->rx_busy_skb) {
err = -ENOMEM;
goto done;
}
err = sock_queue_rcv_skb(sk, skb); err = sock_queue_rcv_skb(sk, skb);
...@@ -894,6 +905,9 @@ static int l2cap_sock_recv_cb(void *data, struct sk_buff *skb) ...@@ -894,6 +905,9 @@ static int l2cap_sock_recv_cb(void *data, struct sk_buff *skb)
err = 0; err = 0;
} }
done:
release_sock(sk);
return err; return err;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment