diff options
Diffstat (limited to 'include/linux/skbuff.h')
| -rw-r--r-- | include/linux/skbuff.h | 36 | 
1 files changed, 26 insertions, 10 deletions
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 7914fdaf4226..64a395c7f689 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -1354,7 +1354,8 @@ static inline __u32 skb_get_hash_flowi6(struct sk_buff *skb, const struct flowi6  	return skb->hash;  } -__u32 skb_get_hash_perturb(const struct sk_buff *skb, u32 perturb); +__u32 skb_get_hash_perturb(const struct sk_buff *skb, +			   const siphash_key_t *perturb);  static inline __u32 skb_get_hash_raw(const struct sk_buff *skb)  { @@ -1495,6 +1496,19 @@ static inline int skb_queue_empty(const struct sk_buff_head *list)  }  /** + *	skb_queue_empty_lockless - check if a queue is empty + *	@list: queue head + * + *	Returns true if the queue is empty, false otherwise. + *	This variant can be used in lockless contexts. + */ +static inline bool skb_queue_empty_lockless(const struct sk_buff_head *list) +{ +	return READ_ONCE(list->next) == (const struct sk_buff *) list; +} + + +/**   *	skb_queue_is_last - check if skb is the last entry in the queue   *	@list: queue head   *	@skb: buffer @@ -1847,9 +1861,11 @@ static inline void __skb_insert(struct sk_buff *newsk,  				struct sk_buff *prev, struct sk_buff *next,  				struct sk_buff_head *list)  { -	newsk->next = next; -	newsk->prev = prev; -	next->prev  = prev->next = newsk; +	/* see skb_queue_empty_lockless() for the opposite READ_ONCE() */ +	WRITE_ONCE(newsk->next, next); +	WRITE_ONCE(newsk->prev, prev); +	WRITE_ONCE(next->prev, newsk); +	WRITE_ONCE(prev->next, newsk);  	list->qlen++;  } @@ -1860,11 +1876,11 @@ static inline void __skb_queue_splice(const struct sk_buff_head *list,  	struct sk_buff *first = list->next;  	struct sk_buff *last = list->prev; -	first->prev = prev; -	prev->next = first; +	WRITE_ONCE(first->prev, prev); +	WRITE_ONCE(prev->next, first); -	last->next = next; -	next->prev = last; +	WRITE_ONCE(last->next, next); +	WRITE_ONCE(next->prev, last);  }  /** @@ -2005,8 +2021,8 @@ static inline void __skb_unlink(struct sk_buff *skb, struct sk_buff_head *list)  	next	   = skb->next;  	prev	   = skb->prev;  	skb->next  = skb->prev = NULL; -	next->prev = prev; -	prev->next = next; +	WRITE_ONCE(next->prev, prev); +	WRITE_ONCE(prev->next, next);  }  /**  | 
