UDP GSO segmentation currently propagates socket write ownership only when the aggregate uses sock_wfree. An encapsulator such as ovpn can instead retain ownership from the payload socket, including tcp_wfree, while repackaging its data as UDP GSO.
In that case the destructor remains on the aggregate and runs when software segmentation consumes it, before the resulting UDP packets complete transmission. This releases the write-memory charge early and can wake TCP Small Queues prematurely. Use is_skb_wmem to recognize the standard write-accounting destructors and propagate the original destructor to every segment. These destructors all release ownership using skb->sk and skb->truesize, so the existing truesize adjustment remains applicable. Skbs owned through sock_wfree are handled as before. Signed-off-by: Ralf Lici <[email protected]> --- New in v4. net/ipv4/udp_offload.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c index cf07c3c6611a..d41529030fbb 100644 --- a/net/ipv4/udp_offload.c +++ b/net/ipv4/udp_offload.c @@ -481,6 +481,7 @@ static struct sk_buff *__udp_gso_segment_list(struct sk_buff *skb, struct sk_buff *__udp_gso_segment(struct sk_buff *gso_skb, netdev_features_t features, bool is_ipv6) { + void (*destructor)(struct sk_buff *skb) = gso_skb->destructor; struct sock *sk = gso_skb->sk; unsigned int sum_truesize = 0; struct sk_buff *segs, *seg; @@ -542,7 +543,7 @@ struct sk_buff *__udp_gso_segment(struct sk_buff *gso_skb, skb_pull(gso_skb, sizeof(*uh)); /* clear destructor to avoid skb_segment assigning it to tail */ - copy_dtor = gso_skb->destructor == sock_wfree; + copy_dtor = is_skb_wmem(gso_skb); if (copy_dtor) { gso_skb->destructor = NULL; gso_skb->sk = NULL; @@ -551,7 +552,7 @@ struct sk_buff *__udp_gso_segment(struct sk_buff *gso_skb, segs = skb_segment(gso_skb, features); if (IS_ERR_OR_NULL(segs)) { if (copy_dtor) { - gso_skb->destructor = sock_wfree; + gso_skb->destructor = destructor; gso_skb->sk = sk; } return segs; @@ -571,7 +572,7 @@ struct sk_buff *__udp_gso_segment(struct sk_buff *gso_skb, for (;;) { if (copy_dtor) { - seg->destructor = sock_wfree; + seg->destructor = destructor; seg->sk = sk; sum_truesize += seg->truesize; } -- 2.56.0 _______________________________________________ Openvpn-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/openvpn-devel
