diff options
-rw-r--r-- | drivers/firewire/core-transaction.c | 20 |
1 files changed, 11 insertions, 9 deletions
diff --git a/drivers/firewire/core-transaction.c b/drivers/firewire/core-transaction.c index 87d6f2d2f02d..d39cfa45817a 100644 --- a/drivers/firewire/core-transaction.c +++ b/drivers/firewire/core-transaction.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/kernel.h> | 31 | #include <linux/kernel.h> |
32 | #include <linux/list.h> | 32 | #include <linux/list.h> |
33 | #include <linux/module.h> | 33 | #include <linux/module.h> |
34 | #include <linux/rculist.h> | ||
34 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
35 | #include <linux/spinlock.h> | 36 | #include <linux/spinlock.h> |
36 | #include <linux/string.h> | 37 | #include <linux/string.h> |
@@ -489,7 +490,7 @@ static struct fw_address_handler *lookup_overlapping_address_handler( | |||
489 | { | 490 | { |
490 | struct fw_address_handler *handler; | 491 | struct fw_address_handler *handler; |
491 | 492 | ||
492 | list_for_each_entry(handler, list, link) { | 493 | list_for_each_entry_rcu(handler, list, link) { |
493 | if (handler->offset < offset + length && | 494 | if (handler->offset < offset + length && |
494 | offset < handler->offset + handler->length) | 495 | offset < handler->offset + handler->length) |
495 | return handler; | 496 | return handler; |
@@ -510,7 +511,7 @@ static struct fw_address_handler *lookup_enclosing_address_handler( | |||
510 | { | 511 | { |
511 | struct fw_address_handler *handler; | 512 | struct fw_address_handler *handler; |
512 | 513 | ||
513 | list_for_each_entry(handler, list, link) { | 514 | list_for_each_entry_rcu(handler, list, link) { |
514 | if (is_enclosing_handler(handler, offset, length)) | 515 | if (is_enclosing_handler(handler, offset, length)) |
515 | return handler; | 516 | return handler; |
516 | } | 517 | } |
@@ -588,7 +589,7 @@ int fw_core_add_address_handler(struct fw_address_handler *handler, | |||
588 | if (other != NULL) { | 589 | if (other != NULL) { |
589 | handler->offset += other->length; | 590 | handler->offset += other->length; |
590 | } else { | 591 | } else { |
591 | list_add_tail(&handler->link, &address_handler_list); | 592 | list_add_tail_rcu(&handler->link, &address_handler_list); |
592 | ret = 0; | 593 | ret = 0; |
593 | break; | 594 | break; |
594 | } | 595 | } |
@@ -609,8 +610,9 @@ EXPORT_SYMBOL(fw_core_add_address_handler); | |||
609 | void fw_core_remove_address_handler(struct fw_address_handler *handler) | 610 | void fw_core_remove_address_handler(struct fw_address_handler *handler) |
610 | { | 611 | { |
611 | spin_lock_bh(&address_handler_lock); | 612 | spin_lock_bh(&address_handler_lock); |
612 | list_del(&handler->link); | 613 | list_del_rcu(&handler->link); |
613 | spin_unlock_bh(&address_handler_lock); | 614 | spin_unlock_bh(&address_handler_lock); |
615 | synchronize_rcu(); | ||
614 | } | 616 | } |
615 | EXPORT_SYMBOL(fw_core_remove_address_handler); | 617 | EXPORT_SYMBOL(fw_core_remove_address_handler); |
616 | 618 | ||
@@ -844,7 +846,7 @@ static void handle_exclusive_region_request(struct fw_card *card, | |||
844 | if (tcode == TCODE_LOCK_REQUEST) | 846 | if (tcode == TCODE_LOCK_REQUEST) |
845 | tcode = 0x10 + HEADER_GET_EXTENDED_TCODE(p->header[3]); | 847 | tcode = 0x10 + HEADER_GET_EXTENDED_TCODE(p->header[3]); |
846 | 848 | ||
847 | spin_lock_bh(&address_handler_lock); | 849 | rcu_read_lock(); |
848 | handler = lookup_enclosing_address_handler(&address_handler_list, | 850 | handler = lookup_enclosing_address_handler(&address_handler_list, |
849 | offset, request->length); | 851 | offset, request->length); |
850 | if (handler) | 852 | if (handler) |
@@ -853,7 +855,7 @@ static void handle_exclusive_region_request(struct fw_card *card, | |||
853 | p->generation, offset, | 855 | p->generation, offset, |
854 | request->data, request->length, | 856 | request->data, request->length, |
855 | handler->callback_data); | 857 | handler->callback_data); |
856 | spin_unlock_bh(&address_handler_lock); | 858 | rcu_read_unlock(); |
857 | 859 | ||
858 | if (!handler) | 860 | if (!handler) |
859 | fw_send_response(card, request, RCODE_ADDRESS_ERROR); | 861 | fw_send_response(card, request, RCODE_ADDRESS_ERROR); |
@@ -886,8 +888,8 @@ static void handle_fcp_region_request(struct fw_card *card, | |||
886 | return; | 888 | return; |
887 | } | 889 | } |
888 | 890 | ||
889 | spin_lock_bh(&address_handler_lock); | 891 | rcu_read_lock(); |
890 | list_for_each_entry(handler, &address_handler_list, link) { | 892 | list_for_each_entry_rcu(handler, &address_handler_list, link) { |
891 | if (is_enclosing_handler(handler, offset, request->length)) | 893 | if (is_enclosing_handler(handler, offset, request->length)) |
892 | handler->address_callback(card, NULL, tcode, | 894 | handler->address_callback(card, NULL, tcode, |
893 | destination, source, | 895 | destination, source, |
@@ -896,7 +898,7 @@ static void handle_fcp_region_request(struct fw_card *card, | |||
896 | request->length, | 898 | request->length, |
897 | handler->callback_data); | 899 | handler->callback_data); |
898 | } | 900 | } |
899 | spin_unlock_bh(&address_handler_lock); | 901 | rcu_read_unlock(); |
900 | 902 | ||
901 | fw_send_response(card, request, RCODE_COMPLETE); | 903 | fw_send_response(card, request, RCODE_COMPLETE); |
902 | } | 904 | } |