diff options
| -rw-r--r-- | include/linux/skbuff.h | 33 |
1 files changed, 24 insertions, 9 deletions
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index a391147c03d4..64a395c7f689 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h | |||
| @@ -1496,6 +1496,19 @@ static inline int skb_queue_empty(const struct sk_buff_head *list) | |||
| 1496 | } | 1496 | } |
| 1497 | 1497 | ||
| 1498 | /** | 1498 | /** |
| 1499 | * skb_queue_empty_lockless - check if a queue is empty | ||
| 1500 | * @list: queue head | ||
| 1501 | * | ||
| 1502 | * Returns true if the queue is empty, false otherwise. | ||
| 1503 | * This variant can be used in lockless contexts. | ||
| 1504 | */ | ||
| 1505 | static inline bool skb_queue_empty_lockless(const struct sk_buff_head *list) | ||
| 1506 | { | ||
| 1507 | return READ_ONCE(list->next) == (const struct sk_buff *) list; | ||
| 1508 | } | ||
| 1509 | |||
| 1510 | |||
| 1511 | /** | ||
| 1499 | * skb_queue_is_last - check if skb is the last entry in the queue | 1512 | * skb_queue_is_last - check if skb is the last entry in the queue |
| 1500 | * @list: queue head | 1513 | * @list: queue head |
| 1501 | * @skb: buffer | 1514 | * @skb: buffer |
| @@ -1848,9 +1861,11 @@ static inline void __skb_insert(struct sk_buff *newsk, | |||
| 1848 | struct sk_buff *prev, struct sk_buff *next, | 1861 | struct sk_buff *prev, struct sk_buff *next, |
| 1849 | struct sk_buff_head *list) | 1862 | struct sk_buff_head *list) |
| 1850 | { | 1863 | { |
| 1851 | newsk->next = next; | 1864 | /* see skb_queue_empty_lockless() for the opposite READ_ONCE() */ |
| 1852 | newsk->prev = prev; | 1865 | WRITE_ONCE(newsk->next, next); |
| 1853 | next->prev = prev->next = newsk; | 1866 | WRITE_ONCE(newsk->prev, prev); |
| 1867 | WRITE_ONCE(next->prev, newsk); | ||
| 1868 | WRITE_ONCE(prev->next, newsk); | ||
| 1854 | list->qlen++; | 1869 | list->qlen++; |
| 1855 | } | 1870 | } |
| 1856 | 1871 | ||
| @@ -1861,11 +1876,11 @@ static inline void __skb_queue_splice(const struct sk_buff_head *list, | |||
| 1861 | struct sk_buff *first = list->next; | 1876 | struct sk_buff *first = list->next; |
| 1862 | struct sk_buff *last = list->prev; | 1877 | struct sk_buff *last = list->prev; |
| 1863 | 1878 | ||
| 1864 | first->prev = prev; | 1879 | WRITE_ONCE(first->prev, prev); |
| 1865 | prev->next = first; | 1880 | WRITE_ONCE(prev->next, first); |
| 1866 | 1881 | ||
| 1867 | last->next = next; | 1882 | WRITE_ONCE(last->next, next); |
| 1868 | next->prev = last; | 1883 | WRITE_ONCE(next->prev, last); |
| 1869 | } | 1884 | } |
| 1870 | 1885 | ||
| 1871 | /** | 1886 | /** |
| @@ -2006,8 +2021,8 @@ static inline void __skb_unlink(struct sk_buff *skb, struct sk_buff_head *list) | |||
| 2006 | next = skb->next; | 2021 | next = skb->next; |
| 2007 | prev = skb->prev; | 2022 | prev = skb->prev; |
| 2008 | skb->next = skb->prev = NULL; | 2023 | skb->next = skb->prev = NULL; |
| 2009 | next->prev = prev; | 2024 | WRITE_ONCE(next->prev, prev); |
| 2010 | prev->next = next; | 2025 | WRITE_ONCE(prev->next, next); |
| 2011 | } | 2026 | } |
| 2012 | 2027 | ||
| 2013 | /** | 2028 | /** |
