Skip to content

Commit d2e0ef4

Browse files
committed
Merge branch 'nfp-move-BPF-offload-code-into-app'
Jakub Kicinski says: ==================== nfp: move BPF offload code into app This series moves the eBPF offload code out of netdev/vNIC handling and starts building the nfp_app. Port init is moved into the apps as well because various apps associate vNICs, representors with ports differently. First patch adds a helper for updating tc stats which has been waiting in my tree to be included in any moderately related series. Next series will bring communicating with FW using control messages, then representors, BPF maps, tc flower... :) ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents c380e37 + 47eaa23 commit d2e0ef4

File tree

20 files changed

+600
-172
lines changed

20 files changed

+600
-172
lines changed

drivers/net/ethernet/mellanox/mlx5/core/en_tc.c

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1863,9 +1863,7 @@ int mlx5e_stats_flower(struct mlx5e_priv *priv,
18631863
{
18641864
struct mlx5e_tc_table *tc = &priv->fs.tc;
18651865
struct mlx5e_tc_flow *flow;
1866-
struct tc_action *a;
18671866
struct mlx5_fc *counter;
1868-
LIST_HEAD(actions);
18691867
u64 bytes;
18701868
u64 packets;
18711869
u64 lastuse;
@@ -1884,13 +1882,7 @@ int mlx5e_stats_flower(struct mlx5e_priv *priv,
18841882

18851883
mlx5_fc_query_cached(counter, &bytes, &packets, &lastuse);
18861884

1887-
preempt_disable();
1888-
1889-
tcf_exts_to_list(f->exts, &actions);
1890-
list_for_each_entry(a, &actions, list)
1891-
tcf_action_stats_update(a, bytes, packets, lastuse);
1892-
1893-
preempt_enable();
1885+
tcf_exts_stats_update(f->exts, bytes, packets, lastuse);
18941886

18951887
return 0;
18961888
}

drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -397,8 +397,6 @@ int mlxsw_sp_flower_stats(struct mlxsw_sp_port *mlxsw_sp_port, bool ingress,
397397
struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
398398
struct mlxsw_sp_acl_ruleset *ruleset;
399399
struct mlxsw_sp_acl_rule *rule;
400-
struct tc_action *a;
401-
LIST_HEAD(actions);
402400
u64 packets;
403401
u64 lastuse;
404402
u64 bytes;
@@ -419,13 +417,7 @@ int mlxsw_sp_flower_stats(struct mlxsw_sp_port *mlxsw_sp_port, bool ingress,
419417
if (err)
420418
goto err_rule_get_stats;
421419

422-
preempt_disable();
423-
424-
tcf_exts_to_list(f->exts, &actions);
425-
list_for_each_entry(a, &actions, list)
426-
tcf_action_stats_update(a, bytes, packets, lastuse);
427-
428-
preempt_enable();
420+
tcf_exts_stats_update(f->exts, bytes, packets, lastuse);
429421

430422
mlxsw_sp_acl_ruleset_put(mlxsw_sp, ruleset);
431423
return 0;

drivers/net/ethernet/netronome/nfp/Makefile

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,23 @@ nfp-objs := \
1515
nfpcore/nfp_rtsym.o \
1616
nfpcore/nfp_target.o \
1717
nfp_app.o \
18+
nfp_app_nic.o \
1819
nfp_devlink.o \
1920
nfp_hwmon.o \
2021
nfp_main.o \
2122
nfp_net_common.o \
2223
nfp_net_ethtool.o \
23-
nfp_net_offload.o \
2424
nfp_net_main.o \
2525
nfp_netvf_main.o \
26-
nfp_port.o
26+
nfp_port.o \
27+
bpf/main.o \
28+
bpf/offload.o \
29+
nic/main.o
2730

2831
ifeq ($(CONFIG_BPF_SYSCALL),y)
2932
nfp-objs += \
30-
nfp_bpf_verifier.o \
31-
nfp_bpf_jit.o
33+
bpf/verifier.o \
34+
bpf/jit.o
3235
endif
3336

3437
nfp-$(CONFIG_NFP_DEBUG) += nfp_net_debugfs.o

drivers/net/ethernet/netronome/nfp/nfp_bpf_jit.c renamed to drivers/net/ethernet/netronome/nfp/bpf/jit.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@
3939
#include <linux/pkt_cls.h>
4040
#include <linux/unistd.h>
4141

42-
#include "nfp_asm.h"
43-
#include "nfp_bpf.h"
42+
#include "main.h"
43+
#include "../nfp_asm.h"
4444

4545
/* --- NFP prog --- */
4646
/* Foreach "multiple" entries macros provide pos and next<n> pointers.
Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
/*
2+
* Copyright (C) 2017 Netronome Systems, Inc.
3+
*
4+
* This software is dual licensed under the GNU General License Version 2,
5+
* June 1991 as shown in the file COPYING in the top-level directory of this
6+
* source tree or the BSD 2-Clause License provided below. You have the
7+
* option to license this software under the complete terms of either license.
8+
*
9+
* The BSD 2-Clause License:
10+
*
11+
* Redistribution and use in source and binary forms, with or
12+
* without modification, are permitted provided that the following
13+
* conditions are met:
14+
*
15+
* 1. Redistributions of source code must retain the above
16+
* copyright notice, this list of conditions and the following
17+
* disclaimer.
18+
*
19+
* 2. Redistributions in binary form must reproduce the above
20+
* copyright notice, this list of conditions and the following
21+
* disclaimer in the documentation and/or other materials
22+
* provided with the distribution.
23+
*
24+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26+
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28+
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29+
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30+
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31+
* SOFTWARE.
32+
*/
33+
34+
#include <net/pkt_cls.h>
35+
36+
#include "../nfpcore/nfp_cpp.h"
37+
#include "../nfp_app.h"
38+
#include "../nfp_main.h"
39+
#include "../nfp_net.h"
40+
#include "../nfp_port.h"
41+
#include "main.h"
42+
43+
static bool nfp_net_ebpf_capable(struct nfp_net *nn)
44+
{
45+
if (nn->cap & NFP_NET_CFG_CTRL_BPF &&
46+
nn_readb(nn, NFP_NET_CFG_BPF_ABI) == NFP_NET_BPF_ABI)
47+
return true;
48+
return false;
49+
}
50+
51+
static int
52+
nfp_bpf_xdp_offload(struct nfp_app *app, struct nfp_net *nn,
53+
struct bpf_prog *prog)
54+
{
55+
struct tc_cls_bpf_offload cmd = {
56+
.prog = prog,
57+
};
58+
int ret;
59+
60+
if (!nfp_net_ebpf_capable(nn))
61+
return -EINVAL;
62+
63+
if (nn->dp.ctrl & NFP_NET_CFG_CTRL_BPF) {
64+
if (!nn->dp.bpf_offload_xdp)
65+
return prog ? -EBUSY : 0;
66+
cmd.command = prog ? TC_CLSBPF_REPLACE : TC_CLSBPF_DESTROY;
67+
} else {
68+
if (!prog)
69+
return 0;
70+
cmd.command = TC_CLSBPF_ADD;
71+
}
72+
73+
ret = nfp_net_bpf_offload(nn, &cmd);
74+
/* Stop offload if replace not possible */
75+
if (ret && cmd.command == TC_CLSBPF_REPLACE)
76+
nfp_bpf_xdp_offload(app, nn, NULL);
77+
nn->dp.bpf_offload_xdp = prog && !ret;
78+
return ret;
79+
}
80+
81+
static const char *nfp_bpf_extra_cap(struct nfp_app *app, struct nfp_net *nn)
82+
{
83+
return nfp_net_ebpf_capable(nn) ? "BPF" : "";
84+
}
85+
86+
static int
87+
nfp_bpf_vnic_init(struct nfp_app *app, struct nfp_net *nn, unsigned int id)
88+
{
89+
struct nfp_net_bpf_priv *priv;
90+
int ret;
91+
92+
/* Limit to single port, otherwise it's just a NIC */
93+
if (id > 0) {
94+
nfp_warn(app->cpp,
95+
"BPF NIC doesn't support more than one port right now\n");
96+
nn->port = nfp_port_alloc(app, NFP_PORT_INVALID, nn->dp.netdev);
97+
return PTR_ERR_OR_ZERO(nn->port);
98+
}
99+
100+
priv = kmalloc(sizeof(*priv), GFP_KERNEL);
101+
if (!priv)
102+
return -ENOMEM;
103+
104+
nn->app_priv = priv;
105+
spin_lock_init(&priv->rx_filter_lock);
106+
setup_timer(&priv->rx_filter_stats_timer,
107+
nfp_net_filter_stats_timer, (unsigned long)nn);
108+
109+
ret = nfp_app_nic_vnic_init(app, nn, id);
110+
if (ret)
111+
kfree(priv);
112+
113+
return ret;
114+
}
115+
116+
static void nfp_bpf_vnic_clean(struct nfp_app *app, struct nfp_net *nn)
117+
{
118+
if (nn->dp.bpf_offload_xdp)
119+
nfp_bpf_xdp_offload(app, nn, NULL);
120+
kfree(nn->app_priv);
121+
}
122+
123+
static int nfp_bpf_setup_tc(struct nfp_app *app, struct net_device *netdev,
124+
u32 handle, __be16 proto, struct tc_to_netdev *tc)
125+
{
126+
struct nfp_net *nn = netdev_priv(netdev);
127+
128+
if (TC_H_MAJ(handle) != TC_H_MAJ(TC_H_INGRESS))
129+
return -EOPNOTSUPP;
130+
if (proto != htons(ETH_P_ALL))
131+
return -EOPNOTSUPP;
132+
133+
if (tc->type == TC_SETUP_CLSBPF && nfp_net_ebpf_capable(nn)) {
134+
if (!nn->dp.bpf_offload_xdp)
135+
return nfp_net_bpf_offload(nn, tc->cls_bpf);
136+
else
137+
return -EBUSY;
138+
}
139+
140+
return -EINVAL;
141+
}
142+
143+
static bool nfp_bpf_tc_busy(struct nfp_app *app, struct nfp_net *nn)
144+
{
145+
return nn->dp.ctrl & NFP_NET_CFG_CTRL_BPF;
146+
}
147+
148+
const struct nfp_app_type app_bpf = {
149+
.id = NFP_APP_BPF_NIC,
150+
.name = "ebpf",
151+
152+
.extra_cap = nfp_bpf_extra_cap,
153+
154+
.vnic_init = nfp_bpf_vnic_init,
155+
.vnic_clean = nfp_bpf_vnic_clean,
156+
157+
.setup_tc = nfp_bpf_setup_tc,
158+
.tc_busy = nfp_bpf_tc_busy,
159+
.xdp_offload = nfp_bpf_xdp_offload,
160+
};

drivers/net/ethernet/netronome/nfp/nfp_bpf.h renamed to drivers/net/ethernet/netronome/nfp/bpf/main.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@
3939
#include <linux/list.h>
4040
#include <linux/types.h>
4141

42+
#include "../nfp_net.h"
43+
4244
/* For branch fixup logic use up-most byte of branch instruction as scratch
4345
* area. Remember to clear this before sending instructions to HW!
4446
*/
@@ -198,4 +200,25 @@ nfp_bpf_jit(struct bpf_prog *filter, void *prog, enum nfp_bpf_action_type act,
198200

199201
int nfp_prog_verify(struct nfp_prog *nfp_prog, struct bpf_prog *prog);
200202

203+
struct nfp_net;
204+
struct tc_cls_bpf_offload;
205+
206+
/**
207+
* struct nfp_net_bpf_priv - per-vNIC BPF private data
208+
* @rx_filter: Filter offload statistics - dropped packets/bytes
209+
* @rx_filter_prev: Filter offload statistics - values from previous update
210+
* @rx_filter_change: Jiffies when statistics last changed
211+
* @rx_filter_stats_timer: Timer for polling filter offload statistics
212+
* @rx_filter_lock: Lock protecting timer state changes (teardown)
213+
*/
214+
struct nfp_net_bpf_priv {
215+
struct nfp_stat_pair rx_filter, rx_filter_prev;
216+
unsigned long rx_filter_change;
217+
struct timer_list rx_filter_stats_timer;
218+
spinlock_t rx_filter_lock;
219+
};
220+
221+
int nfp_net_bpf_offload(struct nfp_net *nn, struct tc_cls_bpf_offload *cls_bpf);
222+
void nfp_net_filter_stats_timer(unsigned long data);
223+
201224
#endif

0 commit comments

Comments
 (0)