diff options
author | Julian Anastasov <ja@ssi.bg> | 2013-03-21 05:58:08 -0400 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2013-04-01 18:23:43 -0400 |
commit | 276472eae063d717b775fdfc87529937402d0e08 (patch) | |
tree | 666e19bc85d1d9d87147aa657e40f3868984be32 /include/net/ip_vs.h | |
parent | 363c97d7435ebba8a040f86e29bdec79ee182f0c (diff) |
ipvs: remove rs_lock by using RCU
rs_lock was used to protect rs_table (hash table)
from updaters (under global mutex) and readers (packet handlers).
We can remove rs_lock by using RCU lock for readers. Reclaiming
dest only with kfree_rcu is enough because the readers access
only fields from the ip_vs_dest structure.
Use hlist for rs_table.
As we are now using hlist_del_rcu, introduce in_rs_table
flag as replacement for the list_empty checks which do not
work with RCU. It is needed because only NAT dests are in
the rs_table.
Signed-off-by: Julian Anastasov <ja@ssi.bg>
Signed-off by: Hans Schillstrom <hans@schillstrom.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
Diffstat (limited to 'include/net/ip_vs.h')
-rw-r--r-- | include/net/ip_vs.h | 14 |
1 files changed, 8 insertions, 6 deletions
diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h index 84ca17141a44..b06aa6c939fa 100644 --- a/include/net/ip_vs.h +++ b/include/net/ip_vs.h | |||
@@ -738,7 +738,7 @@ struct ip_vs_dest_dst { | |||
738 | */ | 738 | */ |
739 | struct ip_vs_dest { | 739 | struct ip_vs_dest { |
740 | struct list_head n_list; /* for the dests in the service */ | 740 | struct list_head n_list; /* for the dests in the service */ |
741 | struct list_head d_list; /* for table with all the dests */ | 741 | struct hlist_node d_list; /* for table with all the dests */ |
742 | 742 | ||
743 | u16 af; /* address family */ | 743 | u16 af; /* address family */ |
744 | __be16 port; /* port number of the server */ | 744 | __be16 port; /* port number of the server */ |
@@ -767,6 +767,9 @@ struct ip_vs_dest { | |||
767 | __be16 vport; /* virtual port number */ | 767 | __be16 vport; /* virtual port number */ |
768 | union nf_inet_addr vaddr; /* virtual IP address */ | 768 | union nf_inet_addr vaddr; /* virtual IP address */ |
769 | __u32 vfwmark; /* firewall mark of service */ | 769 | __u32 vfwmark; /* firewall mark of service */ |
770 | |||
771 | struct rcu_head rcu_head; | ||
772 | unsigned int in_rs_table:1; /* we are in rs_table */ | ||
770 | }; | 773 | }; |
771 | 774 | ||
772 | 775 | ||
@@ -897,7 +900,7 @@ struct netns_ipvs { | |||
897 | #define IP_VS_RTAB_SIZE (1 << IP_VS_RTAB_BITS) | 900 | #define IP_VS_RTAB_SIZE (1 << IP_VS_RTAB_BITS) |
898 | #define IP_VS_RTAB_MASK (IP_VS_RTAB_SIZE - 1) | 901 | #define IP_VS_RTAB_MASK (IP_VS_RTAB_SIZE - 1) |
899 | 902 | ||
900 | struct list_head rs_table[IP_VS_RTAB_SIZE]; | 903 | struct hlist_head rs_table[IP_VS_RTAB_SIZE]; |
901 | /* ip_vs_app */ | 904 | /* ip_vs_app */ |
902 | struct list_head app_list; | 905 | struct list_head app_list; |
903 | /* ip_vs_proto */ | 906 | /* ip_vs_proto */ |
@@ -933,7 +936,6 @@ struct netns_ipvs { | |||
933 | 936 | ||
934 | int num_services; /* no of virtual services */ | 937 | int num_services; /* no of virtual services */ |
935 | 938 | ||
936 | rwlock_t rs_lock; /* real services table */ | ||
937 | /* Trash for destinations */ | 939 | /* Trash for destinations */ |
938 | struct list_head dest_trash; | 940 | struct list_head dest_trash; |
939 | /* Service counters */ | 941 | /* Service counters */ |
@@ -1376,9 +1378,9 @@ static inline void ip_vs_service_put(struct ip_vs_service *svc) | |||
1376 | atomic_dec(&svc->usecnt); | 1378 | atomic_dec(&svc->usecnt); |
1377 | } | 1379 | } |
1378 | 1380 | ||
1379 | extern struct ip_vs_dest * | 1381 | extern bool |
1380 | ip_vs_lookup_real_service(struct net *net, int af, __u16 protocol, | 1382 | ip_vs_has_real_service(struct net *net, int af, __u16 protocol, |
1381 | const union nf_inet_addr *daddr, __be16 dport); | 1383 | const union nf_inet_addr *daddr, __be16 dport); |
1382 | 1384 | ||
1383 | extern int ip_vs_use_count_inc(void); | 1385 | extern int ip_vs_use_count_inc(void); |
1384 | extern void ip_vs_use_count_dec(void); | 1386 | extern void ip_vs_use_count_dec(void); |