Commit 50d935ea authored by Eric Dumazet's avatar Eric Dumazet Committed by David S. Miller

net/packet: convert po->has_vnet_hdr to an atomic flag

po->has_vnet_hdr can be read locklessly.
Signed-off-by: default avatarEric Dumazet <edumazet@google.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 164bddac
...@@ -2309,7 +2309,7 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, ...@@ -2309,7 +2309,7 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev,
netoff = TPACKET_ALIGN(po->tp_hdrlen + netoff = TPACKET_ALIGN(po->tp_hdrlen +
(maclen < 16 ? 16 : maclen)) + (maclen < 16 ? 16 : maclen)) +
po->tp_reserve; po->tp_reserve;
if (po->has_vnet_hdr) { if (packet_sock_flag(po, PACKET_SOCK_HAS_VNET_HDR)) {
netoff += sizeof(struct virtio_net_hdr); netoff += sizeof(struct virtio_net_hdr);
do_vnet = true; do_vnet = true;
} }
...@@ -2780,7 +2780,8 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) ...@@ -2780,7 +2780,8 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
size_max = po->tx_ring.frame_size size_max = po->tx_ring.frame_size
- (po->tp_hdrlen - sizeof(struct sockaddr_ll)); - (po->tp_hdrlen - sizeof(struct sockaddr_ll));
if ((size_max > dev->mtu + reserve + VLAN_HLEN) && !po->has_vnet_hdr) if ((size_max > dev->mtu + reserve + VLAN_HLEN) &&
!packet_sock_flag(po, PACKET_SOCK_HAS_VNET_HDR))
size_max = dev->mtu + reserve + VLAN_HLEN; size_max = dev->mtu + reserve + VLAN_HLEN;
reinit_completion(&po->skb_completion); reinit_completion(&po->skb_completion);
...@@ -2809,7 +2810,7 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) ...@@ -2809,7 +2810,7 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
status = TP_STATUS_SEND_REQUEST; status = TP_STATUS_SEND_REQUEST;
hlen = LL_RESERVED_SPACE(dev); hlen = LL_RESERVED_SPACE(dev);
tlen = dev->needed_tailroom; tlen = dev->needed_tailroom;
if (po->has_vnet_hdr) { if (packet_sock_flag(po, PACKET_SOCK_HAS_VNET_HDR)) {
vnet_hdr = data; vnet_hdr = data;
data += sizeof(*vnet_hdr); data += sizeof(*vnet_hdr);
tp_len -= sizeof(*vnet_hdr); tp_len -= sizeof(*vnet_hdr);
...@@ -2837,7 +2838,7 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) ...@@ -2837,7 +2838,7 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
addr, hlen, copylen, &sockc); addr, hlen, copylen, &sockc);
if (likely(tp_len >= 0) && if (likely(tp_len >= 0) &&
tp_len > dev->mtu + reserve && tp_len > dev->mtu + reserve &&
!po->has_vnet_hdr && !packet_sock_flag(po, PACKET_SOCK_HAS_VNET_HDR) &&
!packet_extra_vlan_len_allowed(dev, skb)) !packet_extra_vlan_len_allowed(dev, skb))
tp_len = -EMSGSIZE; tp_len = -EMSGSIZE;
...@@ -2856,7 +2857,7 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) ...@@ -2856,7 +2857,7 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
} }
} }
if (po->has_vnet_hdr) { if (packet_sock_flag(po, PACKET_SOCK_HAS_VNET_HDR)) {
if (virtio_net_hdr_to_skb(skb, vnet_hdr, vio_le())) { if (virtio_net_hdr_to_skb(skb, vnet_hdr, vio_le())) {
tp_len = -EINVAL; tp_len = -EINVAL;
goto tpacket_error; goto tpacket_error;
...@@ -2991,7 +2992,7 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len) ...@@ -2991,7 +2992,7 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len)
if (sock->type == SOCK_RAW) if (sock->type == SOCK_RAW)
reserve = dev->hard_header_len; reserve = dev->hard_header_len;
if (po->has_vnet_hdr) { if (packet_sock_flag(po, PACKET_SOCK_HAS_VNET_HDR)) {
err = packet_snd_vnet_parse(msg, &len, &vnet_hdr); err = packet_snd_vnet_parse(msg, &len, &vnet_hdr);
if (err) if (err)
goto out_unlock; goto out_unlock;
...@@ -3451,7 +3452,7 @@ static int packet_recvmsg(struct socket *sock, struct msghdr *msg, size_t len, ...@@ -3451,7 +3452,7 @@ static int packet_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
packet_rcv_try_clear_pressure(pkt_sk(sk)); packet_rcv_try_clear_pressure(pkt_sk(sk));
if (pkt_sk(sk)->has_vnet_hdr) { if (packet_sock_flag(pkt_sk(sk), PACKET_SOCK_HAS_VNET_HDR)) {
err = packet_rcv_vnet(msg, skb, &len); err = packet_rcv_vnet(msg, skb, &len);
if (err) if (err)
goto out_free; goto out_free;
...@@ -3931,7 +3932,7 @@ packet_setsockopt(struct socket *sock, int level, int optname, sockptr_t optval, ...@@ -3931,7 +3932,7 @@ packet_setsockopt(struct socket *sock, int level, int optname, sockptr_t optval,
if (po->rx_ring.pg_vec || po->tx_ring.pg_vec) { if (po->rx_ring.pg_vec || po->tx_ring.pg_vec) {
ret = -EBUSY; ret = -EBUSY;
} else { } else {
po->has_vnet_hdr = !!val; packet_sock_flag_set(po, PACKET_SOCK_HAS_VNET_HDR, val);
ret = 0; ret = 0;
} }
release_sock(sk); release_sock(sk);
...@@ -4065,7 +4066,7 @@ static int packet_getsockopt(struct socket *sock, int level, int optname, ...@@ -4065,7 +4066,7 @@ static int packet_getsockopt(struct socket *sock, int level, int optname,
val = packet_sock_flag(po, PACKET_SOCK_ORIGDEV); val = packet_sock_flag(po, PACKET_SOCK_ORIGDEV);
break; break;
case PACKET_VNET_HDR: case PACKET_VNET_HDR:
val = po->has_vnet_hdr; val = packet_sock_flag(po, PACKET_SOCK_HAS_VNET_HDR);
break; break;
case PACKET_VERSION: case PACKET_VERSION:
val = po->tp_version; val = po->tp_version;
......
...@@ -27,7 +27,7 @@ static int pdiag_put_info(const struct packet_sock *po, struct sk_buff *nlskb) ...@@ -27,7 +27,7 @@ static int pdiag_put_info(const struct packet_sock *po, struct sk_buff *nlskb)
pinfo.pdi_flags |= PDI_AUXDATA; pinfo.pdi_flags |= PDI_AUXDATA;
if (packet_sock_flag(po, PACKET_SOCK_ORIGDEV)) if (packet_sock_flag(po, PACKET_SOCK_ORIGDEV))
pinfo.pdi_flags |= PDI_ORIGDEV; pinfo.pdi_flags |= PDI_ORIGDEV;
if (po->has_vnet_hdr) if (packet_sock_flag(po, PACKET_SOCK_HAS_VNET_HDR))
pinfo.pdi_flags |= PDI_VNETHDR; pinfo.pdi_flags |= PDI_VNETHDR;
if (packet_sock_flag(po, PACKET_SOCK_TP_LOSS)) if (packet_sock_flag(po, PACKET_SOCK_TP_LOSS))
pinfo.pdi_flags |= PDI_LOSS; pinfo.pdi_flags |= PDI_LOSS;
......
...@@ -118,7 +118,6 @@ struct packet_sock { ...@@ -118,7 +118,6 @@ struct packet_sock {
struct mutex pg_vec_lock; struct mutex pg_vec_lock;
unsigned long flags; unsigned long flags;
unsigned int running; /* bind_lock must be held */ unsigned int running; /* bind_lock must be held */
unsigned int has_vnet_hdr:1; /* writer must hold sock lock */
int pressure; int pressure;
int ifindex; /* bound device */ int ifindex; /* bound device */
__be16 num; __be16 num;
...@@ -146,6 +145,7 @@ enum packet_sock_flags { ...@@ -146,6 +145,7 @@ enum packet_sock_flags {
PACKET_SOCK_AUXDATA, PACKET_SOCK_AUXDATA,
PACKET_SOCK_TX_HAS_OFF, PACKET_SOCK_TX_HAS_OFF,
PACKET_SOCK_TP_LOSS, PACKET_SOCK_TP_LOSS,
PACKET_SOCK_HAS_VNET_HDR,
}; };
static inline void packet_sock_flag_set(struct packet_sock *po, static inline void packet_sock_flag_set(struct packet_sock *po,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment