tsnep: Support XDP BPF program setup
Implement setup of BPF programs for XDP RX path with command
XDP_SETUP_PROG of ndo_bpf(). This is the final step for XDP RX path
support.
There is no need to reinit the RX queues as they are always prepared for
XDP.
Additionally remove $(tsnep-y) from $(tsnep-objs) because it is added
automatically.
Test results with A53 1.2GHz:
XDP_DROP (samples/bpf/xdp1)
proto 17: 883878 pkt/s
XDP_TX (samples/bpf/xdp2)
proto 17: 255693 pkt/s
XDP_REDIRECT (samples/bpf/xdpsock)
sock0@eth2:0 rxdrop xdp-drv
pps pkts 1.00
rx 855,582 5,404,523
tx 0 0
XDP_REDIRECT (samples/bpf/xdp_redirect)
eth2->eth1 613,267 rx/s 0 err,drop/s 613,272 xmit/s
Signed-off-by: Gerhard Engleder <gerhard@engleder-embedded.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
committed by
David S. Miller
parent
65b28c8100
commit
f0f6460f91
@@ -6,5 +6,5 @@
|
||||
obj-$(CONFIG_TSNEP) += tsnep.o
|
||||
|
||||
tsnep-objs := tsnep_main.o tsnep_ethtool.o tsnep_ptp.o tsnep_tc.o \
|
||||
tsnep_rxnfc.o $(tsnep-y)
|
||||
tsnep_rxnfc.o tsnep_xdp.o
|
||||
tsnep-$(CONFIG_TSNEP_SELFTESTS) += tsnep_selftests.o
|
||||
|
||||
@@ -211,6 +211,9 @@ int tsnep_rxnfc_add_rule(struct tsnep_adapter *adapter,
|
||||
int tsnep_rxnfc_del_rule(struct tsnep_adapter *adapter,
|
||||
struct ethtool_rxnfc *cmd);
|
||||
|
||||
int tsnep_xdp_setup_prog(struct tsnep_adapter *adapter, struct bpf_prog *prog,
|
||||
struct netlink_ext_ack *extack);
|
||||
|
||||
#if IS_ENABLED(CONFIG_TSNEP_SELFTESTS)
|
||||
int tsnep_ethtool_get_test_count(void);
|
||||
void tsnep_ethtool_get_test_strings(u8 *data);
|
||||
|
||||
@@ -1614,6 +1614,18 @@ static ktime_t tsnep_netdev_get_tstamp(struct net_device *netdev,
|
||||
return ns_to_ktime(timestamp);
|
||||
}
|
||||
|
||||
static int tsnep_netdev_bpf(struct net_device *dev, struct netdev_bpf *bpf)
|
||||
{
|
||||
struct tsnep_adapter *adapter = netdev_priv(dev);
|
||||
|
||||
switch (bpf->command) {
|
||||
case XDP_SETUP_PROG:
|
||||
return tsnep_xdp_setup_prog(adapter, bpf->prog, bpf->extack);
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
}
|
||||
|
||||
static struct tsnep_tx *tsnep_xdp_get_tx(struct tsnep_adapter *adapter, u32 cpu)
|
||||
{
|
||||
if (cpu >= TSNEP_MAX_QUEUES)
|
||||
@@ -1674,6 +1686,7 @@ static const struct net_device_ops tsnep_netdev_ops = {
|
||||
.ndo_set_features = tsnep_netdev_set_features,
|
||||
.ndo_get_tstamp = tsnep_netdev_get_tstamp,
|
||||
.ndo_setup_tc = tsnep_tc_setup,
|
||||
.ndo_bpf = tsnep_netdev_bpf,
|
||||
.ndo_xdp_xmit = tsnep_netdev_xdp_xmit,
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Copyright (C) 2022 Gerhard Engleder <gerhard@engleder-embedded.com> */
|
||||
|
||||
#include <linux/if_vlan.h>
|
||||
#include <net/xdp_sock_drv.h>
|
||||
|
||||
#include "tsnep.h"
|
||||
|
||||
int tsnep_xdp_setup_prog(struct tsnep_adapter *adapter, struct bpf_prog *prog,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct bpf_prog *old_prog;
|
||||
|
||||
old_prog = xchg(&adapter->xdp_prog, prog);
|
||||
if (old_prog)
|
||||
bpf_prog_put(old_prog);
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user