summaryrefslogtreecommitdiffstats
path: root/net/bluetooth/l2cap_sock.c
diff options
context:
space:
mode:
authorAndrei Emeltchenko <andrei.emeltchenko@intel.com>2012-02-21 12:54:55 +0200
committerJohan Hedberg <johan.hedberg@intel.com>2012-02-23 13:06:57 +0200
commit3df91ea20e744344100b10ae69a17211fcf5b207 (patch)
treee238acaf376266331985debc4a5a76c4e2636209 /net/bluetooth/l2cap_sock.c
parent1b009c982482ee0e4cbabcd9bdae690a29119ede (diff)
downloadlinux-3df91ea20e744344100b10ae69a17211fcf5b207.tar.bz2
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.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index b48d6c1b9db6..1273fcbeec28 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;
}