summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTakashi Sakamoto <o-takashi@sakamocchi.jp>2025-08-03 21:20:13 +0900
committerTakashi Sakamoto <o-takashi@sakamocchi.jp>2025-08-03 21:20:13 +0900
commite8cf6875005b017c293bf1b9be707c43f3eff9f4 (patch)
tree2594d506fade9126c93b4904266d550f21162bdc
parent7c527c15cdda2e0a26a05ac15a44d3e14738fc55 (diff)
firewire: core: call handler for exclusive regions outside RCU read-side critical section
The previous commit added reference counting to ensure safe invocations of address handlers. This commit moves the invocation of handlers for exclusive regions outside of the RCU read-side critical section. The address handler for the requested region is selected within the critical section, then invoked outside of it. Link: https://lore.kernel.org/r/20250803122015.236493-3-o-takashi@sakamocchi.jp Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
-rw-r--r--drivers/firewire/core-transaction.c16
1 files changed, 9 insertions, 7 deletions
diff --git a/drivers/firewire/core-transaction.c b/drivers/firewire/core-transaction.c
index 29ca9f3f14ce..a742971c65fa 100644
--- a/drivers/firewire/core-transaction.c
+++ b/drivers/firewire/core-transaction.c
@@ -935,17 +935,19 @@ static void handle_exclusive_region_request(struct fw_card *card,
scoped_guard(rcu) {
handler = lookup_enclosing_address_handler(&address_handler_list, offset,
request->length);
- if (handler) {
+ if (handler)
get_address_handler(handler);
- handler->address_callback(card, request, tcode, destination, source,
- p->generation, offset, request->data,
- request->length, handler->callback_data);
- put_address_handler(handler);
- }
}
- if (!handler)
+ if (!handler) {
fw_send_response(card, request, RCODE_ADDRESS_ERROR);
+ return;
+ }
+
+ // Outside the RCU read-side critical section. Without spinlock. With reference count.
+ handler->address_callback(card, request, tcode, destination, source, p->generation, offset,
+ request->data, request->length, handler->callback_data);
+ put_address_handler(handler);
}
static void handle_fcp_region_request(struct fw_card *card,