diff options
author | Gustavo F. Padovan <gustavo@las.ic.unicamp.br> | 2009-08-23 23:45:19 -0400 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2009-08-24 04:05:05 -0400 |
commit | e686219a64fee9be9ce438dc3f040cd71ddd168a (patch) | |
tree | 1b72117be85dc4dd5c4656e459043d2528069760 /net/bluetooth | |
parent | 9e726b17422bade75fba94e625cd35fd1353e682 (diff) |
Bluetooth: Add locking scheme to L2CAP timeout callbacks
Avoid race conditions when accessing the L2CAP socket from within the
timeout handlers.
Signed-off-by: Gustavo F. Padovan <gustavo@las.ic.unicamp.br>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/bluetooth')
-rw-r--r-- | net/bluetooth/l2cap.c | 4 |
1 files changed, 4 insertions, 0 deletions
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index c04526f3df2e..efac637525f1 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c | |||
@@ -1192,6 +1192,7 @@ static void l2cap_monitor_timeout(unsigned long arg) | |||
1192 | struct sock *sk = (void *) arg; | 1192 | struct sock *sk = (void *) arg; |
1193 | u16 control; | 1193 | u16 control; |
1194 | 1194 | ||
1195 | bh_lock_sock(sk); | ||
1195 | if (l2cap_pi(sk)->retry_count >= l2cap_pi(sk)->remote_max_tx) { | 1196 | if (l2cap_pi(sk)->retry_count >= l2cap_pi(sk)->remote_max_tx) { |
1196 | l2cap_send_disconn_req(l2cap_pi(sk)->conn, sk); | 1197 | l2cap_send_disconn_req(l2cap_pi(sk)->conn, sk); |
1197 | return; | 1198 | return; |
@@ -1203,6 +1204,7 @@ static void l2cap_monitor_timeout(unsigned long arg) | |||
1203 | control = L2CAP_CTRL_POLL; | 1204 | control = L2CAP_CTRL_POLL; |
1204 | control |= L2CAP_SUPER_RCV_READY; | 1205 | control |= L2CAP_SUPER_RCV_READY; |
1205 | l2cap_send_sframe(l2cap_pi(sk), control); | 1206 | l2cap_send_sframe(l2cap_pi(sk), control); |
1207 | bh_unlock_sock(sk); | ||
1206 | } | 1208 | } |
1207 | 1209 | ||
1208 | static void l2cap_retrans_timeout(unsigned long arg) | 1210 | static void l2cap_retrans_timeout(unsigned long arg) |
@@ -1210,6 +1212,7 @@ static void l2cap_retrans_timeout(unsigned long arg) | |||
1210 | struct sock *sk = (void *) arg; | 1212 | struct sock *sk = (void *) arg; |
1211 | u16 control; | 1213 | u16 control; |
1212 | 1214 | ||
1215 | bh_lock_sock(sk); | ||
1213 | l2cap_pi(sk)->retry_count = 1; | 1216 | l2cap_pi(sk)->retry_count = 1; |
1214 | __mod_monitor_timer(); | 1217 | __mod_monitor_timer(); |
1215 | 1218 | ||
@@ -1218,6 +1221,7 @@ static void l2cap_retrans_timeout(unsigned long arg) | |||
1218 | control = L2CAP_CTRL_POLL; | 1221 | control = L2CAP_CTRL_POLL; |
1219 | control |= L2CAP_SUPER_RCV_READY; | 1222 | control |= L2CAP_SUPER_RCV_READY; |
1220 | l2cap_send_sframe(l2cap_pi(sk), control); | 1223 | l2cap_send_sframe(l2cap_pi(sk), control); |
1224 | bh_unlock_sock(sk); | ||
1221 | } | 1225 | } |
1222 | 1226 | ||
1223 | static void l2cap_drop_acked_frames(struct sock *sk) | 1227 | static void l2cap_drop_acked_frames(struct sock *sk) |