VisionFive2 Linux kernel

StarFive Tech Linux Kernel for VisionFive (JH7110) boards (mirror)

More than 9999 Commits   32 Branches   54 Tags
author: Stefan Richter <stefanr@s5r6.in-berlin.de> 2012-02-18 19:54:45 +0100 committer: Stefan Richter <stefanr@s5r6.in-berlin.de> 2012-02-22 22:36:01 +0100 commit: 90963f1cdb3baffc68321e7c98073bf9e99d2ec7 parent: 280f64d4f108b7ac707d6208d50a59627b984dc5
Commit Summary:
firewire: core: fix race at address_handler unregistration
Diffstat:
1 file changed, 7 insertions, 4 deletions
diff --git a/drivers/firewire/core-transaction.c b/drivers/firewire/core-transaction.c
index 89e310ba03ba..190bf61533a2 100644
--- a/drivers/firewire/core-transaction.c
+++ b/drivers/firewire/core-transaction.c
@@ -602,6 +602,9 @@ EXPORT_SYMBOL(fw_core_add_address_handler);
 
 /**
  * fw_core_remove_address_handler() - unregister an address handler
+ *
+ * When fw_core_remove_address_handler() returns, @handler->callback() is
+ * guaranteed to not run on any CPU anymore.
  */
 void fw_core_remove_address_handler(struct fw_address_handler *handler)
 {
@@ -838,16 +841,16 @@ static void handle_exclusive_region_request(struct fw_card *card,
 	spin_lock_irqsave(&address_handler_lock, flags);
 	handler = lookup_enclosing_address_handler(&address_handler_list,
 						   offset, request->length);
-	spin_unlock_irqrestore(&address_handler_lock, flags);
-
-	if (handler == NULL)
-		fw_send_response(card, request, RCODE_ADDRESS_ERROR);
-	else
+	if (handler)
 		handler->address_callback(card, request,
 					  tcode, destination, source,
 					  p->generation, offset,
 					  request->data, request->length,
 					  handler->callback_data);
+	spin_unlock_irqrestore(&address_handler_lock, flags);
+
+	if (!handler)
+		fw_send_response(card, request, RCODE_ADDRESS_ERROR);
 }
 
 static void handle_fcp_region_request(struct fw_card *card,