Skip to content

Commit 105a201

Browse files
edumazetdavem330
authored andcommitted
net/packet: remove po->xmit
Use PACKET_SOCK_QDISC_BYPASS atomic bit instead of a pointer. This removes one indirect call in fast path, and READ_ONCE()/WRITE_ONCE() annotations as well. Signed-off-by: Eric Dumazet <[email protected]> Suggested-by: Willem de Bruijn <[email protected]> Cc: Daniel Borkmann <[email protected]> Reviewed-by: Willem de Bruijn <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 72abf21 commit 105a201

File tree

2 files changed

+10
-16
lines changed

2 files changed

+10
-16
lines changed

net/packet/af_packet.c

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -270,8 +270,11 @@ static noinline struct sk_buff *nf_hook_direct_egress(struct sk_buff *skb)
270270
}
271271
#endif
272272

273-
static int packet_direct_xmit(struct sk_buff *skb)
273+
static int packet_xmit(const struct packet_sock *po, struct sk_buff *skb)
274274
{
275+
if (!packet_sock_flag(po, PACKET_SOCK_QDISC_BYPASS))
276+
return dev_queue_xmit(skb);
277+
275278
#ifdef CONFIG_NETFILTER_EGRESS
276279
if (nf_hook_egress_active()) {
277280
skb = nf_hook_direct_egress(skb);
@@ -305,12 +308,6 @@ static void packet_cached_dev_reset(struct packet_sock *po)
305308
RCU_INIT_POINTER(po->cached_dev, NULL);
306309
}
307310

308-
static bool packet_use_direct_xmit(const struct packet_sock *po)
309-
{
310-
/* Paired with WRITE_ONCE() in packet_setsockopt() */
311-
return READ_ONCE(po->xmit) == packet_direct_xmit;
312-
}
313-
314311
static u16 packet_pick_tx_queue(struct sk_buff *skb)
315312
{
316313
struct net_device *dev = skb->dev;
@@ -2872,8 +2869,7 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
28722869
packet_inc_pending(&po->tx_ring);
28732870

28742871
status = TP_STATUS_SEND_REQUEST;
2875-
/* Paired with WRITE_ONCE() in packet_setsockopt() */
2876-
err = READ_ONCE(po->xmit)(skb);
2872+
err = packet_xmit(po, skb);
28772873
if (unlikely(err != 0)) {
28782874
if (err > 0)
28792875
err = net_xmit_errno(err);
@@ -3076,8 +3072,8 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len)
30763072
virtio_net_hdr_set_proto(skb, &vnet_hdr);
30773073
}
30783074

3079-
/* Paired with WRITE_ONCE() in packet_setsockopt() */
3080-
err = READ_ONCE(po->xmit)(skb);
3075+
err = packet_xmit(po, skb);
3076+
30813077
if (unlikely(err != 0)) {
30823078
if (err > 0)
30833079
err = net_xmit_errno(err);
@@ -3359,7 +3355,6 @@ static int packet_create(struct net *net, struct socket *sock, int protocol,
33593355
init_completion(&po->skb_completion);
33603356
sk->sk_family = PF_PACKET;
33613357
po->num = proto;
3362-
po->xmit = dev_queue_xmit;
33633358

33643359
err = packet_alloc_pending(po);
33653360
if (err)
@@ -4010,8 +4005,7 @@ packet_setsockopt(struct socket *sock, int level, int optname, sockptr_t optval,
40104005
if (copy_from_sockptr(&val, optval, sizeof(val)))
40114006
return -EFAULT;
40124007

4013-
/* Paired with all lockless reads of po->xmit */
4014-
WRITE_ONCE(po->xmit, val ? packet_direct_xmit : dev_queue_xmit);
4008+
packet_sock_flag_set(po, PACKET_SOCK_QDISC_BYPASS, val);
40154009
return 0;
40164010
}
40174011
default:
@@ -4126,7 +4120,7 @@ static int packet_getsockopt(struct socket *sock, int level, int optname,
41264120
val = packet_sock_flag(po, PACKET_SOCK_TX_HAS_OFF);
41274121
break;
41284122
case PACKET_QDISC_BYPASS:
4129-
val = packet_use_direct_xmit(po);
4123+
val = packet_sock_flag(po, PACKET_SOCK_QDISC_BYPASS);
41304124
break;
41314125
default:
41324126
return -ENOPROTOOPT;

net/packet/internal.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,6 @@ struct packet_sock {
128128
unsigned int tp_tstamp;
129129
struct completion skb_completion;
130130
struct net_device __rcu *cached_dev;
131-
int (*xmit)(struct sk_buff *skb);
132131
struct packet_type prot_hook ____cacheline_aligned_in_smp;
133132
atomic_t tp_drops ____cacheline_aligned_in_smp;
134133
};
@@ -143,6 +142,7 @@ enum packet_sock_flags {
143142
PACKET_SOCK_HAS_VNET_HDR,
144143
PACKET_SOCK_RUNNING,
145144
PACKET_SOCK_PRESSURE,
145+
PACKET_SOCK_QDISC_BYPASS,
146146
};
147147

148148
static inline void packet_sock_flag_set(struct packet_sock *po,

0 commit comments

Comments
 (0)