From patchwork Fri Nov 3 20:56:26 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Kicinski X-Patchwork-Id: 834093 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=netronome-com.20150623.gappssmtp.com header.i=@netronome-com.20150623.gappssmtp.com header.b="AglhR+X5"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3yTDm61Ykdz9s7p for ; Sat, 4 Nov 2017 07:57:10 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755742AbdKCU46 (ORCPT ); Fri, 3 Nov 2017 16:56:58 -0400 Received: from mail-pg0-f65.google.com ([74.125.83.65]:53641 "EHLO mail-pg0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754855AbdKCU44 (ORCPT ); Fri, 3 Nov 2017 16:56:56 -0400 Received: by mail-pg0-f65.google.com with SMTP id s2so3436009pge.10 for ; Fri, 03 Nov 2017 13:56:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=netronome-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=5cjJl0nXNkRF3ANhTtv4wCx/P1PbIhusNJiFpLkb+Q4=; b=AglhR+X50Y1pMTNNeo3REIRs06IbhaUsl8zd32uBE/KX7AltqzCVViCffVXmMsH+XH K1GNC9a/V5KAEmI82GkPgHYvAzOJ2DKzXvkPnwvpn4jufbmXqBgUmu0QaqENAuw8fHqY QEjzqaRErDo4ht5GmyjtrfhOnX1oTpIGWda0P8HhyUfJLJqtLBxokv6OCqY7U3nIi+us hT/VZ/QIX0rif5dKaDrJVSad7FklVjwuBoSTeJRCXeIgC/GSBcWCzvHrQck16NNuF6W9 LIjOTXIzJxZR9J6D0iJWRO+wFS3DPWXqUtktbltuCgRWBYR7+4CoMK0CqKX4yiY9qzCZ Iusw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=5cjJl0nXNkRF3ANhTtv4wCx/P1PbIhusNJiFpLkb+Q4=; b=r7xQa1fEPoSrw9B0UET3QJIgQLHXr18zDsDflCMZ5BfciMywhHMhlEV188KHz0FjSx /z9Xk6MNfFkVkXaBK53aehTpKGxIR0Meh24o+jdEpfjAX0iBNLv8yruqEGTdT58i4gbQ V7Rtl+g7umhqh1nSK8npDSzeIkw69rbCkQEk5w/gQvHn9kzTi6zjRqOEXny4zNYfCPpU l3OQTEQAkdcNwr7hbxTp1993l9Ga3zW3MxYZ3I5QE/jN6+S6F1Wk2eeBkkbnubHLxrOV bLGqIl4gqfkrVj6sNkn7K3EP4dVvDzeq5yYIbLJnEuU4b043GSamlWwFpAo/9xK7Cq/k lcUQ== X-Gm-Message-State: AMCzsaW6zwW86opCCKEsA71i7Sjm+u4FEBD6+hsP64zs/u88p1ZEqgSY 9pKbmhK7hDuP3eWeTN2fdHJ462nO X-Google-Smtp-Source: ABhQp+TCQcMIwzUy0pLvPP6T1nnH853I6Q2rKdQWK7Lgl0hBxY016IFFguofrURB6YYz+jBx6CQdPA== X-Received: by 10.99.141.200 with SMTP id z191mr8095966pgd.73.1509742615367; Fri, 03 Nov 2017 13:56:55 -0700 (PDT) Received: from jkicinski-Precision-T1700.netronome.com ([75.53.12.129]) by smtp.gmail.com with ESMTPSA id o10sm9989029pgq.69.2017.11.03.13.56.54 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 03 Nov 2017 13:56:54 -0700 (PDT) From: Jakub Kicinski To: netdev@vger.kernel.org Cc: oss-drivers@netronome.com, alexei.starovoitov@gmail.com, daniel@iogearbox.net, Jakub Kicinski Subject: [PATCH net-next v2 11/15] nfp: bpf: require seamless reload for program replace Date: Fri, 3 Nov 2017 13:56:26 -0700 Message-Id: <20171103205630.1083-12-jakub.kicinski@netronome.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20171103205630.1083-1-jakub.kicinski@netronome.com> References: <20171103205630.1083-1-jakub.kicinski@netronome.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Firmware supports live replacement of programs for quite some time now. Remove the software-fallback related logic and depend on the FW for program replace. Seamless reload will become a requirement if maps are present, anyway. Load and start stages have to be split now, since replace only needs a load, start has already been done on add. Signed-off-by: Jakub Kicinski Reviewed-by: Quentin Monnet --- drivers/net/ethernet/netronome/nfp/bpf/main.c | 11 ++--- drivers/net/ethernet/netronome/nfp/bpf/main.h | 2 +- drivers/net/ethernet/netronome/nfp/bpf/offload.c | 62 ++++++++++++------------ drivers/net/ethernet/netronome/nfp/nfp_net.h | 2 - 4 files changed, 35 insertions(+), 42 deletions(-) diff --git a/drivers/net/ethernet/netronome/nfp/bpf/main.c b/drivers/net/ethernet/netronome/nfp/bpf/main.c index 9e1286346d42..7ae7528cd96b 100644 --- a/drivers/net/ethernet/netronome/nfp/bpf/main.c +++ b/drivers/net/ethernet/netronome/nfp/bpf/main.c @@ -68,7 +68,7 @@ nfp_bpf_xdp_offload(struct nfp_app *app, struct nfp_net *nn, if (prog && running && !xdp_running) return -EBUSY; - ret = nfp_net_bpf_offload(nn, prog, running, true); + ret = nfp_net_bpf_offload(nn, prog, running); /* Stop offload if replace not possible */ if (ret && prog) nfp_bpf_xdp_offload(app, nn, NULL); @@ -93,7 +93,6 @@ static int nfp_bpf_setup_tc_block_cb(enum tc_setup_type type, { struct tc_cls_bpf_offload *cls_bpf = type_data; struct nfp_net *nn = cb_priv; - bool skip_sw; if (type != TC_SETUP_CLSBPF || !tc_can_offload(nn->dp.netdev) || @@ -111,15 +110,13 @@ static int nfp_bpf_setup_tc_block_cb(enum tc_setup_type type, return -EOPNOTSUPP; } - skip_sw = !!(cls_bpf->gen_flags & TCA_CLS_FLAGS_SKIP_SW); - switch (cls_bpf->command) { case TC_CLSBPF_REPLACE: - return nfp_net_bpf_offload(nn, cls_bpf->prog, true, !skip_sw); + return nfp_net_bpf_offload(nn, cls_bpf->prog, true); case TC_CLSBPF_ADD: - return nfp_net_bpf_offload(nn, cls_bpf->prog, false, !skip_sw); + return nfp_net_bpf_offload(nn, cls_bpf->prog, false); case TC_CLSBPF_DESTROY: - return nfp_net_bpf_offload(nn, NULL, true, !skip_sw); + return nfp_net_bpf_offload(nn, NULL, true); default: return -EOPNOTSUPP; } diff --git a/drivers/net/ethernet/netronome/nfp/bpf/main.h b/drivers/net/ethernet/netronome/nfp/bpf/main.h index 6dddab95d57a..df56f40fea7c 100644 --- a/drivers/net/ethernet/netronome/nfp/bpf/main.h +++ b/drivers/net/ethernet/netronome/nfp/bpf/main.h @@ -183,6 +183,6 @@ int nfp_prog_verify(struct nfp_prog *nfp_prog, struct bpf_prog *prog); struct nfp_net; int nfp_net_bpf_offload(struct nfp_net *nn, struct bpf_prog *prog, - bool old_prog, bool sw_fallback); + bool old_prog); #endif diff --git a/drivers/net/ethernet/netronome/nfp/bpf/offload.c b/drivers/net/ethernet/netronome/nfp/bpf/offload.c index c09efa1a9649..f4b9a46c844d 100644 --- a/drivers/net/ethernet/netronome/nfp/bpf/offload.c +++ b/drivers/net/ethernet/netronome/nfp/bpf/offload.c @@ -94,14 +94,11 @@ nfp_net_bpf_offload_prepare(struct nfp_net *nn, struct bpf_prog *prog, } static void -nfp_net_bpf_load_and_start(struct nfp_net *nn, bool sw_fallback, - void *code, dma_addr_t dma_addr, - unsigned int code_sz, unsigned int n_instr) +nfp_net_bpf_load(struct nfp_net *nn, void *code, dma_addr_t dma_addr, + unsigned int code_sz, unsigned int n_instr) { int err; - nn->dp.bpf_offload_skip_sw = !sw_fallback; - nn_writew(nn, NFP_NET_CFG_BPF_SIZE, n_instr); nn_writeq(nn, NFP_NET_CFG_BPF_ADDR, dma_addr); @@ -110,14 +107,19 @@ nfp_net_bpf_load_and_start(struct nfp_net *nn, bool sw_fallback, if (err) nn_err(nn, "FW command error while loading BPF: %d\n", err); + dma_free_coherent(nn->dp.dev, code_sz, code, dma_addr); +} + +static void nfp_net_bpf_start(struct nfp_net *nn) +{ + int err; + /* Enable passing packets through BPF function */ nn->dp.ctrl |= NFP_NET_CFG_CTRL_BPF; nn_writel(nn, NFP_NET_CFG_CTRL, nn->dp.ctrl); err = nfp_net_reconfig(nn, NFP_NET_CFG_UPDATE_GEN); if (err) nn_err(nn, "FW command error while enabling BPF: %d\n", err); - - dma_free_coherent(nn->dp.dev, code_sz, code, dma_addr); } static int nfp_net_bpf_stop(struct nfp_net *nn) @@ -127,13 +129,12 @@ static int nfp_net_bpf_stop(struct nfp_net *nn) nn->dp.ctrl &= ~NFP_NET_CFG_CTRL_BPF; nn_writel(nn, NFP_NET_CFG_CTRL, nn->dp.ctrl); - nn->dp.bpf_offload_skip_sw = 0; return nfp_net_reconfig(nn, NFP_NET_CFG_UPDATE_GEN); } int nfp_net_bpf_offload(struct nfp_net *nn, struct bpf_prog *prog, - bool old_prog, bool sw_fallback) + bool old_prog) { struct nfp_bpf_result res; dma_addr_t dma_addr; @@ -141,37 +142,34 @@ int nfp_net_bpf_offload(struct nfp_net *nn, struct bpf_prog *prog, void *code; int err; - /* There is nothing stopping us from implementing seamless - * replace but the simple method of loading I adopted in - * the firmware does not handle atomic replace (i.e. we have to - * stop the BPF offload and re-enable it). Leaking-in a few - * frames which didn't have BPF applied in the hardware should - * be fine if software fallback is available, though. - */ - if (prog && old_prog && nn->dp.bpf_offload_skip_sw) - return -EBUSY; + if (prog && old_prog) { + u8 cap; + + cap = nn_readb(nn, NFP_NET_CFG_BPF_CAP); + if (!(cap & NFP_NET_BPF_CAP_RELO)) { + nn_err(nn, "FW does not support live reload\n"); + return -EBUSY; + } + } /* Something else is loaded, different program type? */ if (!old_prog && nn->dp.ctrl & NFP_NET_CFG_CTRL_BPF) return -EBUSY; - max_instr = nn_readw(nn, NFP_NET_CFG_BPF_MAX_LEN); - code = NULL; + if (old_prog && !prog) + return nfp_net_bpf_stop(nn); - if (prog) { - err = nfp_net_bpf_offload_prepare(nn, prog, &res, &code, - &dma_addr, max_instr); - if (err) - return err; - } + max_instr = nn_readw(nn, NFP_NET_CFG_BPF_MAX_LEN); - if (old_prog) - nfp_net_bpf_stop(nn); + err = nfp_net_bpf_offload_prepare(nn, prog, &res, &code, &dma_addr, + max_instr); + if (err) + return err; - if (prog) - nfp_net_bpf_load_and_start(nn, sw_fallback, code, - dma_addr, max_instr * sizeof(u64), - res.n_instr); + nfp_net_bpf_load(nn, code, dma_addr, max_instr * sizeof(u64), + res.n_instr); + if (!old_prog) + nfp_net_bpf_start(nn); return 0; } diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net.h b/drivers/net/ethernet/netronome/nfp/nfp_net.h index 3d411f0d15b6..7f9857c276b1 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_net.h +++ b/drivers/net/ethernet/netronome/nfp/nfp_net.h @@ -476,7 +476,6 @@ struct nfp_stat_pair { * @dev: Backpointer to struct device * @netdev: Backpointer to net_device structure * @is_vf: Is the driver attached to a VF? - * @bpf_offload_skip_sw: Offloaded BPF program will not be rerun by cls_bpf * @bpf_offload_xdp: Offloaded BPF program is XDP * @chained_metadata_format: Firemware will use new metadata format * @rx_dma_dir: Mapping direction for RX buffers @@ -502,7 +501,6 @@ struct nfp_net_dp { struct net_device *netdev; u8 is_vf:1; - u8 bpf_offload_skip_sw:1; u8 bpf_offload_xdp:1; u8 chained_metadata_format:1;