diff options
author | Eric Dumazet <eric.dumazet@gmail.com> | 2010-10-28 23:09:24 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-11-08 16:50:08 -0500 |
commit | fc766e4c4965915ab52a1d1fa3c7a7b3e7bc07f0 (patch) | |
tree | d45160f52eea37d4e5149d511c3c577bef253801 /net/decnet/dn_dev.c | |
parent | e4a7b93bd5d84e1e79917d024d17d745d190fc9a (diff) |
decnet: RCU conversion and get rid of dev_base_lock
While tracking dev_base_lock users, I found decnet used it in
dnet_select_source(), but for a wrong purpose:
Writers only hold RTNL, not dev_base_lock, so readers must use RCU if
they cannot use RTNL.
Adds an rcu_head in struct dn_ifaddr and handle proper RCU management.
Adds __rcu annotation in dn_route as well.
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Acked-by: Steven Whitehouse <swhiteho@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/decnet/dn_dev.c')
-rw-r--r-- | net/decnet/dn_dev.c | 100 |
1 files changed, 59 insertions, 41 deletions
diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c index 4c409b46aa35..0ba15633c418 100644 --- a/net/decnet/dn_dev.c +++ b/net/decnet/dn_dev.c | |||
@@ -267,7 +267,7 @@ static int dn_forwarding_proc(ctl_table *table, int write, | |||
267 | if (table->extra1 == NULL) | 267 | if (table->extra1 == NULL) |
268 | return -EINVAL; | 268 | return -EINVAL; |
269 | 269 | ||
270 | dn_db = dev->dn_ptr; | 270 | dn_db = rcu_dereference_raw(dev->dn_ptr); |
271 | old = dn_db->parms.forwarding; | 271 | old = dn_db->parms.forwarding; |
272 | 272 | ||
273 | err = proc_dointvec(table, write, buffer, lenp, ppos); | 273 | err = proc_dointvec(table, write, buffer, lenp, ppos); |
@@ -332,14 +332,19 @@ static struct dn_ifaddr *dn_dev_alloc_ifa(void) | |||
332 | return ifa; | 332 | return ifa; |
333 | } | 333 | } |
334 | 334 | ||
335 | static __inline__ void dn_dev_free_ifa(struct dn_ifaddr *ifa) | 335 | static void dn_dev_free_ifa_rcu(struct rcu_head *head) |
336 | { | 336 | { |
337 | kfree(ifa); | 337 | kfree(container_of(head, struct dn_ifaddr, rcu)); |
338 | } | 338 | } |
339 | 339 | ||
340 | static void dn_dev_del_ifa(struct dn_dev *dn_db, struct dn_ifaddr **ifap, int destroy) | 340 | static void dn_dev_free_ifa(struct dn_ifaddr *ifa) |
341 | { | 341 | { |
342 | struct dn_ifaddr *ifa1 = *ifap; | 342 | call_rcu(&ifa->rcu, dn_dev_free_ifa_rcu); |
343 | } | ||
344 | |||
345 | static void dn_dev_del_ifa(struct dn_dev *dn_db, struct dn_ifaddr __rcu **ifap, int destroy) | ||
346 | { | ||
347 | struct dn_ifaddr *ifa1 = rtnl_dereference(*ifap); | ||
343 | unsigned char mac_addr[6]; | 348 | unsigned char mac_addr[6]; |
344 | struct net_device *dev = dn_db->dev; | 349 | struct net_device *dev = dn_db->dev; |
345 | 350 | ||
@@ -373,7 +378,9 @@ static int dn_dev_insert_ifa(struct dn_dev *dn_db, struct dn_ifaddr *ifa) | |||
373 | ASSERT_RTNL(); | 378 | ASSERT_RTNL(); |
374 | 379 | ||
375 | /* Check for duplicates */ | 380 | /* Check for duplicates */ |
376 | for(ifa1 = dn_db->ifa_list; ifa1; ifa1 = ifa1->ifa_next) { | 381 | for (ifa1 = rtnl_dereference(dn_db->ifa_list); |
382 | ifa1 != NULL; | ||
383 | ifa1 = rtnl_dereference(ifa1->ifa_next)) { | ||
377 | if (ifa1->ifa_local == ifa->ifa_local) | 384 | if (ifa1->ifa_local == ifa->ifa_local) |
378 | return -EEXIST; | 385 | return -EEXIST; |
379 | } | 386 | } |
@@ -386,7 +393,7 @@ static int dn_dev_insert_ifa(struct dn_dev *dn_db, struct dn_ifaddr *ifa) | |||
386 | } | 393 | } |
387 | 394 | ||
388 | ifa->ifa_next = dn_db->ifa_list; | 395 | ifa->ifa_next = dn_db->ifa_list; |
389 | dn_db->ifa_list = ifa; | 396 | rcu_assign_pointer(dn_db->ifa_list, ifa); |
390 | 397 | ||
391 | dn_ifaddr_notify(RTM_NEWADDR, ifa); | 398 | dn_ifaddr_notify(RTM_NEWADDR, ifa); |
392 | blocking_notifier_call_chain(&dnaddr_chain, NETDEV_UP, ifa); | 399 | blocking_notifier_call_chain(&dnaddr_chain, NETDEV_UP, ifa); |
@@ -396,7 +403,7 @@ static int dn_dev_insert_ifa(struct dn_dev *dn_db, struct dn_ifaddr *ifa) | |||
396 | 403 | ||
397 | static int dn_dev_set_ifa(struct net_device *dev, struct dn_ifaddr *ifa) | 404 | static int dn_dev_set_ifa(struct net_device *dev, struct dn_ifaddr *ifa) |
398 | { | 405 | { |
399 | struct dn_dev *dn_db = dev->dn_ptr; | 406 | struct dn_dev *dn_db = rtnl_dereference(dev->dn_ptr); |
400 | int rv; | 407 | int rv; |
401 | 408 | ||
402 | if (dn_db == NULL) { | 409 | if (dn_db == NULL) { |
@@ -425,7 +432,8 @@ int dn_dev_ioctl(unsigned int cmd, void __user *arg) | |||
425 | struct sockaddr_dn *sdn = (struct sockaddr_dn *)&ifr->ifr_addr; | 432 | struct sockaddr_dn *sdn = (struct sockaddr_dn *)&ifr->ifr_addr; |
426 | struct dn_dev *dn_db; | 433 | struct dn_dev *dn_db; |
427 | struct net_device *dev; | 434 | struct net_device *dev; |
428 | struct dn_ifaddr *ifa = NULL, **ifap = NULL; | 435 | struct dn_ifaddr *ifa = NULL; |
436 | struct dn_ifaddr __rcu **ifap = NULL; | ||
429 | int ret = 0; | 437 | int ret = 0; |
430 | 438 | ||
431 | if (copy_from_user(ifr, arg, DN_IFREQ_SIZE)) | 439 | if (copy_from_user(ifr, arg, DN_IFREQ_SIZE)) |
@@ -454,8 +462,10 @@ int dn_dev_ioctl(unsigned int cmd, void __user *arg) | |||
454 | goto done; | 462 | goto done; |
455 | } | 463 | } |
456 | 464 | ||
457 | if ((dn_db = dev->dn_ptr) != NULL) { | 465 | if ((dn_db = rtnl_dereference(dev->dn_ptr)) != NULL) { |
458 | for (ifap = &dn_db->ifa_list; (ifa=*ifap) != NULL; ifap = &ifa->ifa_next) | 466 | for (ifap = &dn_db->ifa_list; |
467 | (ifa = rtnl_dereference(*ifap)) != NULL; | ||
468 | ifap = &ifa->ifa_next) | ||
459 | if (strcmp(ifr->ifr_name, ifa->ifa_label) == 0) | 469 | if (strcmp(ifr->ifr_name, ifa->ifa_label) == 0) |
460 | break; | 470 | break; |
461 | } | 471 | } |
@@ -558,7 +568,7 @@ static struct dn_dev *dn_dev_by_index(int ifindex) | |||
558 | 568 | ||
559 | dev = __dev_get_by_index(&init_net, ifindex); | 569 | dev = __dev_get_by_index(&init_net, ifindex); |
560 | if (dev) | 570 | if (dev) |
561 | dn_dev = dev->dn_ptr; | 571 | dn_dev = rtnl_dereference(dev->dn_ptr); |
562 | 572 | ||
563 | return dn_dev; | 573 | return dn_dev; |
564 | } | 574 | } |
@@ -576,7 +586,8 @@ static int dn_nl_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
576 | struct nlattr *tb[IFA_MAX+1]; | 586 | struct nlattr *tb[IFA_MAX+1]; |
577 | struct dn_dev *dn_db; | 587 | struct dn_dev *dn_db; |
578 | struct ifaddrmsg *ifm; | 588 | struct ifaddrmsg *ifm; |
579 | struct dn_ifaddr *ifa, **ifap; | 589 | struct dn_ifaddr *ifa; |
590 | struct dn_ifaddr __rcu **ifap; | ||
580 | int err = -EINVAL; | 591 | int err = -EINVAL; |
581 | 592 | ||
582 | if (!net_eq(net, &init_net)) | 593 | if (!net_eq(net, &init_net)) |
@@ -592,7 +603,9 @@ static int dn_nl_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
592 | goto errout; | 603 | goto errout; |
593 | 604 | ||
594 | err = -EADDRNOTAVAIL; | 605 | err = -EADDRNOTAVAIL; |
595 | for (ifap = &dn_db->ifa_list; (ifa = *ifap); ifap = &ifa->ifa_next) { | 606 | for (ifap = &dn_db->ifa_list; |
607 | (ifa = rtnl_dereference(*ifap)) != NULL; | ||
608 | ifap = &ifa->ifa_next) { | ||
596 | if (tb[IFA_LOCAL] && | 609 | if (tb[IFA_LOCAL] && |
597 | nla_memcmp(tb[IFA_LOCAL], &ifa->ifa_local, 2)) | 610 | nla_memcmp(tb[IFA_LOCAL], &ifa->ifa_local, 2)) |
598 | continue; | 611 | continue; |
@@ -632,7 +645,7 @@ static int dn_nl_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
632 | if ((dev = __dev_get_by_index(&init_net, ifm->ifa_index)) == NULL) | 645 | if ((dev = __dev_get_by_index(&init_net, ifm->ifa_index)) == NULL) |
633 | return -ENODEV; | 646 | return -ENODEV; |
634 | 647 | ||
635 | if ((dn_db = dev->dn_ptr) == NULL) { | 648 | if ((dn_db = rtnl_dereference(dev->dn_ptr)) == NULL) { |
636 | dn_db = dn_dev_create(dev, &err); | 649 | dn_db = dn_dev_create(dev, &err); |
637 | if (!dn_db) | 650 | if (!dn_db) |
638 | return err; | 651 | return err; |
@@ -748,11 +761,11 @@ static int dn_nl_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb) | |||
748 | skip_naddr = 0; | 761 | skip_naddr = 0; |
749 | } | 762 | } |
750 | 763 | ||
751 | if ((dn_db = dev->dn_ptr) == NULL) | 764 | if ((dn_db = rtnl_dereference(dev->dn_ptr)) == NULL) |
752 | goto cont; | 765 | goto cont; |
753 | 766 | ||
754 | for (ifa = dn_db->ifa_list, dn_idx = 0; ifa; | 767 | for (ifa = rtnl_dereference(dn_db->ifa_list), dn_idx = 0; ifa; |
755 | ifa = ifa->ifa_next, dn_idx++) { | 768 | ifa = rtnl_dereference(ifa->ifa_next), dn_idx++) { |
756 | if (dn_idx < skip_naddr) | 769 | if (dn_idx < skip_naddr) |
757 | continue; | 770 | continue; |
758 | 771 | ||
@@ -773,21 +786,22 @@ done: | |||
773 | 786 | ||
774 | static int dn_dev_get_first(struct net_device *dev, __le16 *addr) | 787 | static int dn_dev_get_first(struct net_device *dev, __le16 *addr) |
775 | { | 788 | { |
776 | struct dn_dev *dn_db = (struct dn_dev *)dev->dn_ptr; | 789 | struct dn_dev *dn_db; |
777 | struct dn_ifaddr *ifa; | 790 | struct dn_ifaddr *ifa; |
778 | int rv = -ENODEV; | 791 | int rv = -ENODEV; |
779 | 792 | ||
793 | rcu_read_lock(); | ||
794 | dn_db = rcu_dereference(dev->dn_ptr); | ||
780 | if (dn_db == NULL) | 795 | if (dn_db == NULL) |
781 | goto out; | 796 | goto out; |
782 | 797 | ||
783 | rtnl_lock(); | 798 | ifa = rcu_dereference(dn_db->ifa_list); |
784 | ifa = dn_db->ifa_list; | ||
785 | if (ifa != NULL) { | 799 | if (ifa != NULL) { |
786 | *addr = ifa->ifa_local; | 800 | *addr = ifa->ifa_local; |
787 | rv = 0; | 801 | rv = 0; |
788 | } | 802 | } |
789 | rtnl_unlock(); | ||
790 | out: | 803 | out: |
804 | rcu_read_unlock(); | ||
791 | return rv; | 805 | return rv; |
792 | } | 806 | } |
793 | 807 | ||
@@ -823,7 +837,7 @@ static void dn_send_endnode_hello(struct net_device *dev, struct dn_ifaddr *ifa) | |||
823 | struct endnode_hello_message *msg; | 837 | struct endnode_hello_message *msg; |
824 | struct sk_buff *skb = NULL; | 838 | struct sk_buff *skb = NULL; |
825 | __le16 *pktlen; | 839 | __le16 *pktlen; |
826 | struct dn_dev *dn_db = (struct dn_dev *)dev->dn_ptr; | 840 | struct dn_dev *dn_db = rcu_dereference_raw(dev->dn_ptr); |
827 | 841 | ||
828 | if ((skb = dn_alloc_skb(NULL, sizeof(*msg), GFP_ATOMIC)) == NULL) | 842 | if ((skb = dn_alloc_skb(NULL, sizeof(*msg), GFP_ATOMIC)) == NULL) |
829 | return; | 843 | return; |
@@ -889,7 +903,7 @@ static int dn_am_i_a_router(struct dn_neigh *dn, struct dn_dev *dn_db, struct dn | |||
889 | static void dn_send_router_hello(struct net_device *dev, struct dn_ifaddr *ifa) | 903 | static void dn_send_router_hello(struct net_device *dev, struct dn_ifaddr *ifa) |
890 | { | 904 | { |
891 | int n; | 905 | int n; |
892 | struct dn_dev *dn_db = dev->dn_ptr; | 906 | struct dn_dev *dn_db = rcu_dereference_raw(dev->dn_ptr); |
893 | struct dn_neigh *dn = (struct dn_neigh *)dn_db->router; | 907 | struct dn_neigh *dn = (struct dn_neigh *)dn_db->router; |
894 | struct sk_buff *skb; | 908 | struct sk_buff *skb; |
895 | size_t size; | 909 | size_t size; |
@@ -960,7 +974,7 @@ static void dn_send_router_hello(struct net_device *dev, struct dn_ifaddr *ifa) | |||
960 | 974 | ||
961 | static void dn_send_brd_hello(struct net_device *dev, struct dn_ifaddr *ifa) | 975 | static void dn_send_brd_hello(struct net_device *dev, struct dn_ifaddr *ifa) |
962 | { | 976 | { |
963 | struct dn_dev *dn_db = (struct dn_dev *)dev->dn_ptr; | 977 | struct dn_dev *dn_db = rcu_dereference_raw(dev->dn_ptr); |
964 | 978 | ||
965 | if (dn_db->parms.forwarding == 0) | 979 | if (dn_db->parms.forwarding == 0) |
966 | dn_send_endnode_hello(dev, ifa); | 980 | dn_send_endnode_hello(dev, ifa); |
@@ -998,7 +1012,7 @@ static void dn_send_ptp_hello(struct net_device *dev, struct dn_ifaddr *ifa) | |||
998 | 1012 | ||
999 | static int dn_eth_up(struct net_device *dev) | 1013 | static int dn_eth_up(struct net_device *dev) |
1000 | { | 1014 | { |
1001 | struct dn_dev *dn_db = dev->dn_ptr; | 1015 | struct dn_dev *dn_db = rcu_dereference_raw(dev->dn_ptr); |
1002 | 1016 | ||
1003 | if (dn_db->parms.forwarding == 0) | 1017 | if (dn_db->parms.forwarding == 0) |
1004 | dev_mc_add(dev, dn_rt_all_end_mcast); | 1018 | dev_mc_add(dev, dn_rt_all_end_mcast); |
@@ -1012,7 +1026,7 @@ static int dn_eth_up(struct net_device *dev) | |||
1012 | 1026 | ||
1013 | static void dn_eth_down(struct net_device *dev) | 1027 | static void dn_eth_down(struct net_device *dev) |
1014 | { | 1028 | { |
1015 | struct dn_dev *dn_db = dev->dn_ptr; | 1029 | struct dn_dev *dn_db = rcu_dereference_raw(dev->dn_ptr); |
1016 | 1030 | ||
1017 | if (dn_db->parms.forwarding == 0) | 1031 | if (dn_db->parms.forwarding == 0) |
1018 | dev_mc_del(dev, dn_rt_all_end_mcast); | 1032 | dev_mc_del(dev, dn_rt_all_end_mcast); |
@@ -1025,12 +1039,16 @@ static void dn_dev_set_timer(struct net_device *dev); | |||
1025 | static void dn_dev_timer_func(unsigned long arg) | 1039 | static void dn_dev_timer_func(unsigned long arg) |
1026 | { | 1040 | { |
1027 | struct net_device *dev = (struct net_device *)arg; | 1041 | struct net_device *dev = (struct net_device *)arg; |
1028 | struct dn_dev *dn_db = dev->dn_ptr; | 1042 | struct dn_dev *dn_db; |
1029 | struct dn_ifaddr *ifa; | 1043 | struct dn_ifaddr *ifa; |
1030 | 1044 | ||
1045 | rcu_read_lock(); | ||
1046 | dn_db = rcu_dereference(dev->dn_ptr); | ||
1031 | if (dn_db->t3 <= dn_db->parms.t2) { | 1047 | if (dn_db->t3 <= dn_db->parms.t2) { |
1032 | if (dn_db->parms.timer3) { | 1048 | if (dn_db->parms.timer3) { |
1033 | for(ifa = dn_db->ifa_list; ifa; ifa = ifa->ifa_next) { | 1049 | for (ifa = rcu_dereference(dn_db->ifa_list); |
1050 | ifa; | ||
1051 | ifa = rcu_dereference(ifa->ifa_next)) { | ||
1034 | if (!(ifa->ifa_flags & IFA_F_SECONDARY)) | 1052 | if (!(ifa->ifa_flags & IFA_F_SECONDARY)) |
1035 | dn_db->parms.timer3(dev, ifa); | 1053 | dn_db->parms.timer3(dev, ifa); |
1036 | } | 1054 | } |
@@ -1039,13 +1057,13 @@ static void dn_dev_timer_func(unsigned long arg) | |||
1039 | } else { | 1057 | } else { |
1040 | dn_db->t3 -= dn_db->parms.t2; | 1058 | dn_db->t3 -= dn_db->parms.t2; |
1041 | } | 1059 | } |
1042 | 1060 | rcu_read_unlock(); | |
1043 | dn_dev_set_timer(dev); | 1061 | dn_dev_set_timer(dev); |
1044 | } | 1062 | } |
1045 | 1063 | ||
1046 | static void dn_dev_set_timer(struct net_device *dev) | 1064 | static void dn_dev_set_timer(struct net_device *dev) |
1047 | { | 1065 | { |
1048 | struct dn_dev *dn_db = dev->dn_ptr; | 1066 | struct dn_dev *dn_db = rcu_dereference_raw(dev->dn_ptr); |
1049 | 1067 | ||
1050 | if (dn_db->parms.t2 > dn_db->parms.t3) | 1068 | if (dn_db->parms.t2 > dn_db->parms.t3) |
1051 | dn_db->parms.t2 = dn_db->parms.t3; | 1069 | dn_db->parms.t2 = dn_db->parms.t3; |
@@ -1077,8 +1095,8 @@ static struct dn_dev *dn_dev_create(struct net_device *dev, int *err) | |||
1077 | return NULL; | 1095 | return NULL; |
1078 | 1096 | ||
1079 | memcpy(&dn_db->parms, p, sizeof(struct dn_dev_parms)); | 1097 | memcpy(&dn_db->parms, p, sizeof(struct dn_dev_parms)); |
1080 | smp_wmb(); | 1098 | |
1081 | dev->dn_ptr = dn_db; | 1099 | rcu_assign_pointer(dev->dn_ptr, dn_db); |
1082 | dn_db->dev = dev; | 1100 | dn_db->dev = dev; |
1083 | init_timer(&dn_db->timer); | 1101 | init_timer(&dn_db->timer); |
1084 | 1102 | ||
@@ -1086,7 +1104,7 @@ static struct dn_dev *dn_dev_create(struct net_device *dev, int *err) | |||
1086 | 1104 | ||
1087 | dn_db->neigh_parms = neigh_parms_alloc(dev, &dn_neigh_table); | 1105 | dn_db->neigh_parms = neigh_parms_alloc(dev, &dn_neigh_table); |
1088 | if (!dn_db->neigh_parms) { | 1106 | if (!dn_db->neigh_parms) { |
1089 | dev->dn_ptr = NULL; | 1107 | rcu_assign_pointer(dev->dn_ptr, NULL); |
1090 | kfree(dn_db); | 1108 | kfree(dn_db); |
1091 | return NULL; | 1109 | return NULL; |
1092 | } | 1110 | } |
@@ -1125,7 +1143,7 @@ void dn_dev_up(struct net_device *dev) | |||
1125 | struct dn_ifaddr *ifa; | 1143 | struct dn_ifaddr *ifa; |
1126 | __le16 addr = decnet_address; | 1144 | __le16 addr = decnet_address; |
1127 | int maybe_default = 0; | 1145 | int maybe_default = 0; |
1128 | struct dn_dev *dn_db = (struct dn_dev *)dev->dn_ptr; | 1146 | struct dn_dev *dn_db = rtnl_dereference(dev->dn_ptr); |
1129 | 1147 | ||
1130 | if ((dev->type != ARPHRD_ETHER) && (dev->type != ARPHRD_LOOPBACK)) | 1148 | if ((dev->type != ARPHRD_ETHER) && (dev->type != ARPHRD_LOOPBACK)) |
1131 | return; | 1149 | return; |
@@ -1176,7 +1194,7 @@ void dn_dev_up(struct net_device *dev) | |||
1176 | 1194 | ||
1177 | static void dn_dev_delete(struct net_device *dev) | 1195 | static void dn_dev_delete(struct net_device *dev) |
1178 | { | 1196 | { |
1179 | struct dn_dev *dn_db = dev->dn_ptr; | 1197 | struct dn_dev *dn_db = rtnl_dereference(dev->dn_ptr); |
1180 | 1198 | ||
1181 | if (dn_db == NULL) | 1199 | if (dn_db == NULL) |
1182 | return; | 1200 | return; |
@@ -1204,13 +1222,13 @@ static void dn_dev_delete(struct net_device *dev) | |||
1204 | 1222 | ||
1205 | void dn_dev_down(struct net_device *dev) | 1223 | void dn_dev_down(struct net_device *dev) |
1206 | { | 1224 | { |
1207 | struct dn_dev *dn_db = dev->dn_ptr; | 1225 | struct dn_dev *dn_db = rtnl_dereference(dev->dn_ptr); |
1208 | struct dn_ifaddr *ifa; | 1226 | struct dn_ifaddr *ifa; |
1209 | 1227 | ||
1210 | if (dn_db == NULL) | 1228 | if (dn_db == NULL) |
1211 | return; | 1229 | return; |
1212 | 1230 | ||
1213 | while((ifa = dn_db->ifa_list) != NULL) { | 1231 | while ((ifa = rtnl_dereference(dn_db->ifa_list)) != NULL) { |
1214 | dn_dev_del_ifa(dn_db, &dn_db->ifa_list, 0); | 1232 | dn_dev_del_ifa(dn_db, &dn_db->ifa_list, 0); |
1215 | dn_dev_free_ifa(ifa); | 1233 | dn_dev_free_ifa(ifa); |
1216 | } | 1234 | } |
@@ -1270,7 +1288,7 @@ static inline int is_dn_dev(struct net_device *dev) | |||
1270 | } | 1288 | } |
1271 | 1289 | ||
1272 | static void *dn_dev_seq_start(struct seq_file *seq, loff_t *pos) | 1290 | static void *dn_dev_seq_start(struct seq_file *seq, loff_t *pos) |
1273 | __acquires(rcu) | 1291 | __acquires(RCU) |
1274 | { | 1292 | { |
1275 | int i; | 1293 | int i; |
1276 | struct net_device *dev; | 1294 | struct net_device *dev; |
@@ -1313,7 +1331,7 @@ static void *dn_dev_seq_next(struct seq_file *seq, void *v, loff_t *pos) | |||
1313 | } | 1331 | } |
1314 | 1332 | ||
1315 | static void dn_dev_seq_stop(struct seq_file *seq, void *v) | 1333 | static void dn_dev_seq_stop(struct seq_file *seq, void *v) |
1316 | __releases(rcu) | 1334 | __releases(RCU) |
1317 | { | 1335 | { |
1318 | rcu_read_unlock(); | 1336 | rcu_read_unlock(); |
1319 | } | 1337 | } |
@@ -1340,7 +1358,7 @@ static int dn_dev_seq_show(struct seq_file *seq, void *v) | |||
1340 | struct net_device *dev = v; | 1358 | struct net_device *dev = v; |
1341 | char peer_buf[DN_ASCBUF_LEN]; | 1359 | char peer_buf[DN_ASCBUF_LEN]; |
1342 | char router_buf[DN_ASCBUF_LEN]; | 1360 | char router_buf[DN_ASCBUF_LEN]; |
1343 | struct dn_dev *dn_db = dev->dn_ptr; | 1361 | struct dn_dev *dn_db = rcu_dereference(dev->dn_ptr); |
1344 | 1362 | ||
1345 | seq_printf(seq, "%-8s %1s %04u %04u %04lu %04lu" | 1363 | seq_printf(seq, "%-8s %1s %04u %04u %04lu %04lu" |
1346 | " %04hu %03d %02x %-10s %-7s %-7s\n", | 1364 | " %04hu %03d %02x %-10s %-7s %-7s\n", |