BACKPORT: dev: packet: make packet_direct_xmit a common function
The new dev_direct_xmit will be used by AF_XDP in later commits. Signed-off-by: Magnus Karlsson <magnus.karlsson@intel.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org> Signed-off-by: Sorayukii <sorayukii69@gmail.com>
This commit is contained in:
parent
f9b829aee8
commit
1f91cd12f9
3 changed files with 42 additions and 38 deletions
|
|
@ -2513,6 +2513,7 @@ void dev_disable_lro(struct net_device *dev);
|
|||
int dev_loopback_xmit(struct net *net, struct sock *sk, struct sk_buff *newskb);
|
||||
int dev_queue_xmit(struct sk_buff *skb);
|
||||
int dev_queue_xmit_accel(struct sk_buff *skb, void *accel_priv);
|
||||
int dev_direct_xmit(struct sk_buff *skb, u16 queue_id);
|
||||
int dev_queue_xmit_list(struct sk_buff *skb);
|
||||
int register_netdevice(struct net_device *dev);
|
||||
void unregister_netdevice_queue(struct net_device *dev, struct list_head *head);
|
||||
|
|
|
|||
|
|
@ -3605,6 +3605,42 @@ int dev_queue_xmit_list(struct sk_buff *skb)
|
|||
}
|
||||
EXPORT_SYMBOL(dev_queue_xmit_list);
|
||||
|
||||
int dev_direct_xmit(struct sk_buff *skb, u16 queue_id)
|
||||
{
|
||||
struct net_device *dev = skb->dev;
|
||||
struct sk_buff *orig_skb = skb;
|
||||
struct netdev_queue *txq;
|
||||
int ret = NETDEV_TX_BUSY;
|
||||
|
||||
if (unlikely(!netif_running(dev) ||
|
||||
!netif_carrier_ok(dev)))
|
||||
goto drop;
|
||||
|
||||
skb = validate_xmit_skb_list(skb, dev);
|
||||
if (skb != orig_skb)
|
||||
goto drop;
|
||||
|
||||
skb_set_queue_mapping(skb, queue_id);
|
||||
txq = skb_get_tx_queue(dev, skb);
|
||||
|
||||
local_bh_disable();
|
||||
|
||||
HARD_TX_LOCK(dev, txq, smp_processor_id());
|
||||
if (!netif_xmit_frozen_or_drv_stopped(txq))
|
||||
ret = netdev_start_xmit(skb, dev, txq, false);
|
||||
HARD_TX_UNLOCK(dev, txq);
|
||||
|
||||
local_bh_enable();
|
||||
|
||||
if (!dev_xmit_complete(ret))
|
||||
kfree_skb(skb);
|
||||
|
||||
return ret;
|
||||
drop:
|
||||
atomic_long_inc(&dev->tx_dropped);
|
||||
kfree_skb_list(skb);
|
||||
return NET_XMIT_DROP;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* Receiver routines
|
||||
|
|
|
|||
|
|
@ -216,6 +216,7 @@ static void prb_clear_rxhash(struct tpacket_kbdq_core *,
|
|||
static void prb_fill_vlan_info(struct tpacket_kbdq_core *,
|
||||
struct tpacket3_hdr *);
|
||||
static void packet_flush_mclist(struct sock *sk);
|
||||
static u16 packet_pick_tx_queue(struct sk_buff *skb);
|
||||
|
||||
struct packet_skb_cb {
|
||||
union {
|
||||
|
|
@ -249,38 +250,7 @@ static void __fanout_link(struct sock *sk, struct packet_sock *po);
|
|||
|
||||
static int packet_direct_xmit(struct sk_buff *skb)
|
||||
{
|
||||
struct net_device *dev = skb->dev;
|
||||
struct sk_buff *orig_skb = skb;
|
||||
struct netdev_queue *txq;
|
||||
int ret = NETDEV_TX_BUSY;
|
||||
|
||||
if (unlikely(!netif_running(dev) ||
|
||||
!netif_carrier_ok(dev)))
|
||||
goto drop;
|
||||
|
||||
skb = validate_xmit_skb_list(skb, dev);
|
||||
if (skb != orig_skb)
|
||||
goto drop;
|
||||
|
||||
txq = skb_get_tx_queue(dev, skb);
|
||||
|
||||
local_bh_disable();
|
||||
|
||||
HARD_TX_LOCK(dev, txq, smp_processor_id());
|
||||
if (!netif_xmit_frozen_or_drv_stopped(txq))
|
||||
ret = netdev_start_xmit(skb, dev, txq, false);
|
||||
HARD_TX_UNLOCK(dev, txq);
|
||||
|
||||
local_bh_enable();
|
||||
|
||||
if (!dev_xmit_complete(ret))
|
||||
kfree_skb(skb);
|
||||
|
||||
return ret;
|
||||
drop:
|
||||
atomic_long_inc(&dev->tx_dropped);
|
||||
kfree_skb_list(skb);
|
||||
return NET_XMIT_DROP;
|
||||
return dev_direct_xmit(skb, packet_pick_tx_queue(skb));
|
||||
}
|
||||
|
||||
static struct net_device *packet_cached_dev_get(struct packet_sock *po)
|
||||
|
|
@ -317,8 +287,9 @@ static u16 __packet_pick_tx_queue(struct net_device *dev, struct sk_buff *skb)
|
|||
return (u16) raw_smp_processor_id() % dev->real_num_tx_queues;
|
||||
}
|
||||
|
||||
static void packet_pick_tx_queue(struct net_device *dev, struct sk_buff *skb)
|
||||
static u16 packet_pick_tx_queue(struct sk_buff *skb)
|
||||
{
|
||||
struct net_device *dev = skb->dev;
|
||||
const struct net_device_ops *ops = dev->netdev_ops;
|
||||
u16 queue_index;
|
||||
|
||||
|
|
@ -330,7 +301,7 @@ static void packet_pick_tx_queue(struct net_device *dev, struct sk_buff *skb)
|
|||
queue_index = __packet_pick_tx_queue(dev, skb);
|
||||
}
|
||||
|
||||
skb_set_queue_mapping(skb, queue_index);
|
||||
return queue_index;
|
||||
}
|
||||
|
||||
/* __register_prot_hook must be invoked through register_prot_hook
|
||||
|
|
@ -2799,8 +2770,6 @@ tpacket_error:
|
|||
goto tpacket_error;
|
||||
}
|
||||
|
||||
packet_pick_tx_queue(dev, skb);
|
||||
|
||||
skb->destructor = tpacket_destruct_skb;
|
||||
__packet_set_status(po, ph, TP_STATUS_SENDING);
|
||||
packet_inc_pending(&po->tx_ring);
|
||||
|
|
@ -2994,8 +2963,6 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len)
|
|||
skb->priority = sk->sk_priority;
|
||||
skb->mark = sockc.mark;
|
||||
|
||||
packet_pick_tx_queue(dev, skb);
|
||||
|
||||
if (has_vnet_hdr) {
|
||||
err = packet_snd_vnet_gso(skb, &vnet_hdr);
|
||||
if (err)
|
||||
|
|
|
|||
Loading…
Reference in a new issue