Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fca9c20a authored by Julian Anastasov's avatar Julian Anastasov Committed by Pablo Neira Ayuso
Browse files

ipvs: add ip_vs_dest_hold and ip_vs_dest_put



ip_vs_dest_hold will be used under RCU lock
while ip_vs_dest_put can be called even after dest
is removed from service, as it happens for conns and
some schedulers.

Signed-off-by: default avatarJulian Anastasov <ja@ssi.bg>
Signed-off-by: default avatarSimon Horman <horms@verge.net.au>
parent 6b6df466
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -1427,6 +1427,16 @@ ip_vs_find_dest(struct net *net, int af, const union nf_inet_addr *daddr,
		__u16 protocol, __u32 fwmark, __u32 flags);
extern struct ip_vs_dest *ip_vs_try_bind_dest(struct ip_vs_conn *cp);

static inline void ip_vs_dest_hold(struct ip_vs_dest *dest)
{
	atomic_inc(&dest->refcnt);
}

static inline void ip_vs_dest_put(struct ip_vs_dest *dest)
{
	smp_mb__before_atomic_dec();
	atomic_dec(&dest->refcnt);
}

/*
 *      IPVS sync daemon data and function prototypes
+2 −7
Original line number Diff line number Diff line
@@ -554,7 +554,7 @@ ip_vs_bind_dest(struct ip_vs_conn *cp, struct ip_vs_dest *dest)
		return;

	/* Increase the refcnt counter of the dest */
	atomic_inc(&dest->refcnt);
	ip_vs_dest_hold(dest);

	conn_flags = atomic_read(&dest->conn_flags);
	if (cp->protocol != IPPROTO_UDP)
@@ -700,12 +700,7 @@ static inline void ip_vs_unbind_dest(struct ip_vs_conn *cp)
			dest->flags &= ~IP_VS_DEST_F_OVERLOAD;
	}

	/*
	 * Simply decrease the refcnt of the dest, because the
	 * dest will be either in service's destination list
	 * or in the trash.
	 */
	atomic_dec(&dest->refcnt);
	ip_vs_dest_put(dest);
}

static int expire_quiescent_template(struct netns_ipvs *ipvs,
+2 −2
Original line number Diff line number Diff line
@@ -616,7 +616,7 @@ struct ip_vs_dest *ip_vs_find_dest(struct net *net, int af,
	if (!dest)
		dest = ip_vs_lookup_dest(svc, daddr, port ^ dport);
	if (dest)
		atomic_inc(&dest->refcnt);
		ip_vs_dest_hold(dest);
	ip_vs_service_put(svc);
	return dest;
}
@@ -1056,7 +1056,7 @@ static void __ip_vs_del_dest(struct net *net, struct ip_vs_dest *dest)
			      ntohs(dest->port),
			      atomic_read(&dest->refcnt));
		list_add(&dest->n_list, &ipvs->dest_trash);
		atomic_inc(&dest->refcnt);
		ip_vs_dest_hold(dest);
	}
}

+2 −2
Original line number Diff line number Diff line
@@ -861,7 +861,7 @@ static void ip_vs_proc_conn(struct net *net, struct ip_vs_conn_param *param,
		if (!dest) {
			dest = ip_vs_try_bind_dest(cp);
			if (dest)
				atomic_dec(&dest->refcnt);
				ip_vs_dest_put(dest);
		}
	} else {
		/*
@@ -874,7 +874,7 @@ static void ip_vs_proc_conn(struct net *net, struct ip_vs_conn_param *param,

		cp = ip_vs_conn_new(param, daddr, dport, flags, dest, fwmark);
		if (dest)
			atomic_dec(&dest->refcnt);
			ip_vs_dest_put(dest);
		if (!cp) {
			if (param->pe_data)
				kfree(param->pe_data);