From: Bobby Eshleman bobbyeshleman@meta.com
Add a net pointer, netns_tracker, and net_mode to the vsock skb and helpers for getting/setting them. These fields are only used by vsock_loopback in order to avoid net-related race conditions (more info in the loopback patch).
This extends virtio_vsock_skb_cb to 32 bytes (with CONFIG_NET_DEV_REFCNT_TRACKER=y):
struct virtio_vsock_skb_cb { struct net * net; /* 0 8 */ netns_tracker ns_tracker; /* 8 8 */ enum vsock_net_mode net_mode; /* 16 4 */ u32 offset; /* 20 4 */ bool reply; /* 24 1 */ bool tap_delivered; /* 25 1 */
/* size: 32, cachelines: 1, members: 6 */ /* padding: 6 */ /* last cacheline: 32 bytes */ };
Signed-off-by: Bobby Eshleman bobbyeshleman@meta.com --- Changes in v9: - update commit message to specify usage by loopback only - add comment in virtio_vsock_skb_cb mentioning usage by vsock_loopback - add ns_tracker to skb->cb - removed Stefano's Reviewed-by trailer due to ns_tracker addition (not sure if this is the right process thing to do)
Changes in v7: - rename `orig_net_mode` to `net_mode` - update commit message with a more complete explanation of changes
Changes in v5: - some diff context change due to rebase to current net-next --- include/linux/virtio_vsock.h | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+)
diff --git a/include/linux/virtio_vsock.h b/include/linux/virtio_vsock.h index 18deb3c8dab3..a3ef752cdb95 100644 --- a/include/linux/virtio_vsock.h +++ b/include/linux/virtio_vsock.h @@ -10,6 +10,10 @@ #define VIRTIO_VSOCK_SKB_HEADROOM (sizeof(struct virtio_vsock_hdr))
struct virtio_vsock_skb_cb { + /* net, net_mode, and ns_tracker are only used by vsock_loopback. */ + struct net *net; + netns_tracker ns_tracker; + enum vsock_net_mode net_mode; u32 offset; bool reply; bool tap_delivered; @@ -130,6 +134,35 @@ static inline size_t virtio_vsock_skb_len(struct sk_buff *skb) return (size_t)(skb_end_pointer(skb) - skb->head); }
+static inline struct net *virtio_vsock_skb_net(struct sk_buff *skb) +{ + return VIRTIO_VSOCK_SKB_CB(skb)->net; +} + +static inline void virtio_vsock_skb_set_net(struct sk_buff *skb, struct net *net) +{ + get_net_track(net, &VIRTIO_VSOCK_SKB_CB(skb)->ns_tracker, GFP_KERNEL); + VIRTIO_VSOCK_SKB_CB(skb)->net = net; +} + +static inline void virtio_vsock_skb_clear_net(struct sk_buff *skb) +{ + put_net_track(VIRTIO_VSOCK_SKB_CB(skb)->net, + &VIRTIO_VSOCK_SKB_CB(skb)->ns_tracker); + VIRTIO_VSOCK_SKB_CB(skb)->net = NULL; +} + +static inline enum vsock_net_mode virtio_vsock_skb_net_mode(struct sk_buff *skb) +{ + return VIRTIO_VSOCK_SKB_CB(skb)->net_mode; +} + +static inline void virtio_vsock_skb_set_net_mode(struct sk_buff *skb, + enum vsock_net_mode net_mode) +{ + VIRTIO_VSOCK_SKB_CB(skb)->net_mode = net_mode; +} + /* Dimension the RX SKB so that the entire thing fits exactly into * a single 4KiB page. This avoids wasting memory due to alloc_skb() * rounding up to the next page order and also means that we