Skip to content

Commit 2222bcb

Browse files
cladischStefan Richter
authored andcommitted
firewire: core: do not use del_timer_sync() in interrupt context
Because we might be in interrupt context, replace del_timer_sync() with del_timer(). If the timer is already running, we know that it will clean up the transaction, so we do not need to do any further processing in the normal transaction handler. Many thanks to Yong Zhang for diagnosing this. Reported-by: Stefan Richter <stefanr@s5r6.in-berlin.de> Signed-off-by: Clemens Ladisch <clemens@ladisch.de> Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
1 parent 1bf145f commit 2222bcb

File tree

1 file changed

+10
-3
lines changed

1 file changed

+10
-3
lines changed

drivers/firewire/core-transaction.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,10 @@ static int close_transaction(struct fw_transaction *transaction,
8181
spin_lock_irqsave(&card->lock, flags);
8282
list_for_each_entry(t, &card->transaction_list, link) {
8383
if (t == transaction) {
84+
if (!del_timer(&t->split_timeout_timer)) {
85+
spin_unlock_irqrestore(&card->lock, flags);
86+
goto timed_out;
87+
}
8488
list_del_init(&t->link);
8589
card->tlabel_mask &= ~(1ULL << t->tlabel);
8690
break;
@@ -89,11 +93,11 @@ static int close_transaction(struct fw_transaction *transaction,
8993
spin_unlock_irqrestore(&card->lock, flags);
9094

9195
if (&t->link != &card->transaction_list) {
92-
del_timer_sync(&t->split_timeout_timer);
9396
t->callback(card, rcode, NULL, 0, t->callback_data);
9497
return 0;
9598
}
9699

100+
timed_out:
97101
return -ENOENT;
98102
}
99103

@@ -921,6 +925,10 @@ void fw_core_handle_response(struct fw_card *card, struct fw_packet *p)
921925
spin_lock_irqsave(&card->lock, flags);
922926
list_for_each_entry(t, &card->transaction_list, link) {
923927
if (t->node_id == source && t->tlabel == tlabel) {
928+
if (!del_timer(&t->split_timeout_timer)) {
929+
spin_unlock_irqrestore(&card->lock, flags);
930+
goto timed_out;
931+
}
924932
list_del_init(&t->link);
925933
card->tlabel_mask &= ~(1ULL << t->tlabel);
926934
break;
@@ -929,6 +937,7 @@ void fw_core_handle_response(struct fw_card *card, struct fw_packet *p)
929937
spin_unlock_irqrestore(&card->lock, flags);
930938

931939
if (&t->link == &card->transaction_list) {
940+
timed_out:
932941
fw_notify("Unsolicited response (source %x, tlabel %x)\n",
933942
source, tlabel);
934943
return;
@@ -963,8 +972,6 @@ void fw_core_handle_response(struct fw_card *card, struct fw_packet *p)
963972
break;
964973
}
965974

966-
del_timer_sync(&t->split_timeout_timer);
967-
968975
/*
969976
* The response handler may be executed while the request handler
970977
* is still pending. Cancel the request handler.

0 commit comments

Comments
 (0)