From patchwork Thu Jul 12 03:36:44 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Kicinski X-Patchwork-Id: 942772 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@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; dmarc=none (p=none dis=none) header.from=netronome.com 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="WoWbnoZJ"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 41R1pC5K7Lz9s1R for ; Thu, 12 Jul 2018 13:37:07 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726730AbeGLDoj (ORCPT ); Wed, 11 Jul 2018 23:44:39 -0400 Received: from mail-qt0-f194.google.com ([209.85.216.194]:35980 "EHLO mail-qt0-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726497AbeGLDoj (ORCPT ); Wed, 11 Jul 2018 23:44:39 -0400 Received: by mail-qt0-f194.google.com with SMTP id f1-v6so23008881qti.3 for ; Wed, 11 Jul 2018 20:37:05 -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=hWGIrsc1tap7hlXdgPC2qXNCDFWPJ075HwdgsUUeALI=; b=WoWbnoZJ6WCVut53g+hUt1JYj7jNyz51nrOafC4aChqFkBj5jtuJOW3gNJ1d5oNpg9 sjX0i1DeB1D/IkNq/JWPTlVv/UEV2O6lb53dYxo3qVaSRehEwJhrhFRN8imU0EptbGVb DUyHr2rvfLPWI64SNb02DX8XZQDlv7UVf6PpAYwmm85U4rsqxArHr4/T5Gwd2IIlF4YV D37vfuJpDiMhFEU5PRuD10HrThci0RwbrBHXI0tlQa+dL8y0+yo4nQJ7/GF6ed+F4QPx 6iTZT4txHJFAv8XlcTGnmoUbviAHmelmIS3DgHMqQUVHR3mBbF6pmPGSqYoTnYRKGofX QkDQ== 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=hWGIrsc1tap7hlXdgPC2qXNCDFWPJ075HwdgsUUeALI=; b=ek1JpxfACLOR+rJrFvPy1MbcTERCzwQDhpSvsRU98VbZGvUPBJ7w7FMKKPkZX7Yzr5 yJDDNneYKpvW9Z8jSv7Pvi1x70ufEOZUuwDiVOoQfwtLHysEQpoNCy3ZuAaWv2wpph8l HmDwT6aTypjghDupUD+HQlNzNK0BIj7fPsnQgF/KHSB060KC7lTIC+fCe95Wxy3ioWXj hrDN18pJ9O8Y86ASKanNqWOuxcxCGBiCI7jIZfQ+uXK5D6vyqFBFw67zl1eYmZ++bIbB GqJGzbfILqtZXtbyklbGhPHS+/B8kdyYraPEiWWBU09DkH4BhAv0CsFJw5fq+E3e2yKG C75A== X-Gm-Message-State: AOUpUlHbtXJlBdQa0pu5vkHF6mWB+c7kizJe9ufwq8L7BhibZU5rdYuv TPS2Q+3+uyKX7ZoXIvelwOcWlw== X-Google-Smtp-Source: AAOMgpf7E9NUQZNY3/lHNkd2y8mfgF8S1QIX0CwG3cxcJpst9zv0jndJVm+dMg5MVXxbSkcbbpVY3A== X-Received: by 2002:a0c:bc8a:: with SMTP id l10-v6mr561893qvg.130.1531366624512; Wed, 11 Jul 2018 20:37:04 -0700 (PDT) Received: from jkicinski-Precision-T1700.netronome.com ([75.53.12.129]) by smtp.gmail.com with ESMTPSA id s125-v6sm9350072qkd.14.2018.07.11.20.37.03 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 11 Jul 2018 20:37:04 -0700 (PDT) From: Jakub Kicinski To: alexei.starovoitov@gmail.com, daniel@iogearbox.net Cc: oss-drivers@netronome.com, netdev@vger.kernel.org, Jakub Kicinski Subject: [PATCH bpf-next 7/7] nfp: add support for simultaneous driver and hw XDP Date: Wed, 11 Jul 2018 20:36:44 -0700 Message-Id: <20180712033644.23954-8-jakub.kicinski@netronome.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180712033644.23954-1-jakub.kicinski@netronome.com> References: <20180712033644.23954-1-jakub.kicinski@netronome.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Split handling of offloaded and driver programs completely. Since offloaded programs always come with XDP_FLAGS_HW_MODE set in reality there could be no sharing, anyway, programs would only be installed in driver or in hardware. Splitting the handling allows us to install programs in HW and in driver at the same time. Signed-off-by: Jakub Kicinski Reviewed-by: Quentin Monnet --- drivers/net/ethernet/netronome/nfp/bpf/main.c | 11 +---- drivers/net/ethernet/netronome/nfp/nfp_net.h | 6 +-- .../ethernet/netronome/nfp/nfp_net_common.c | 49 ++++++++----------- 3 files changed, 26 insertions(+), 40 deletions(-) diff --git a/drivers/net/ethernet/netronome/nfp/bpf/main.c b/drivers/net/ethernet/netronome/nfp/bpf/main.c index 4dbf7cba6377..b95b94d008cf 100644 --- a/drivers/net/ethernet/netronome/nfp/bpf/main.c +++ b/drivers/net/ethernet/netronome/nfp/bpf/main.c @@ -66,26 +66,19 @@ nfp_bpf_xdp_offload(struct nfp_app *app, struct nfp_net *nn, struct bpf_prog *prog, struct netlink_ext_ack *extack) { bool running, xdp_running; - int ret; if (!nfp_net_ebpf_capable(nn)) return -EINVAL; running = nn->dp.ctrl & NFP_NET_CFG_CTRL_BPF; - xdp_running = running && nn->dp.bpf_offload_xdp; + xdp_running = running && nn->xdp_hw.prog; if (!prog && !xdp_running) return 0; if (prog && running && !xdp_running) return -EBUSY; - ret = nfp_net_bpf_offload(nn, prog, running, extack); - /* Stop offload if replace not possible */ - if (ret) - return ret; - - nn->dp.bpf_offload_xdp = !!prog; - return ret; + return nfp_net_bpf_offload(nn, prog, running, extack); } static const char *nfp_bpf_extra_cap(struct nfp_app *app, struct nfp_net *nn) diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net.h b/drivers/net/ethernet/netronome/nfp/nfp_net.h index 2021dda595b7..8970ec981e11 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_net.h +++ b/drivers/net/ethernet/netronome/nfp/nfp_net.h @@ -485,7 +485,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_xdp: Offloaded BPF program is XDP * @chained_metadata_format: Firemware will use new metadata format * @rx_dma_dir: Mapping direction for RX buffers * @rx_dma_off: Offset at which DMA packets (for XDP headroom) @@ -510,7 +509,6 @@ struct nfp_net_dp { struct net_device *netdev; u8 is_vf:1; - u8 bpf_offload_xdp:1; u8 chained_metadata_format:1; u8 rx_dma_dir; @@ -553,7 +551,8 @@ struct nfp_net_dp { * @rss_cfg: RSS configuration * @rss_key: RSS secret key * @rss_itbl: RSS indirection table - * @xdp: Information about the attached XDP program + * @xdp: Information about the driver XDP program + * @xdp_hw: Information about the HW XDP program * @max_r_vecs: Number of allocated interrupt vectors for RX/TX * @max_tx_rings: Maximum number of TX rings supported by the Firmware * @max_rx_rings: Maximum number of RX rings supported by the Firmware @@ -610,6 +609,7 @@ struct nfp_net { u8 rss_itbl[NFP_NET_CFG_RSS_ITBL_SZ]; struct xdp_attachment_info xdp; + struct xdp_attachment_info xdp_hw; unsigned int max_tx_rings; unsigned int max_rx_rings; diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c index bb1e72e8dbc2..a712e83c3f0f 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c +++ b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c @@ -1710,8 +1710,7 @@ static int nfp_net_rx(struct nfp_net_rx_ring *rx_ring, int budget) } } - if (xdp_prog && !(rxd->rxd.flags & PCIE_DESC_RX_BPF && - dp->bpf_offload_xdp) && !meta.portid) { + if (xdp_prog && !meta.portid) { void *orig_data = rxbuf->frag + pkt_off; unsigned int dma_off; int act; @@ -3393,14 +3392,18 @@ static void nfp_net_del_vxlan_port(struct net_device *netdev, nfp_net_set_vxlan_port(nn, idx, 0); } -static int -nfp_net_xdp_setup_drv(struct nfp_net *nn, struct bpf_prog *prog, - struct netlink_ext_ack *extack) +static int nfp_net_xdp_setup_drv(struct nfp_net *nn, struct netdev_bpf *bpf) { + struct bpf_prog *prog = bpf->prog; struct nfp_net_dp *dp; + int err; + + if (!xdp_attachment_flags_ok(&nn->xdp, bpf)) + return -EBUSY; if (!prog == !nn->dp.xdp_prog) { WRITE_ONCE(nn->dp.xdp_prog, prog); + xdp_attachment_setup(&nn->xdp, bpf); return 0; } @@ -3414,33 +3417,26 @@ nfp_net_xdp_setup_drv(struct nfp_net *nn, struct bpf_prog *prog, dp->rx_dma_off = prog ? XDP_PACKET_HEADROOM - nn->dp.rx_offset : 0; /* We need RX reconfig to remap the buffers (BIDIR vs FROM_DEV) */ - return nfp_net_ring_reconfig(nn, dp, extack); + err = nfp_net_ring_reconfig(nn, dp, bpf->extack); + if (err) + return err; + + xdp_attachment_setup(&nn->xdp, bpf); + return 0; } -static int nfp_net_xdp_setup(struct nfp_net *nn, struct netdev_bpf *bpf) +static int nfp_net_xdp_setup_hw(struct nfp_net *nn, struct netdev_bpf *bpf) { - struct bpf_prog *drv_prog, *offload_prog; int err; - if (!xdp_attachment_flags_ok(&nn->xdp, bpf)) + if (!xdp_attachment_flags_ok(&nn->xdp_hw, bpf)) return -EBUSY; - /* Load both when no flags set to allow easy activation of driver path - * when program is replaced by one which can't be offloaded. - */ - drv_prog = bpf->flags & XDP_FLAGS_HW_MODE ? NULL : bpf->prog; - offload_prog = bpf->flags & XDP_FLAGS_DRV_MODE ? NULL : bpf->prog; - - err = nfp_net_xdp_setup_drv(nn, drv_prog, bpf->extack); + err = nfp_app_xdp_offload(nn->app, nn, bpf->prog, bpf->extack); if (err) return err; - err = nfp_app_xdp_offload(nn->app, nn, offload_prog, bpf->extack); - if (err && bpf->flags & XDP_FLAGS_HW_MODE) - return err; - - xdp_attachment_setup(&nn->xdp, bpf); - + xdp_attachment_setup(&nn->xdp_hw, bpf); return 0; } @@ -3450,16 +3446,13 @@ static int nfp_net_xdp(struct net_device *netdev, struct netdev_bpf *xdp) switch (xdp->command) { case XDP_SETUP_PROG: + return nfp_net_xdp_setup_drv(nn, xdp); case XDP_SETUP_PROG_HW: - return nfp_net_xdp_setup(nn, xdp); + return nfp_net_xdp_setup_hw(nn, xdp); case XDP_QUERY_PROG: - if (nn->dp.bpf_offload_xdp) - return 0; return xdp_attachment_query(&nn->xdp, xdp); case XDP_QUERY_PROG_HW: - if (!nn->dp.bpf_offload_xdp) - return 0; - return xdp_attachment_query(&nn->xdp, xdp); + return xdp_attachment_query(&nn->xdp_hw, xdp); default: return nfp_app_bpf(nn->app, nn, xdp); }