* [PATCH 1/2] Bluetooth: Remove usage of __cancel_delayed_work()
@ 2012-01-18 12:48 Ulisses Furquim
2012-01-18 12:48 ` [PATCH 2/2] Bluetooth: Remove wait for delayed work to finish Ulisses Furquim
0 siblings, 1 reply; 4+ messages in thread
From: Ulisses Furquim @ 2012-01-18 12:48 UTC (permalink / raw)
To: linux-bluetooth; +Cc: padovan
__cancel_delayed_work() is being used in some paths where we cannot
sleep waiting for the delayed work to finish. However, that function
might return while the timer is running and the work will be queued
again. Replace the calls with safer cancel_delayed_work() version
which spins until the timer handler finishes in other CPUs and
cancels the delayed work.
Signed-off-by: Ulisses Furquim <ulisses@profusion.mobi>
---
include/net/bluetooth/l2cap.h | 4 ++--
net/bluetooth/l2cap_core.c | 10 +++++-----
2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 18242ea..dd2dbe8 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -611,7 +611,7 @@ static inline void l2cap_set_timer(struct l2cap_chan *chan,
{
BT_DBG("chan %p state %d timeout %ld", chan, chan->state, timeout);
- if (!__cancel_delayed_work(work))
+ if (!cancel_delayed_work(work))
l2cap_chan_hold(chan);
schedule_delayed_work(work, timeout);
}
@@ -621,7 +621,7 @@ static inline bool l2cap_clear_timer(struct l2cap_chan *chan,
{
bool ret;
- ret = __cancel_delayed_work(work);
+ ret = cancel_delayed_work(work);
if (ret)
l2cap_chan_put(chan);
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 0087db8..6ee7a2d 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -1018,10 +1018,10 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err)
hci_chan_del(conn->hchan);
if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
- __cancel_delayed_work(&conn->info_timer);
+ cancel_delayed_work(&conn->info_timer);
if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->pend)) {
- __cancel_delayed_work(&conn->security_timer);
+ cancel_delayed_work(&conn->security_timer);
smp_chan_destroy(conn);
}
@@ -2583,7 +2583,7 @@ static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hd
if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
cmd->ident == conn->info_ident) {
- __cancel_delayed_work(&conn->info_timer);
+ cancel_delayed_work(&conn->info_timer);
conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
conn->info_ident = 0;
@@ -3130,7 +3130,7 @@ static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cm
conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE)
return 0;
- __cancel_delayed_work(&conn->info_timer);
+ cancel_delayed_work(&conn->info_timer);
if (result != L2CAP_IR_SUCCESS) {
conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
@@ -4504,7 +4504,7 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
if (hcon->type == LE_LINK) {
smp_distribute_keys(conn, 0);
- __cancel_delayed_work(&conn->security_timer);
+ cancel_delayed_work(&conn->security_timer);
}
rcu_read_lock();
--
1.7.8.rc4
^ permalink raw reply related [flat|nested] 4+ messages in thread* [PATCH 2/2] Bluetooth: Remove wait for delayed work to finish
2012-01-18 12:48 [PATCH 1/2] Bluetooth: Remove usage of __cancel_delayed_work() Ulisses Furquim
@ 2012-01-18 12:48 ` Ulisses Furquim
2012-01-18 19:34 ` Andre Guedes
0 siblings, 1 reply; 4+ messages in thread
From: Ulisses Furquim @ 2012-01-18 12:48 UTC (permalink / raw)
To: linux-bluetooth; +Cc: padovan
Do not wait for delayed work to finish where it's not needed. In the
case of adv_work the handler is already protected by the hdev lock
and removing the wait we also avoid introducing deadlocks involving
the delayed work lock.
Signed-off-by: Ulisses Furquim <ulisses@profusion.mobi>
---
net/bluetooth/hci_core.c | 2 +-
net/bluetooth/hci_event.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index a7b7200..b4041be 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1731,7 +1731,7 @@ void hci_unregister_dev(struct hci_dev *hdev)
hci_del_sysfs(hdev);
- cancel_delayed_work_sync(&hdev->adv_work);
+ cancel_delayed_work(&hdev->adv_work);
destroy_workqueue(hdev->workqueue);
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index c2fe964..f28cbae 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -1045,7 +1045,7 @@ static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
case LE_SCANNING_ENABLED:
set_bit(HCI_LE_SCAN, &hdev->dev_flags);
- cancel_delayed_work_sync(&hdev->adv_work);
+ cancel_delayed_work(&hdev->adv_work);
hci_dev_lock(hdev);
hci_adv_entries_clear(hdev);
--
1.7.8.rc4
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH 2/2] Bluetooth: Remove wait for delayed work to finish
2012-01-18 12:48 ` [PATCH 2/2] Bluetooth: Remove wait for delayed work to finish Ulisses Furquim
@ 2012-01-18 19:34 ` Andre Guedes
2012-01-18 19:40 ` Ulisses Furquim
0 siblings, 1 reply; 4+ messages in thread
From: Andre Guedes @ 2012-01-18 19:34 UTC (permalink / raw)
To: Ulisses Furquim; +Cc: linux-bluetooth, padovan
Hi Ulisses,
On Wed, Jan 18, 2012 at 9:48 AM, Ulisses Furquim <ulisses@profusion.mobi> wrote:
> Do not wait for delayed work to finish where it's not needed. In the
> case of adv_work the handler is already protected by the hdev lock
> and removing the wait we also avoid introducing deadlocks involving
> the delayed work lock.
>
> Signed-off-by: Ulisses Furquim <ulisses@profusion.mobi>
> ---
> net/bluetooth/hci_core.c | 2 +-
> net/bluetooth/hci_event.c | 2 +-
> 2 files changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
> index a7b7200..b4041be 100644
> --- a/net/bluetooth/hci_core.c
> +++ b/net/bluetooth/hci_core.c
> @@ -1731,7 +1731,7 @@ void hci_unregister_dev(struct hci_dev *hdev)
>
> hci_del_sysfs(hdev);
>
> - cancel_delayed_work_sync(&hdev->adv_work);
> + cancel_delayed_work(&hdev->adv_work);
I'm afraid we'll introduce a race condition if we don't use the
_sync variant at hci_unregister_dev.
If we don't wait adv_work finish it may be running after hdev
object is freed.
>
> destroy_workqueue(hdev->workqueue);
>
> diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
> index c2fe964..f28cbae 100644
> --- a/net/bluetooth/hci_event.c
> +++ b/net/bluetooth/hci_event.c
> @@ -1045,7 +1045,7 @@ static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
> case LE_SCANNING_ENABLED:
> set_bit(HCI_LE_SCAN, &hdev->dev_flags);
>
> - cancel_delayed_work_sync(&hdev->adv_work);
> + cancel_delayed_work(&hdev->adv_work);
>
> hci_dev_lock(hdev);
> hci_adv_entries_clear(hdev);
BR,
Andre
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH 2/2] Bluetooth: Remove wait for delayed work to finish
2012-01-18 19:34 ` Andre Guedes
@ 2012-01-18 19:40 ` Ulisses Furquim
0 siblings, 0 replies; 4+ messages in thread
From: Ulisses Furquim @ 2012-01-18 19:40 UTC (permalink / raw)
To: Andre Guedes; +Cc: linux-bluetooth, padovan
Hi Andre,
On Wed, Jan 18, 2012 at 5:34 PM, Andre Guedes
<andre.guedes@openbossa.org> wrote:
> Hi Ulisses,
>
> On Wed, Jan 18, 2012 at 9:48 AM, Ulisses Furquim <ulisses@profusion.mobi> wrote:
>> Do not wait for delayed work to finish where it's not needed. In the
>> case of adv_work the handler is already protected by the hdev lock
>> and removing the wait we also avoid introducing deadlocks involving
>> the delayed work lock.
>>
>> Signed-off-by: Ulisses Furquim <ulisses@profusion.mobi>
>> ---
>> net/bluetooth/hci_core.c | 2 +-
>> net/bluetooth/hci_event.c | 2 +-
>> 2 files changed, 2 insertions(+), 2 deletions(-)
>>
>> diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
>> index a7b7200..b4041be 100644
>> --- a/net/bluetooth/hci_core.c
>> +++ b/net/bluetooth/hci_core.c
>> @@ -1731,7 +1731,7 @@ void hci_unregister_dev(struct hci_dev *hdev)
>>
>> hci_del_sysfs(hdev);
>>
>> - cancel_delayed_work_sync(&hdev->adv_work);
>> + cancel_delayed_work(&hdev->adv_work);
>
> I'm afraid we'll introduce a race condition if we don't use the
> _sync variant at hci_unregister_dev.
>
> If we don't wait adv_work finish it may be running after hdev
> object is freed.
Indeed, you're right. And I was going through the uses of _sync() and
skipped those in paths where we free the object but didn't see this
one.
Regards,
--
Ulisses Furquim
ProFUSION embedded systems
http://profusion.mobi
Mobile: +55 19 9250 0942
Skype: ulissesffs
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2012-01-18 19:40 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-01-18 12:48 [PATCH 1/2] Bluetooth: Remove usage of __cancel_delayed_work() Ulisses Furquim
2012-01-18 12:48 ` [PATCH 2/2] Bluetooth: Remove wait for delayed work to finish Ulisses Furquim
2012-01-18 19:34 ` Andre Guedes
2012-01-18 19:40 ` Ulisses Furquim
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox