net/packet: convert po->tp_loss to an atomic flag
authorEric Dumazet <edumazet@google.com>
Thu, 16 Mar 2023 01:10:11 +0000 (01:10 +0000)
committerDavid S. Miller <davem@davemloft.net>
Fri, 17 Mar 2023 08:52:05 +0000 (08:52 +0000)
tp_loss can be read locklessly.

Convert it to an atomic flag to avoid races.

Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/packet/af_packet.c
net/packet/diag.c
net/packet/internal.h

index 7800dc6..119063c 100644 (file)
@@ -2843,7 +2843,7 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
 
                if (unlikely(tp_len < 0)) {
 tpacket_error:
-                       if (po->tp_loss) {
+                       if (packet_sock_flag(po, PACKET_SOCK_TP_LOSS)) {
                                __packet_set_status(po, ph,
                                                TP_STATUS_AVAILABLE);
                                packet_increment_head(&po->tx_ring);
@@ -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) {
                        ret = -EBUSY;
                } else {
-                       po->tp_loss = !!val;
+                       packet_sock_flag_set(po, PACKET_SOCK_TP_LOSS, val);
                        ret = 0;
                }
                release_sock(sk);
@@ -4095,7 +4095,7 @@ static int packet_getsockopt(struct socket *sock, int level, int optname,
                val = po->tp_reserve;
                break;
        case PACKET_LOSS:
-               val = po->tp_loss;
+               val = packet_sock_flag(po, PACKET_SOCK_TP_LOSS);
                break;
        case PACKET_TIMESTAMP:
                val = READ_ONCE(po->tp_tstamp);
index 0abca32..8bb4ce6 100644 (file)
@@ -29,7 +29,7 @@ static int pdiag_put_info(const struct packet_sock *po, struct sk_buff *nlskb)
                pinfo.pdi_flags |= PDI_ORIGDEV;
        if (po->has_vnet_hdr)
                pinfo.pdi_flags |= PDI_VNETHDR;
-       if (po->tp_loss)
+       if (packet_sock_flag(po, PACKET_SOCK_TP_LOSS))
                pinfo.pdi_flags |= PDI_LOSS;
 
        return nla_put(nlskb, PACKET_DIAG_INFO, sizeof(pinfo), &pinfo);
index 0d16a58..9d406a9 100644 (file)
@@ -118,8 +118,7 @@ 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 */
-                               tp_loss:1;
+       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_ORIGDEV,
        PACKET_SOCK_AUXDATA,
        PACKET_SOCK_TX_HAS_OFF,
+       PACKET_SOCK_TP_LOSS,
 };
 
 static inline void packet_sock_flag_set(struct packet_sock *po,