diff options
author | Gustavo F. Padovan <padovan@profusion.mobi> | 2010-05-01 16:15:45 -0300 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2010-05-10 09:28:53 +0200 |
commit | dfc909befbfe967bd7f46ef33b6969c1b7f3cf42 (patch) | |
tree | cec8545cce920fe194a2d167467a1ca500c2616d /include/net/bluetooth | |
parent | 6161c0382bbab883a634d284f7367a88bbe88534 (diff) | |
download | kernel_samsung_smdk4412-dfc909befbfe967bd7f46ef33b6969c1b7f3cf42.zip kernel_samsung_smdk4412-dfc909befbfe967bd7f46ef33b6969c1b7f3cf42.tar.gz kernel_samsung_smdk4412-dfc909befbfe967bd7f46ef33b6969c1b7f3cf42.tar.bz2 |
Bluetooth: Fix race condition on l2cap_ertm_send()
l2cap_ertm_send() can be called both from user context and bottom half
context. The socket locks for that contexts are different, the user
context uses a mutex(which can sleep) and the second one uses a
spinlock_bh. That creates a race condition when we have interruptions on
both contexts at the same time.
The better way to solve this is to add a new spinlock to lock
l2cap_ertm_send() and the vars it access. The other solution was to defer
l2cap_ertm_send() with a workqueue, but we the sending process already
has one defer on the hci layer. It's not a good idea add another one.
The patch refactor the code to create l2cap_retransmit_frames(), then we
encapulate the lock of l2cap_ertm_send() for some call. It also changes
l2cap_retransmit_frame() to l2cap_retransmit_one_frame() to avoid
confusion
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Reviewed-by: João Paulo Rechi Vita <jprvita@profusion.mobi>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'include/net/bluetooth')
-rw-r--r-- | include/net/bluetooth/l2cap.h | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index d0185cc..7c695bf 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -353,6 +353,7 @@ struct l2cap_pinfo { __le16 sport; + spinlock_t send_lock; struct timer_list retrans_timer; struct timer_list monitor_timer; struct timer_list ack_timer; |