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

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
Loading
Loading
Loading
Loading
+10 −9
Original line number Diff line number Diff line
@@ -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;
+1 −1
Original line number Diff line number Diff line
@@ -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;
+1 −1
Original line number Diff line number Diff line
@@ -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,