Skip to content

Commit c702558

Browse files
committed
Merge branch 'nfp-fix-disabling-TC-offloads-in-flower-max-TSO-segs-and-module-version'
Jakub Kicinski says: ==================== nfp: fix disabling TC offloads in flower, max TSO segs and module version This set corrects the way nfp deals with the NETIF_F_HW_TC flag. It has slipped the review that flower offload does not currently refuse disabling this flag when filter offload is active. nfp's flower offload does not actually keep track of how many filters for each port are offloaded. The accounting of the number of filters is added to the nfp core structures, and BPF moved to use these structures as well. If users are allowed to disable TC offloads while filters are active, not only is it incorrect behaviour, but actually the NFP will never be told to remove the flows, leading to use-after-free when stats arrive. Fourth patch makes sure we declare the max number of TSO segments. FW should drop longer packets cleanly (otherwise this would be a security problem for untrusted VFs) but dropping longer TSO frames is not nice and driver should prevent them from being generated. Last small addition populates MODULE_VERSION with kernel version. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 5c487bb + 1a5e8e3 commit c702558

File tree

9 files changed

+53
-23
lines changed

9 files changed

+53
-23
lines changed

drivers/net/ethernet/netronome/nfp/bpf/main.c

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535

3636
#include "../nfpcore/nfp_cpp.h"
3737
#include "../nfpcore/nfp_nffw.h"
38+
#include "../nfpcore/nfp_nsp.h"
3839
#include "../nfp_app.h"
3940
#include "../nfp_main.h"
4041
#include "../nfp_net.h"
@@ -87,9 +88,20 @@ static const char *nfp_bpf_extra_cap(struct nfp_app *app, struct nfp_net *nn)
8788
static int
8889
nfp_bpf_vnic_alloc(struct nfp_app *app, struct nfp_net *nn, unsigned int id)
8990
{
91+
struct nfp_pf *pf = app->pf;
9092
struct nfp_bpf_vnic *bv;
9193
int err;
9294

95+
if (!pf->eth_tbl) {
96+
nfp_err(pf->cpp, "No ETH table\n");
97+
return -EINVAL;
98+
}
99+
if (pf->max_data_vnics != pf->eth_tbl->count) {
100+
nfp_err(pf->cpp, "ETH entries don't match vNICs (%d vs %d)\n",
101+
pf->max_data_vnics, pf->eth_tbl->count);
102+
return -EINVAL;
103+
}
104+
93105
bv = kzalloc(sizeof(*bv), GFP_KERNEL);
94106
if (!bv)
95107
return -ENOMEM;
@@ -170,6 +182,7 @@ static int nfp_bpf_setup_tc_block_cb(enum tc_setup_type type,
170182
return err;
171183

172184
bv->tc_prog = cls_bpf->prog;
185+
nn->port->tc_offload_cnt = !!bv->tc_prog;
173186
return 0;
174187
}
175188

@@ -207,13 +220,6 @@ static int nfp_bpf_setup_tc(struct nfp_app *app, struct net_device *netdev,
207220
}
208221
}
209222

210-
static bool nfp_bpf_tc_busy(struct nfp_app *app, struct nfp_net *nn)
211-
{
212-
struct nfp_bpf_vnic *bv = nn->app_priv;
213-
214-
return !!bv->tc_prog;
215-
}
216-
217223
static int
218224
nfp_bpf_change_mtu(struct nfp_app *app, struct net_device *netdev, int new_mtu)
219225
{
@@ -417,7 +423,6 @@ const struct nfp_app_type app_bpf = {
417423
.ctrl_msg_rx = nfp_bpf_ctrl_msg_rx,
418424

419425
.setup_tc = nfp_bpf_setup_tc,
420-
.tc_busy = nfp_bpf_tc_busy,
421426
.bpf = nfp_ndo_bpf,
422427
.xdp_offload = nfp_bpf_xdp_offload,
423428
};

drivers/net/ethernet/netronome/nfp/flower/offload.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,7 @@ nfp_flower_add_offload(struct nfp_app *app, struct net_device *netdev,
349349
struct tc_cls_flower_offload *flow, bool egress)
350350
{
351351
enum nfp_flower_tun_type tun_type = NFP_FL_TUNNEL_NONE;
352+
struct nfp_port *port = nfp_port_from_netdev(netdev);
352353
struct nfp_flower_priv *priv = app->priv;
353354
struct nfp_fl_payload *flow_pay;
354355
struct nfp_fl_key_ls *key_layer;
@@ -390,6 +391,7 @@ nfp_flower_add_offload(struct nfp_app *app, struct net_device *netdev,
390391
INIT_HLIST_NODE(&flow_pay->link);
391392
flow_pay->tc_flower_cookie = flow->cookie;
392393
hash_add_rcu(priv->flow_table, &flow_pay->link, flow->cookie);
394+
port->tc_offload_cnt++;
393395

394396
/* Deallocate flow payload when flower rule has been destroyed. */
395397
kfree(key_layer);
@@ -421,6 +423,7 @@ static int
421423
nfp_flower_del_offload(struct nfp_app *app, struct net_device *netdev,
422424
struct tc_cls_flower_offload *flow)
423425
{
426+
struct nfp_port *port = nfp_port_from_netdev(netdev);
424427
struct nfp_fl_payload *nfp_flow;
425428
int err;
426429

@@ -442,6 +445,7 @@ nfp_flower_del_offload(struct nfp_app *app, struct net_device *netdev,
442445

443446
err_free_flow:
444447
hash_del_rcu(&nfp_flow->link);
448+
port->tc_offload_cnt--;
445449
kfree(nfp_flow->action_data);
446450
kfree(nfp_flow->mask_data);
447451
kfree(nfp_flow->unmasked_data);

drivers/net/ethernet/netronome/nfp/nfp_app.h

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,6 @@ extern const struct nfp_app_type app_flower;
9292
* @stop: stop application logic
9393
* @ctrl_msg_rx: control message handler
9494
* @setup_tc: setup TC ndo
95-
* @tc_busy: TC HW offload busy (rules loaded)
9695
* @bpf: BPF ndo offload-related calls
9796
* @xdp_offload: offload an XDP program
9897
* @eswitch_mode_get: get SR-IOV eswitch mode
@@ -135,7 +134,6 @@ struct nfp_app_type {
135134

136135
int (*setup_tc)(struct nfp_app *app, struct net_device *netdev,
137136
enum tc_setup_type type, void *type_data);
138-
bool (*tc_busy)(struct nfp_app *app, struct nfp_net *nn);
139137
int (*bpf)(struct nfp_app *app, struct nfp_net *nn,
140138
struct netdev_bpf *xdp);
141139
int (*xdp_offload)(struct nfp_app *app, struct nfp_net *nn,
@@ -301,13 +299,6 @@ static inline bool nfp_app_has_tc(struct nfp_app *app)
301299
return app && app->type->setup_tc;
302300
}
303301

304-
static inline bool nfp_app_tc_busy(struct nfp_app *app, struct nfp_net *nn)
305-
{
306-
if (!app || !app->type->tc_busy)
307-
return false;
308-
return app->type->tc_busy(app, nn);
309-
}
310-
311302
static inline int nfp_app_setup_tc(struct nfp_app *app,
312303
struct net_device *netdev,
313304
enum tc_setup_type type, void *type_data)

drivers/net/ethernet/netronome/nfp/nfp_main.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -649,3 +649,4 @@ MODULE_FIRMWARE("netronome/nic_AMDA0099-0001_2x25.nffw");
649649
MODULE_AUTHOR("Netronome Systems <[email protected]>");
650650
MODULE_LICENSE("GPL");
651651
MODULE_DESCRIPTION("The Netronome Flow Processor (NFP) driver.");
652+
MODULE_VERSION(UTS_RELEASE);

drivers/net/ethernet/netronome/nfp/nfp_net_common.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3210,10 +3210,9 @@ static int nfp_net_set_features(struct net_device *netdev,
32103210
new_ctrl &= ~NFP_NET_CFG_CTRL_GATHER;
32113211
}
32123212

3213-
if (changed & NETIF_F_HW_TC && nfp_app_tc_busy(nn->app, nn)) {
3214-
nn_err(nn, "Cannot disable HW TC offload while in use\n");
3215-
return -EBUSY;
3216-
}
3213+
err = nfp_port_set_features(netdev, features);
3214+
if (err)
3215+
return err;
32173216

32183217
nn_dbg(nn, "Feature change 0x%llx -> 0x%llx (changed=0x%llx)\n",
32193218
netdev->features, features, changed);
@@ -3734,7 +3733,7 @@ static void nfp_net_netdev_init(struct nfp_net *nn)
37343733

37353734
netdev->features = netdev->hw_features;
37363735

3737-
if (nfp_app_has_tc(nn->app))
3736+
if (nfp_app_has_tc(nn->app) && nn->port)
37383737
netdev->hw_features |= NETIF_F_HW_TC;
37393738

37403739
/* Advertise but disable TSO by default. */
@@ -3751,6 +3750,8 @@ static void nfp_net_netdev_init(struct nfp_net *nn)
37513750
netdev->min_mtu = ETH_MIN_MTU;
37523751
netdev->max_mtu = nn->max_mtu;
37533752

3753+
netdev->gso_max_segs = NFP_NET_LSO_MAX_SEGS;
3754+
37543755
netif_carrier_off(netdev);
37553756

37563757
nfp_net_set_ethtool_ops(netdev);

drivers/net/ethernet/netronome/nfp/nfp_net_ctrl.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,12 @@
5959
#define NFP_NET_RX_OFFSET 32
6060

6161
/**
62-
* Maximum header size supported for LSO frames
62+
* LSO parameters
63+
* %NFP_NET_LSO_MAX_HDR_SZ: Maximum header size supported for LSO frames
64+
* %NFP_NET_LSO_MAX_SEGS: Maximum number of segments LSO frame can produce
6365
*/
6466
#define NFP_NET_LSO_MAX_HDR_SZ 255
67+
#define NFP_NET_LSO_MAX_SEGS 64
6568

6669
/**
6770
* Prepend field types

drivers/net/ethernet/netronome/nfp/nfp_net_repr.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,7 @@ const struct net_device_ops nfp_repr_netdev_ops = {
265265
.ndo_set_vf_spoofchk = nfp_app_set_vf_spoofchk,
266266
.ndo_get_vf_config = nfp_app_get_vf_config,
267267
.ndo_set_vf_link_state = nfp_app_set_vf_link_state,
268+
.ndo_set_features = nfp_port_set_features,
268269
};
269270

270271
static void nfp_repr_clean(struct nfp_repr *repr)

drivers/net/ethernet/netronome/nfp/nfp_port.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
*/
3333

3434
#include <linux/lockdep.h>
35+
#include <linux/netdevice.h>
3536
#include <net/switchdev.h>
3637

3738
#include "nfpcore/nfp_cpp.h"
@@ -100,6 +101,23 @@ int nfp_port_setup_tc(struct net_device *netdev, enum tc_setup_type type,
100101
return nfp_app_setup_tc(port->app, netdev, type, type_data);
101102
}
102103

104+
int nfp_port_set_features(struct net_device *netdev, netdev_features_t features)
105+
{
106+
struct nfp_port *port;
107+
108+
port = nfp_port_from_netdev(netdev);
109+
if (!port)
110+
return 0;
111+
112+
if ((netdev->features & NETIF_F_HW_TC) > (features & NETIF_F_HW_TC) &&
113+
port->tc_offload_cnt) {
114+
netdev_err(netdev, "Cannot disable HW TC offload while offloads active\n");
115+
return -EBUSY;
116+
}
117+
118+
return 0;
119+
}
120+
103121
struct nfp_port *
104122
nfp_port_from_id(struct nfp_pf *pf, enum nfp_port_type type, unsigned int id)
105123
{

drivers/net/ethernet/netronome/nfp/nfp_port.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ enum nfp_port_flags {
7272
* @netdev: backpointer to associated netdev
7373
* @type: what port type does the entity represent
7474
* @flags: port flags
75+
* @tc_offload_cnt: number of active TC offloads, how offloads are counted
76+
* is not defined, use as a boolean
7577
* @app: backpointer to the app structure
7678
* @dl_port: devlink port structure
7779
* @eth_id: for %NFP_PORT_PHYS_PORT port ID in NFP enumeration scheme
@@ -87,6 +89,7 @@ struct nfp_port {
8789
enum nfp_port_type type;
8890

8991
unsigned long flags;
92+
unsigned long tc_offload_cnt;
9093

9194
struct nfp_app *app;
9295

@@ -121,6 +124,9 @@ static inline bool nfp_port_is_vnic(const struct nfp_port *port)
121124
return port->type == NFP_PORT_PF_PORT || port->type == NFP_PORT_VF_PORT;
122125
}
123126

127+
int
128+
nfp_port_set_features(struct net_device *netdev, netdev_features_t features);
129+
124130
struct nfp_port *nfp_port_from_netdev(struct net_device *netdev);
125131
struct nfp_port *
126132
nfp_port_from_id(struct nfp_pf *pf, enum nfp_port_type type, unsigned int id);

0 commit comments

Comments
 (0)