diff options
author | Andrei Emeltchenko <andrei.emeltchenko@intel.com> | 2012-02-21 10:54:55 (GMT) |
---|---|---|
committer | Johan Hedberg <johan.hedberg@intel.com> | 2012-02-23 11:06:57 (GMT) |
commit | 3df91ea20e744344100b10ae69a17211fcf5b207 (patch) | |
tree | e238acaf376266331985debc4a5a76c4e2636209 /net/bluetooth/l2cap_sock.c | |
parent | 1b009c982482ee0e4cbabcd9bdae690a29119ede (diff) | |
download | linux-3df91ea20e744344100b10ae69a17211fcf5b207.tar.xz |
Bluetooth: Revert to mutexes from RCU list
Usage of RCU list looks not reasonalbe for a number of reasons:
our code sleep and we had to use socket spinlocks. Most parts
of code are updaters thus there is little sense to use RCU.
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 | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index b48d6c1..1273fcb 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c @@ -796,6 +796,7 @@ static int l2cap_sock_shutdown(struct socket *sock, int how) { struct sock *sk = sock->sk; struct l2cap_chan *chan; + struct l2cap_conn *conn; int err = 0; BT_DBG("sock %p, sk %p", sock, sk); @@ -804,6 +805,10 @@ static int l2cap_sock_shutdown(struct socket *sock, int how) return 0; chan = l2cap_pi(sk)->chan; + conn = chan->conn; + + if (conn) + mutex_lock(&conn->chan_lock); lock_sock(sk); if (!sk->sk_shutdown) { @@ -811,6 +816,7 @@ static int l2cap_sock_shutdown(struct socket *sock, int how) err = __l2cap_wait_ack(sk); sk->sk_shutdown = SHUTDOWN_MASK; + l2cap_chan_close(chan, 0); if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime) @@ -822,6 +828,10 @@ static int l2cap_sock_shutdown(struct socket *sock, int how) err = -sk->sk_err; release_sock(sk); + + if (conn) + mutex_unlock(&conn->chan_lock); + return err; } |