Commit d320bac9 authored by Takashi Sakamoto's avatar Takashi Sakamoto

firewire: core: use guard macro to maintain list of asynchronous transaction

The core function maintains pending asynchronous transactions by list in
the instance of fw_card. The concurrent access to the list is protected
by spinlock in the instance.

This commit uses guard macro to maintain the spinlock.

Link: https://lore.kernel.org/r/20240805085408.251763-14-o-takashi@sakamocchi.jpSigned-off-by: default avatarTakashi Sakamoto <o-takashi@sakamocchi.jp>
parent b9545448
...@@ -49,35 +49,31 @@ static int close_transaction(struct fw_transaction *transaction, struct fw_card ...@@ -49,35 +49,31 @@ static int close_transaction(struct fw_transaction *transaction, struct fw_card
u32 response_tstamp) u32 response_tstamp)
{ {
struct fw_transaction *t = NULL, *iter; struct fw_transaction *t = NULL, *iter;
unsigned long flags;
spin_lock_irqsave(&card->lock, flags); scoped_guard(spinlock_irqsave, &card->lock) {
list_for_each_entry(iter, &card->transaction_list, link) { list_for_each_entry(iter, &card->transaction_list, link) {
if (iter == transaction) { if (iter == transaction) {
if (!try_cancel_split_timeout(iter)) { if (try_cancel_split_timeout(iter)) {
spin_unlock_irqrestore(&card->lock, flags); list_del_init(&iter->link);
goto timed_out; card->tlabel_mask &= ~(1ULL << iter->tlabel);
t = iter;
}
break;
} }
list_del_init(&iter->link);
card->tlabel_mask &= ~(1ULL << iter->tlabel);
t = iter;
break;
} }
} }
spin_unlock_irqrestore(&card->lock, flags);
if (t) { if (!t)
if (!t->with_tstamp) { return -ENOENT;
t->callback.without_tstamp(card, rcode, NULL, 0, t->callback_data);
} else { if (!t->with_tstamp) {
t->callback.with_tstamp(card, rcode, t->packet.timestamp, response_tstamp, t->callback.without_tstamp(card, rcode, NULL, 0, t->callback_data);
NULL, 0, t->callback_data); } else {
} t->callback.with_tstamp(card, rcode, t->packet.timestamp, response_tstamp, NULL, 0,
return 0; t->callback_data);
} }
timed_out: return 0;
return -ENOENT;
} }
/* /*
...@@ -121,16 +117,13 @@ static void split_transaction_timeout_callback(struct timer_list *timer) ...@@ -121,16 +117,13 @@ static void split_transaction_timeout_callback(struct timer_list *timer)
{ {
struct fw_transaction *t = from_timer(t, timer, split_timeout_timer); struct fw_transaction *t = from_timer(t, timer, split_timeout_timer);
struct fw_card *card = t->card; struct fw_card *card = t->card;
unsigned long flags;
spin_lock_irqsave(&card->lock, flags); scoped_guard(spinlock_irqsave, &card->lock) {
if (list_empty(&t->link)) { if (list_empty(&t->link))
spin_unlock_irqrestore(&card->lock, flags); return;
return; list_del(&t->link);
card->tlabel_mask &= ~(1ULL << t->tlabel);
} }
list_del(&t->link);
card->tlabel_mask &= ~(1ULL << t->tlabel);
spin_unlock_irqrestore(&card->lock, flags);
if (!t->with_tstamp) { if (!t->with_tstamp) {
t->callback.without_tstamp(card, RCODE_CANCELLED, NULL, 0, t->callback_data); t->callback.without_tstamp(card, RCODE_CANCELLED, NULL, 0, t->callback_data);
...@@ -143,20 +136,14 @@ static void split_transaction_timeout_callback(struct timer_list *timer) ...@@ -143,20 +136,14 @@ static void split_transaction_timeout_callback(struct timer_list *timer)
static void start_split_transaction_timeout(struct fw_transaction *t, static void start_split_transaction_timeout(struct fw_transaction *t,
struct fw_card *card) struct fw_card *card)
{ {
unsigned long flags; guard(spinlock_irqsave)(&card->lock);
spin_lock_irqsave(&card->lock, flags); if (list_empty(&t->link) || WARN_ON(t->is_split_transaction))
if (list_empty(&t->link) || WARN_ON(t->is_split_transaction)) {
spin_unlock_irqrestore(&card->lock, flags);
return; return;
}
t->is_split_transaction = true; t->is_split_transaction = true;
mod_timer(&t->split_timeout_timer, mod_timer(&t->split_timeout_timer,
jiffies + card->split_timeout_jiffies); jiffies + card->split_timeout_jiffies);
spin_unlock_irqrestore(&card->lock, flags);
} }
static u32 compute_split_timeout_timestamp(struct fw_card *card, u32 request_timestamp); static u32 compute_split_timeout_timestamp(struct fw_card *card, u32 request_timestamp);
...@@ -1015,7 +1002,6 @@ EXPORT_SYMBOL(fw_core_handle_request); ...@@ -1015,7 +1002,6 @@ EXPORT_SYMBOL(fw_core_handle_request);
void fw_core_handle_response(struct fw_card *card, struct fw_packet *p) void fw_core_handle_response(struct fw_card *card, struct fw_packet *p)
{ {
struct fw_transaction *t = NULL, *iter; struct fw_transaction *t = NULL, *iter;
unsigned long flags;
u32 *data; u32 *data;
size_t data_length; size_t data_length;
int tcode, tlabel, source, rcode; int tcode, tlabel, source, rcode;
...@@ -1054,26 +1040,23 @@ void fw_core_handle_response(struct fw_card *card, struct fw_packet *p) ...@@ -1054,26 +1040,23 @@ void fw_core_handle_response(struct fw_card *card, struct fw_packet *p)
break; break;
} }
spin_lock_irqsave(&card->lock, flags); scoped_guard(spinlock_irqsave, &card->lock) {
list_for_each_entry(iter, &card->transaction_list, link) { list_for_each_entry(iter, &card->transaction_list, link) {
if (iter->node_id == source && iter->tlabel == tlabel) { if (iter->node_id == source && iter->tlabel == tlabel) {
if (!try_cancel_split_timeout(iter)) { if (try_cancel_split_timeout(iter)) {
spin_unlock_irqrestore(&card->lock, flags); list_del_init(&iter->link);
goto timed_out; card->tlabel_mask &= ~(1ULL << iter->tlabel);
t = iter;
}
break;
} }
list_del_init(&iter->link);
card->tlabel_mask &= ~(1ULL << iter->tlabel);
t = iter;
break;
} }
} }
spin_unlock_irqrestore(&card->lock, flags);
trace_async_response_inbound((uintptr_t)t, card->index, p->generation, p->speed, p->ack, trace_async_response_inbound((uintptr_t)t, card->index, p->generation, p->speed, p->ack,
p->timestamp, p->header, data, data_length / 4); p->timestamp, p->header, data, data_length / 4);
if (!t) { if (!t) {
timed_out:
fw_notice(card, "unsolicited response (source %x, tlabel %x)\n", fw_notice(card, "unsolicited response (source %x, tlabel %x)\n",
source, tlabel); source, tlabel);
return; return;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment