Commit 164bddac authored by Eric Dumazet's avatar Eric Dumazet Committed by David S. Miller

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

tp_loss can be read locklessly.

Convert it to an atomic flag to avoid races.
Signed-off-by: default avatarEric Dumazet <edumazet@google.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 74383446
...@@ -2843,7 +2843,7 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) ...@@ -2843,7 +2843,7 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
if (unlikely(tp_len < 0)) { if (unlikely(tp_len < 0)) {
tpacket_error: tpacket_error:
if (po->tp_loss) { if (packet_sock_flag(po, PACKET_SOCK_TP_LOSS)) {
__packet_set_status(po, ph, __packet_set_status(po, ph,
TP_STATUS_AVAILABLE); TP_STATUS_AVAILABLE);
packet_increment_head(&po->tx_ring); packet_increment_head(&po->tx_ring);
...@@ -3886,7 +3886,7 @@ packet_setsockopt(struct socket *sock, int level, int optname, sockptr_t optval, ...@@ -3886,7 +3886,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->tp_loss = !!val; packet_sock_flag_set(po, PACKET_SOCK_TP_LOSS, val);
ret = 0; ret = 0;
} }
release_sock(sk); release_sock(sk);
...@@ -4095,7 +4095,7 @@ static int packet_getsockopt(struct socket *sock, int level, int optname, ...@@ -4095,7 +4095,7 @@ static int packet_getsockopt(struct socket *sock, int level, int optname,
val = po->tp_reserve; val = po->tp_reserve;
break; break;
case PACKET_LOSS: case PACKET_LOSS:
val = po->tp_loss; val = packet_sock_flag(po, PACKET_SOCK_TP_LOSS);
break; break;
case PACKET_TIMESTAMP: case PACKET_TIMESTAMP:
val = READ_ONCE(po->tp_tstamp); val = READ_ONCE(po->tp_tstamp);
......
...@@ -29,7 +29,7 @@ static int pdiag_put_info(const struct packet_sock *po, struct sk_buff *nlskb) ...@@ -29,7 +29,7 @@ static int pdiag_put_info(const struct packet_sock *po, struct sk_buff *nlskb)
pinfo.pdi_flags |= PDI_ORIGDEV; pinfo.pdi_flags |= PDI_ORIGDEV;
if (po->has_vnet_hdr) if (po->has_vnet_hdr)
pinfo.pdi_flags |= PDI_VNETHDR; pinfo.pdi_flags |= PDI_VNETHDR;
if (po->tp_loss) if (packet_sock_flag(po, PACKET_SOCK_TP_LOSS))
pinfo.pdi_flags |= PDI_LOSS; pinfo.pdi_flags |= PDI_LOSS;
return nla_put(nlskb, PACKET_DIAG_INFO, sizeof(pinfo), &pinfo); return nla_put(nlskb, PACKET_DIAG_INFO, sizeof(pinfo), &pinfo);
......
...@@ -118,8 +118,7 @@ struct packet_sock { ...@@ -118,8 +118,7 @@ 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 */ unsigned int has_vnet_hdr:1; /* writer must hold sock lock */
tp_loss:1;
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_ORIGDEV, PACKET_SOCK_ORIGDEV,
PACKET_SOCK_AUXDATA, PACKET_SOCK_AUXDATA,
PACKET_SOCK_TX_HAS_OFF, PACKET_SOCK_TX_HAS_OFF,
PACKET_SOCK_TP_LOSS,
}; };
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