From 932bc4d7a53ba418de67fdab533248df5b36c752 Mon Sep 17 00:00:00 2001 From: Julian Anastasov Date: Thu, 21 Mar 2013 11:57:58 +0200 Subject: net: add skb_dst_set_noref_force Rename skb_dst_set_noref to __skb_dst_set_noref and add force flag as suggested by David Miller. The new wrapper skb_dst_set_noref_force will force dst entries that are not cached to be attached as skb dst without taking reference as long as provided dst is reclaimed after RCU grace period. Signed-off-by: Julian Anastasov Signed-off by: Hans Schillstrom Acked-by: David S. Miller Signed-off-by: Simon Horman --- include/linux/skbuff.h | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) (limited to 'include/linux/skbuff.h') diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 878e0ee81068..364e2440a7ee 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -575,7 +575,40 @@ static inline void skb_dst_set(struct sk_buff *skb, struct dst_entry *dst) skb->_skb_refdst = (unsigned long)dst; } -extern void skb_dst_set_noref(struct sk_buff *skb, struct dst_entry *dst); +extern void __skb_dst_set_noref(struct sk_buff *skb, struct dst_entry *dst, + bool force); + +/** + * skb_dst_set_noref - sets skb dst, hopefully, without taking reference + * @skb: buffer + * @dst: dst entry + * + * Sets skb dst, assuming a reference was not taken on dst. + * If dst entry is cached, we do not take reference and dst_release + * will be avoided by refdst_drop. If dst entry is not cached, we take + * reference, so that last dst_release can destroy the dst immediately. + */ +static inline void skb_dst_set_noref(struct sk_buff *skb, struct dst_entry *dst) +{ + __skb_dst_set_noref(skb, dst, false); +} + +/** + * skb_dst_set_noref_force - sets skb dst, without taking reference + * @skb: buffer + * @dst: dst entry + * + * Sets skb dst, assuming a reference was not taken on dst. + * No reference is taken and no dst_release will be called. While for + * cached dsts deferred reclaim is a basic feature, for entries that are + * not cached it is caller's job to guarantee that last dst_release for + * provided dst happens when nobody uses it, eg. after a RCU grace period. + */ +static inline void skb_dst_set_noref_force(struct sk_buff *skb, + struct dst_entry *dst) +{ + __skb_dst_set_noref(skb, dst, true); +} /** * skb_dst_is_noref - Test if skb dst isn't refcounted -- cgit v1.2.3