ipvs: convert connection locking
Convert __ip_vs_conntbl_lock_array as follows: - readers that do not modify conn lists will use RCU lock - updaters that modify lists will use spinlock_t Now for conn lookups we will use RCU read-side critical section. Without using __ip_vs_conn_get such places have access to connection fields and can dereference some pointers like pe and pe_data plus the ability to update timer expiration. If full access is required we contend for reference. We add barrier in __ip_vs_conn_put, so that other CPUs see the refcnt operation after other writes. With the introduction of ip_vs_conn_unlink() we try to reorganize ip_vs_conn_expire(), so that unhashing of connections that should stay more time is avoided, even if it is for very short time. 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>
This commit is contained in:

committed by
Pablo Neira Ayuso

parent
60b6aa3b31
commit
088339a57d
@@ -620,6 +620,8 @@ struct ip_vs_conn {
|
||||
const struct ip_vs_pe *pe;
|
||||
char *pe_data;
|
||||
__u8 pe_data_len;
|
||||
|
||||
struct rcu_head rcu_head;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -1185,9 +1187,19 @@ struct ip_vs_conn * ip_vs_conn_out_get_proto(int af, const struct sk_buff *skb,
|
||||
const struct ip_vs_iphdr *iph,
|
||||
int inverse);
|
||||
|
||||
/* Get reference to gain full access to conn.
|
||||
* By default, RCU read-side critical sections have access only to
|
||||
* conn fields and its PE data, see ip_vs_conn_rcu_free() for reference.
|
||||
*/
|
||||
static inline bool __ip_vs_conn_get(struct ip_vs_conn *cp)
|
||||
{
|
||||
return atomic_inc_not_zero(&cp->refcnt);
|
||||
}
|
||||
|
||||
/* put back the conn without restarting its timer */
|
||||
static inline void __ip_vs_conn_put(struct ip_vs_conn *cp)
|
||||
{
|
||||
smp_mb__before_atomic_dec();
|
||||
atomic_dec(&cp->refcnt);
|
||||
}
|
||||
extern void ip_vs_conn_put(struct ip_vs_conn *cp);
|
||||
|
Reference in New Issue
Block a user