diff options
author | Takashi Sakamoto <o-takashi@sakamocchi.jp> | 2025-08-03 21:20:13 +0900 |
---|---|---|
committer | Takashi Sakamoto <o-takashi@sakamocchi.jp> | 2025-08-03 21:20:13 +0900 |
commit | e8cf6875005b017c293bf1b9be707c43f3eff9f4 (patch) | |
tree | 2594d506fade9126c93b4904266d550f21162bdc | |
parent | 7c527c15cdda2e0a26a05ac15a44d3e14738fc55 (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.c | 16 |
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, |