Skip to content

Commit 0ddf3fb

Browse files
Paolo Abenidavem330
authored andcommitted
udp: preserve skb->dst if required for IP options processing
Eric noticed that in udp_recvmsg() we still need to access skb->dst while processing the IP options. Since commit 0a463c7 ("udp: avoid a cache miss on dequeue") skb->dst is no more available at recvmsg() time and bad things will happen if we enter the relevant code path. This commit address the issue, avoid clearing skb->dst if any IP options are present into the relevant skb. Since the IP CB is contained in the first skb cacheline, we can test it to decide to leverage the consume_stateless_skb() optimization, without measurable additional cost in the faster path. v1 -> v2: updated commit message tags Fixes: 0a463c7 ("udp: avoid a cache miss on dequeue") Reported-by: Andrey Konovalov <andreyknvl@google.com> Reported-by: Eric Dumazet <edumazet@google.com> Signed-off-by: Paolo Abeni <pabeni@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 799f917 commit 0ddf3fb

File tree

1 file changed

+11
-2
lines changed

1 file changed

+11
-2
lines changed

net/ipv4/udp.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1388,6 +1388,11 @@ void skb_consume_udp(struct sock *sk, struct sk_buff *skb, int len)
13881388
unlock_sock_fast(sk, slow);
13891389
}
13901390

1391+
/* we cleared the head states previously only if the skb lacks any IP
1392+
* options, see __udp_queue_rcv_skb().
1393+
*/
1394+
if (unlikely(IPCB(skb)->opt.optlen > 0))
1395+
skb_release_head_state(skb);
13911396
consume_stateless_skb(skb);
13921397
}
13931398
EXPORT_SYMBOL_GPL(skb_consume_udp);
@@ -1779,8 +1784,12 @@ static int __udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
17791784
sk_mark_napi_id_once(sk, skb);
17801785
}
17811786

1782-
/* clear all pending head states while they are hot in the cache */
1783-
skb_release_head_state(skb);
1787+
/* At recvmsg() time we need skb->dst to process IP options-related
1788+
* cmsg, elsewhere can we clear all pending head states while they are
1789+
* hot in the cache
1790+
*/
1791+
if (likely(IPCB(skb)->opt.optlen == 0))
1792+
skb_release_head_state(skb);
17841793

17851794
rc = __udp_enqueue_schedule_skb(sk, skb);
17861795
if (rc < 0) {

0 commit comments

Comments
 (0)