|
@@ -1163,34 +1163,32 @@ out:
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
-#if BITS_PER_LONG == 64
|
|
|
+#define UDP_SKB_IS_STATELESS 0x80000000
|
|
|
+
|
|
|
static void udp_set_dev_scratch(struct sk_buff *skb)
|
|
|
{
|
|
|
- struct udp_dev_scratch *scratch;
|
|
|
+ struct udp_dev_scratch *scratch = udp_skb_scratch(skb);
|
|
|
|
|
|
BUILD_BUG_ON(sizeof(struct udp_dev_scratch) > sizeof(long));
|
|
|
- scratch = (struct udp_dev_scratch *)&skb->dev_scratch;
|
|
|
- scratch->truesize = skb->truesize;
|
|
|
+ scratch->_tsize_state = skb->truesize;
|
|
|
+#if BITS_PER_LONG == 64
|
|
|
scratch->len = skb->len;
|
|
|
scratch->csum_unnecessary = !!skb_csum_unnecessary(skb);
|
|
|
scratch->is_linear = !skb_is_nonlinear(skb);
|
|
|
+#endif
|
|
|
+ if (likely(!skb->_skb_refdst))
|
|
|
+ scratch->_tsize_state |= UDP_SKB_IS_STATELESS;
|
|
|
}
|
|
|
|
|
|
static int udp_skb_truesize(struct sk_buff *skb)
|
|
|
{
|
|
|
- return ((struct udp_dev_scratch *)&skb->dev_scratch)->truesize;
|
|
|
-}
|
|
|
-#else
|
|
|
-static void udp_set_dev_scratch(struct sk_buff *skb)
|
|
|
-{
|
|
|
- skb->dev_scratch = skb->truesize;
|
|
|
+ return udp_skb_scratch(skb)->_tsize_state & ~UDP_SKB_IS_STATELESS;
|
|
|
}
|
|
|
|
|
|
-static int udp_skb_truesize(struct sk_buff *skb)
|
|
|
+static bool udp_skb_has_head_state(struct sk_buff *skb)
|
|
|
{
|
|
|
- return skb->dev_scratch;
|
|
|
+ return !(udp_skb_scratch(skb)->_tsize_state & UDP_SKB_IS_STATELESS);
|
|
|
}
|
|
|
-#endif
|
|
|
|
|
|
/* fully reclaim rmem/fwd memory allocated for skb */
|
|
|
static void udp_rmem_release(struct sock *sk, int size, int partial,
|
|
@@ -1388,10 +1386,10 @@ void skb_consume_udp(struct sock *sk, struct sk_buff *skb, int len)
|
|
|
unlock_sock_fast(sk, slow);
|
|
|
}
|
|
|
|
|
|
- /* we cleared the head states previously only if the skb lacks any IP
|
|
|
- * options, see __udp_queue_rcv_skb().
|
|
|
+ /* In the more common cases we cleared the head states previously,
|
|
|
+ * see __udp_queue_rcv_skb().
|
|
|
*/
|
|
|
- if (unlikely(IPCB(skb)->opt.optlen > 0))
|
|
|
+ if (unlikely(udp_skb_has_head_state(skb)))
|
|
|
skb_release_head_state(skb);
|
|
|
consume_stateless_skb(skb);
|
|
|
}
|
|
@@ -1784,11 +1782,11 @@ static int __udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
|
|
|
sk_mark_napi_id_once(sk, skb);
|
|
|
}
|
|
|
|
|
|
- /* At recvmsg() time we need skb->dst to process IP options-related
|
|
|
- * cmsg, elsewhere can we clear all pending head states while they are
|
|
|
- * hot in the cache
|
|
|
+ /* At recvmsg() time we may access skb->dst or skb->sp depending on
|
|
|
+ * the IP options and the cmsg flags, elsewhere can we clear all
|
|
|
+ * pending head states while they are hot in the cache
|
|
|
*/
|
|
|
- if (likely(IPCB(skb)->opt.optlen == 0))
|
|
|
+ if (likely(IPCB(skb)->opt.optlen == 0 && !skb->sp))
|
|
|
skb_release_head_state(skb);
|
|
|
|
|
|
rc = __udp_enqueue_schedule_skb(sk, skb);
|