mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-04 04:02:26 +00:00
net/packet: convert po->has_vnet_hdr to an atomic flag
po->has_vnet_hdr can be read locklessly. Signed-off-by: Eric Dumazet <edumazet@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
164bddace2
commit
50d935eafe
@ -2309,7 +2309,7 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev,
|
||||
netoff = TPACKET_ALIGN(po->tp_hdrlen +
|
||||
(maclen < 16 ? 16 : maclen)) +
|
||||
po->tp_reserve;
|
||||
if (po->has_vnet_hdr) {
|
||||
if (packet_sock_flag(po, PACKET_SOCK_HAS_VNET_HDR)) {
|
||||
netoff += sizeof(struct virtio_net_hdr);
|
||||
do_vnet = true;
|
||||
}
|
||||
@ -2780,7 +2780,8 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
|
||||
size_max = po->tx_ring.frame_size
|
||||
- (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;
|
||||
|
||||
reinit_completion(&po->skb_completion);
|
||||
@ -2809,7 +2810,7 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
|
||||
status = TP_STATUS_SEND_REQUEST;
|
||||
hlen = LL_RESERVED_SPACE(dev);
|
||||
tlen = dev->needed_tailroom;
|
||||
if (po->has_vnet_hdr) {
|
||||
if (packet_sock_flag(po, PACKET_SOCK_HAS_VNET_HDR)) {
|
||||
vnet_hdr = data;
|
||||
data += sizeof(*vnet_hdr);
|
||||
tp_len -= sizeof(*vnet_hdr);
|
||||
@ -2837,7 +2838,7 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
|
||||
addr, hlen, copylen, &sockc);
|
||||
if (likely(tp_len >= 0) &&
|
||||
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))
|
||||
tp_len = -EMSGSIZE;
|
||||
|
||||
@ -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())) {
|
||||
tp_len = -EINVAL;
|
||||
goto tpacket_error;
|
||||
@ -2991,7 +2992,7 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len)
|
||||
|
||||
if (sock->type == SOCK_RAW)
|
||||
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);
|
||||
if (err)
|
||||
goto out_unlock;
|
||||
@ -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));
|
||||
|
||||
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);
|
||||
if (err)
|
||||
goto out_free;
|
||||
@ -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) {
|
||||
ret = -EBUSY;
|
||||
} else {
|
||||
po->has_vnet_hdr = !!val;
|
||||
packet_sock_flag_set(po, PACKET_SOCK_HAS_VNET_HDR, val);
|
||||
ret = 0;
|
||||
}
|
||||
release_sock(sk);
|
||||
@ -4065,7 +4066,7 @@ static int packet_getsockopt(struct socket *sock, int level, int optname,
|
||||
val = packet_sock_flag(po, PACKET_SOCK_ORIGDEV);
|
||||
break;
|
||||
case PACKET_VNET_HDR:
|
||||
val = po->has_vnet_hdr;
|
||||
val = packet_sock_flag(po, PACKET_SOCK_HAS_VNET_HDR);
|
||||
break;
|
||||
case PACKET_VERSION:
|
||||
val = po->tp_version;
|
||||
|
@ -27,7 +27,7 @@ static int pdiag_put_info(const struct packet_sock *po, struct sk_buff *nlskb)
|
||||
pinfo.pdi_flags |= PDI_AUXDATA;
|
||||
if (packet_sock_flag(po, PACKET_SOCK_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;
|
||||
if (packet_sock_flag(po, PACKET_SOCK_TP_LOSS))
|
||||
pinfo.pdi_flags |= PDI_LOSS;
|
||||
|
@ -118,7 +118,6 @@ struct packet_sock {
|
||||
struct mutex pg_vec_lock;
|
||||
unsigned long flags;
|
||||
unsigned int running; /* bind_lock must be held */
|
||||
unsigned int has_vnet_hdr:1; /* writer must hold sock lock */
|
||||
int pressure;
|
||||
int ifindex; /* bound device */
|
||||
__be16 num;
|
||||
@ -146,6 +145,7 @@ enum packet_sock_flags {
|
||||
PACKET_SOCK_AUXDATA,
|
||||
PACKET_SOCK_TX_HAS_OFF,
|
||||
PACKET_SOCK_TP_LOSS,
|
||||
PACKET_SOCK_HAS_VNET_HDR,
|
||||
};
|
||||
|
||||
static inline void packet_sock_flag_set(struct packet_sock *po,
|
||||
|
Loading…
Reference in New Issue
Block a user