From patchwork Mon Apr 15 14:55:53 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Horman X-Patchwork-Id: 1085676 X-Patchwork-Delegate: davem@davemloft.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="pPjZS6yY"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 44jWm51fHHz9sBF for ; Tue, 16 Apr 2019 00:56:20 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727808AbfDOO4T (ORCPT ); Mon, 15 Apr 2019 10:56:19 -0400 Received: from mail-ed1-f67.google.com ([209.85.208.67]:44360 "EHLO mail-ed1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727608AbfDOO4R (ORCPT ); Mon, 15 Apr 2019 10:56:17 -0400 Received: by mail-ed1-f67.google.com with SMTP id i13so4273226edf.11 for ; Mon, 15 Apr 2019 07:56:15 -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=mu1XjfLZ6ajnif4dDscKngCOI1kjIJQT1p2qmUNZOSM=; b=pPjZS6yYaPrzFxPuCDXA5wdHzFzegNGx32jyN/PGxpV9vyVmgxnTeMND9wcrW7wod8 1B9DsfjUx/BMXHVeDJDdlCWnKVjvT5V7xXkEkWWjsmyeOycVuExNgiP95LMRtb8RHOe0 ZSGWp4c1HrxsQzzqwGRpYWMJNZ0bvyJCaaLKo3k/w66/4l6cd/cxsAGsVcJGs4/uCjPb 4vNoNB2dYIzsfwz/vGxoLHtEsL7rEzgUsT8ncV2mi3Mk3E9iPf07ITvi50FIq8Qeky/i 4SSzjRhJSW4VaKzJcpE6PBtMcy0Juk+q/vzs8g8apxjoilajyQHzo/9D4va+NoMsgDZ+ kUuA== 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=mu1XjfLZ6ajnif4dDscKngCOI1kjIJQT1p2qmUNZOSM=; b=NRGQeLArQq8BTpMiXIYdYqChsa8cL4S7G+Ww92XfLF6RKc/sQ3/ifbkWUfcz4Ylr7N d1Jrx4AIrS9IyQUmufajSeuSHWzN9asdx7CKQrV6D/Ons16SfPjGfN+Raf2VwlTwGXv1 uli0okg/Y5CliSDYdzf96QUf+fdIxUO8uh2mhxxZeCUO6b2MozuMtgTskuprFU/9Xzn0 +Clib67hsOLchnbrv3FMmtmrqNEPAxsqp/FZ1uCyQKY7/KyFkWs2zv/rXsTKEkH9oX77 Ek2EOgsgWFtbc0OMgOuCu59lscgNGOY6Us+jG2xQCQHqBrf3GkR3s9ZMPn9aJZXArV7E qvgA== X-Gm-Message-State: APjAAAXrriEyDzhra0BbvBTT2dEZ4VIMkMam80zTZKIBzMdkbIAtIycQ wscsCcjNoCwr/nTYPkmjIXGv15ww92aYFhrw X-Google-Smtp-Source: APXvYqyqNb9UoJknf2snlEQnSapn7BpgU6D5ca4e04JjhZuoixAbTnJfvqeO+jobfgNI1wgH7qa/PQ== X-Received: by 2002:a50:ca88:: with SMTP id x8mr22336057edh.139.1555340175165; Mon, 15 Apr 2019 07:56:15 -0700 (PDT) Received: from reginn.horms.nl ([2001:982:756:703:d63d:7eff:fe99:ac9d]) by smtp.gmail.com with ESMTPSA id c38sm2540023ede.61.2019.04.15.07.56.13 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 15 Apr 2019 07:56:14 -0700 (PDT) From: Simon Horman To: David Miller , Jakub Kicinski Cc: netdev@vger.kernel.org, oss-drivers@netronome.com, John Hurley , Simon Horman Subject: [PATCH net-next 01/11] nfp: flower: turn on recirc and merge hint support in firmware Date: Mon, 15 Apr 2019 16:55:53 +0200 Message-Id: <20190415145603.32491-2-simon.horman@netronome.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20190415145603.32491-1-simon.horman@netronome.com> References: <20190415145603.32491-1-simon.horman@netronome.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: John Hurley Write to a FW symbol to indicate that the driver supports flow merging. If this symbol does not exist then flow merging and recirculation is not supported on the FW. If support is available, add a stub to deal with FW to kernel merge hint messages. Full flow merging requires the firmware to support of flow mods. If it does not, then do not attempt to 'turn on' flow merging. Signed-off-by: John Hurley Signed-off-by: Simon Horman --- drivers/net/ethernet/netronome/nfp/flower/cmsg.c | 5 +++++ drivers/net/ethernet/netronome/nfp/flower/cmsg.h | 1 + drivers/net/ethernet/netronome/nfp/flower/main.c | 17 +++++++++++++++++ drivers/net/ethernet/netronome/nfp/flower/main.h | 2 ++ 4 files changed, 25 insertions(+) diff --git a/drivers/net/ethernet/netronome/nfp/flower/cmsg.c b/drivers/net/ethernet/netronome/nfp/flower/cmsg.c index cf9e1118ee8f..e1ffbce3357b 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/cmsg.c +++ b/drivers/net/ethernet/netronome/nfp/flower/cmsg.c @@ -222,6 +222,10 @@ nfp_flower_cmsg_process_one_rx(struct nfp_app *app, struct sk_buff *skb) case NFP_FLOWER_CMSG_TYPE_PORT_MOD: nfp_flower_cmsg_portmod_rx(app, skb); break; + case NFP_FLOWER_CMSG_TYPE_MERGE_HINT: + if (app_priv->flower_ext_feats & NFP_FL_FEATS_FLOW_MERGE) + break; + goto err_default; case NFP_FLOWER_CMSG_TYPE_NO_NEIGH: nfp_tunnel_request_route(app, skb); break; @@ -235,6 +239,7 @@ nfp_flower_cmsg_process_one_rx(struct nfp_app *app, struct sk_buff *skb) } /* fall through */ default: +err_default: nfp_flower_cmsg_warn(app, "Cannot handle invalid repr control type %u\n", type); goto out; diff --git a/drivers/net/ethernet/netronome/nfp/flower/cmsg.h b/drivers/net/ethernet/netronome/nfp/flower/cmsg.h index 0ed51e79db00..cf4ab10a614d 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/cmsg.h +++ b/drivers/net/ethernet/netronome/nfp/flower/cmsg.h @@ -407,6 +407,7 @@ enum nfp_flower_cmsg_type_port { NFP_FLOWER_CMSG_TYPE_PORT_REIFY = 6, NFP_FLOWER_CMSG_TYPE_MAC_REPR = 7, NFP_FLOWER_CMSG_TYPE_PORT_MOD = 8, + NFP_FLOWER_CMSG_TYPE_MERGE_HINT = 9, NFP_FLOWER_CMSG_TYPE_NO_NEIGH = 10, NFP_FLOWER_CMSG_TYPE_TUN_MAC = 11, NFP_FLOWER_CMSG_TYPE_ACTIVE_TUNS = 12, diff --git a/drivers/net/ethernet/netronome/nfp/flower/main.c b/drivers/net/ethernet/netronome/nfp/flower/main.c index 408089133599..1569fb6c2c36 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/main.c +++ b/drivers/net/ethernet/netronome/nfp/flower/main.c @@ -641,11 +641,28 @@ static int nfp_flower_init(struct nfp_app *app) goto err_cleanup_metadata; } + if (app_priv->flower_ext_feats & NFP_FL_FEATS_FLOW_MOD) { + /* Tell the firmware that the driver supports flow merging. */ + err = nfp_rtsym_write_le(app->pf->rtbl, + "_abi_flower_merge_hint_enable", 1); + if (!err) + app_priv->flower_ext_feats |= NFP_FL_FEATS_FLOW_MERGE; + else if (err == -ENOENT) + nfp_warn(app->cpp, "Flow merge not supported by FW.\n"); + else + goto err_lag_clean; + } else { + nfp_warn(app->cpp, "Flow mod/merge not supported by FW.\n"); + } + INIT_LIST_HEAD(&app_priv->indr_block_cb_priv); INIT_LIST_HEAD(&app_priv->non_repr_priv); return 0; +err_lag_clean: + if (app_priv->flower_ext_feats & NFP_FL_FEATS_LAG) + nfp_flower_lag_cleanup(&app_priv->nfp_lag); err_cleanup_metadata: nfp_flower_metadata_cleanup(app); err_free_app_priv: diff --git a/drivers/net/ethernet/netronome/nfp/flower/main.h b/drivers/net/ethernet/netronome/nfp/flower/main.h index f6ca8dc9cc92..f5570080b505 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/main.h +++ b/drivers/net/ethernet/netronome/nfp/flower/main.h @@ -39,6 +39,8 @@ struct nfp_app; #define NFP_FL_NBI_MTU_SETTING BIT(1) #define NFP_FL_FEATS_GENEVE_OPT BIT(2) #define NFP_FL_FEATS_VLAN_PCP BIT(3) +#define NFP_FL_FEATS_FLOW_MOD BIT(5) +#define NFP_FL_FEATS_FLOW_MERGE BIT(30) #define NFP_FL_FEATS_LAG BIT(31) struct nfp_fl_mask_id { From patchwork Mon Apr 15 14:55:54 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Horman X-Patchwork-Id: 1085677 X-Patchwork-Delegate: davem@davemloft.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="ba0xJDtG"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 44jWm82xh3z9s4V for ; Tue, 16 Apr 2019 00:56:24 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727820AbfDOO4X (ORCPT ); Mon, 15 Apr 2019 10:56:23 -0400 Received: from mail-ed1-f68.google.com ([209.85.208.68]:43274 "EHLO mail-ed1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727520AbfDOO4T (ORCPT ); Mon, 15 Apr 2019 10:56:19 -0400 Received: by mail-ed1-f68.google.com with SMTP id j20so4761077edq.10 for ; Mon, 15 Apr 2019 07:56:17 -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=GFkH5cdZ2TEGPVun/vZtVDEU6xW53/IEqBM2blta2Hc=; b=ba0xJDtG75MkS/rENP2Ek3NHwqD2NimmCZI67SLHCINeG8TTIyT0x5cCeh1PeNq+qW ni2zJKPOKTcOdtthkWlbDTMjAuNGLk9n7JxpRCXGPjuu7DBYHiJ8zYKEEUInd2JXnxpj TEX6qqXRO97hzy3lUl8d8VKGS6fbgqkNE3O2H2aIcH1spd55vHvPoPlEfvcZqPoaOwEZ O9D3iOKYRjy9hscPQ4tpRcugXQyjiH51+X6rF2pIW3BmoDdbuYgRoJnhuFKTtYRbKrwC VGRbydmKafqtQmNNRXT5ECA/c6fBli2dkAdloHq5NoZvYY6ZRsRxdIAGaPQmRyBxBdgq ldqA== 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=GFkH5cdZ2TEGPVun/vZtVDEU6xW53/IEqBM2blta2Hc=; b=CAHtrAy8PNV+is4Sd0F7DXr/sGabREd8LOo8CprMBbOh0Vj66BzzoY92ZvsDTW5xp9 gIAAlG1KF3cmiiWHvQiwqAcgDlUlr/RaLiBXRwkTEy8Mc29PLjfZ59aM0q/kz496HPMH 3+tasgKAjQDmeI8nMm2iOQ2KiFCNKFsDpf0PP6v1AgtzqnSrZBnFYh+kbTfneevpSVB4 AUoXYUuqZ/K9MRPYp1fmifYWXOmx52kIyQRqTMvPaaLfxJCImXO3bUkvsDpZ7qQNYwY8 2kyJBy/Ip2/d1A/1OgjvGQ3tLhYNGEZNdUJhFErHKX49PJiryYzNrhi3eFTtC3WD/ZOc 6kuw== X-Gm-Message-State: APjAAAVML7yOQ5kcxdr88+aPDVr53NOctJZviLM58+oItleIJfNTeZMZ 5Y+HwA0BGETJYLfw2FhKfSg+lA== X-Google-Smtp-Source: APXvYqzFOqQBj2x20JQlMkv3sqmjyonyZ/K8MQv629XSRWK80k3MYFWoLXLc6sl0Q0xJRP1qmfDu/g== X-Received: by 2002:a50:c9c4:: with SMTP id c4mr32105528edi.107.1555340176809; Mon, 15 Apr 2019 07:56:16 -0700 (PDT) Received: from reginn.horms.nl ([2001:982:756:703:d63d:7eff:fe99:ac9d]) by smtp.gmail.com with ESMTPSA id c38sm2540023ede.61.2019.04.15.07.56.15 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 15 Apr 2019 07:56:16 -0700 (PDT) From: Simon Horman To: David Miller , Jakub Kicinski Cc: netdev@vger.kernel.org, oss-drivers@netronome.com, John Hurley , Simon Horman Subject: [PATCH net-next 02/11] nfp: flower: allow offloading of matches on 'internal' ports Date: Mon, 15 Apr 2019 16:55:54 +0200 Message-Id: <20190415145603.32491-3-simon.horman@netronome.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20190415145603.32491-1-simon.horman@netronome.com> References: <20190415145603.32491-1-simon.horman@netronome.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: John Hurley Recent FW modifications allow the offloading of non repr ports. These ports exist internally on the NFP. So if a rule outputs to an 'internal' port, then the packet will recirculate back into the system but will now have this internal port as it's incoming port. These ports are indicated by a specific type field combined with an 8 bit port id. Add private app data to assign additional port ids for use in offloads. Provide functions to lookup or create new ids when a rule attempts to match on an internal netdev - the only internal netdevs currently supported are of type openvswitch. Have a netdev notifier to release port ids on netdev unregister. OvS offloads rules that match on internal ports as TC egress filters. Ensure that such rules are accepted by the driver. Signed-off-by: John Hurley Signed-off-by: Simon Horman --- drivers/net/ethernet/netronome/nfp/flower/cmsg.h | 7 ++ drivers/net/ethernet/netronome/nfp/flower/main.c | 112 ++++++++++++++++++++- drivers/net/ethernet/netronome/nfp/flower/main.h | 30 ++++++ drivers/net/ethernet/netronome/nfp/flower/match.c | 9 +- .../net/ethernet/netronome/nfp/flower/offload.c | 4 +- 5 files changed, 153 insertions(+), 9 deletions(-) diff --git a/drivers/net/ethernet/netronome/nfp/flower/cmsg.h b/drivers/net/ethernet/netronome/nfp/flower/cmsg.h index cf4ab10a614d..41a2290eb838 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/cmsg.h +++ b/drivers/net/ethernet/netronome/nfp/flower/cmsg.h @@ -474,6 +474,13 @@ enum nfp_flower_cmsg_port_vnic_type { #define NFP_FLOWER_CMSG_PORT_PCIE_Q GENMASK(5, 0) #define NFP_FLOWER_CMSG_PORT_PHYS_PORT_NUM GENMASK(7, 0) +static inline u32 nfp_flower_internal_port_get_port_id(u8 internal_port) +{ + return FIELD_PREP(NFP_FLOWER_CMSG_PORT_PHYS_PORT_NUM, internal_port) | + FIELD_PREP(NFP_FLOWER_CMSG_PORT_TYPE, + NFP_FLOWER_CMSG_PORT_TYPE_OTHER_PORT); +} + static inline u32 nfp_flower_cmsg_phys_port(u8 phys_port) { return FIELD_PREP(NFP_FLOWER_CMSG_PORT_PHYS_PORT_NUM, phys_port) | diff --git a/drivers/net/ethernet/netronome/nfp/flower/main.c b/drivers/net/ethernet/netronome/nfp/flower/main.c index 1569fb6c2c36..d0d8c56cd84a 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/main.c +++ b/drivers/net/ethernet/netronome/nfp/flower/main.c @@ -22,6 +22,9 @@ #define NFP_FLOWER_ALLOWED_VER 0x0001000000010000UL +#define NFP_MIN_INT_PORT_ID 1 +#define NFP_MAX_INT_PORT_ID 256 + static const char *nfp_flower_extra_cap(struct nfp_app *app, struct nfp_net *nn) { return "FLOWER"; @@ -32,6 +35,100 @@ static enum devlink_eswitch_mode eswitch_mode_get(struct nfp_app *app) return DEVLINK_ESWITCH_MODE_SWITCHDEV; } +static int +nfp_flower_lookup_internal_port_id(struct nfp_flower_priv *priv, + struct net_device *netdev) +{ + struct net_device *entry; + int i, id = 0; + + rcu_read_lock(); + idr_for_each_entry(&priv->internal_ports.port_ids, entry, i) + if (entry == netdev) { + id = i; + break; + } + rcu_read_unlock(); + + return id; +} + +static int +nfp_flower_get_internal_port_id(struct nfp_app *app, struct net_device *netdev) +{ + struct nfp_flower_priv *priv = app->priv; + int id; + + id = nfp_flower_lookup_internal_port_id(priv, netdev); + if (id > 0) + return id; + + idr_preload(GFP_ATOMIC); + spin_lock_bh(&priv->internal_ports.lock); + id = idr_alloc(&priv->internal_ports.port_ids, netdev, + NFP_MIN_INT_PORT_ID, NFP_MAX_INT_PORT_ID, GFP_ATOMIC); + spin_unlock_bh(&priv->internal_ports.lock); + idr_preload_end(); + + return id; +} + +u32 nfp_flower_get_port_id_from_netdev(struct nfp_app *app, + struct net_device *netdev) +{ + int ext_port; + + if (nfp_netdev_is_nfp_repr(netdev)) { + return nfp_repr_get_port_id(netdev); + } else if (nfp_flower_internal_port_can_offload(app, netdev)) { + ext_port = nfp_flower_get_internal_port_id(app, netdev); + if (ext_port < 0) + return 0; + + return nfp_flower_internal_port_get_port_id(ext_port); + } + + return 0; +} + +static void +nfp_flower_free_internal_port_id(struct nfp_app *app, struct net_device *netdev) +{ + struct nfp_flower_priv *priv = app->priv; + int id; + + id = nfp_flower_lookup_internal_port_id(priv, netdev); + if (!id) + return; + + spin_lock_bh(&priv->internal_ports.lock); + idr_remove(&priv->internal_ports.port_ids, id); + spin_unlock_bh(&priv->internal_ports.lock); +} + +static int +nfp_flower_internal_port_event_handler(struct nfp_app *app, + struct net_device *netdev, + unsigned long event) +{ + if (event == NETDEV_UNREGISTER && + nfp_flower_internal_port_can_offload(app, netdev)) + nfp_flower_free_internal_port_id(app, netdev); + + return NOTIFY_OK; +} + +static void nfp_flower_internal_port_init(struct nfp_flower_priv *priv) +{ + spin_lock_init(&priv->internal_ports.lock); + idr_init(&priv->internal_ports.port_ids); +} + +static void nfp_flower_internal_port_cleanup(struct nfp_flower_priv *priv) +{ + idr_destroy(&priv->internal_ports.port_ids); +} + static struct nfp_flower_non_repr_priv * nfp_flower_non_repr_priv_lookup(struct nfp_app *app, struct net_device *netdev) { @@ -645,12 +742,14 @@ static int nfp_flower_init(struct nfp_app *app) /* Tell the firmware that the driver supports flow merging. */ err = nfp_rtsym_write_le(app->pf->rtbl, "_abi_flower_merge_hint_enable", 1); - if (!err) + if (!err) { app_priv->flower_ext_feats |= NFP_FL_FEATS_FLOW_MERGE; - else if (err == -ENOENT) + nfp_flower_internal_port_init(app_priv); + } else if (err == -ENOENT) { nfp_warn(app->cpp, "Flow merge not supported by FW.\n"); - else + } else { goto err_lag_clean; + } } else { nfp_warn(app->cpp, "Flow mod/merge not supported by FW.\n"); } @@ -681,6 +780,9 @@ static void nfp_flower_clean(struct nfp_app *app) if (app_priv->flower_ext_feats & NFP_FL_FEATS_LAG) nfp_flower_lag_cleanup(&app_priv->nfp_lag); + if (app_priv->flower_ext_feats & NFP_FL_FEATS_FLOW_MERGE) + nfp_flower_internal_port_cleanup(app_priv); + nfp_flower_metadata_cleanup(app); vfree(app->priv); app->priv = NULL; @@ -779,6 +881,10 @@ nfp_flower_netdev_event(struct nfp_app *app, struct net_device *netdev, if (ret & NOTIFY_STOP_MASK) return ret; + ret = nfp_flower_internal_port_event_handler(app, netdev, event); + if (ret & NOTIFY_STOP_MASK) + return ret; + return nfp_tunnel_mac_event_handler(app, netdev, event, ptr); } diff --git a/drivers/net/ethernet/netronome/nfp/flower/main.h b/drivers/net/ethernet/netronome/nfp/flower/main.h index f5570080b505..485bdc0e1c20 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/main.h +++ b/drivers/net/ethernet/netronome/nfp/flower/main.h @@ -117,6 +117,16 @@ struct nfp_fl_lag { }; /** + * struct nfp_fl_internal_ports - Flower APP priv data for additional ports + * @port_ids: Assignment of ids to any additional ports + * @lock: Lock for extra ports list + */ +struct nfp_fl_internal_ports { + struct idr port_ids; + spinlock_t lock; +}; + +/** * struct nfp_flower_priv - Flower APP per-vNIC priv data * @app: Back pointer to app * @nn: Pointer to vNIC @@ -145,6 +155,7 @@ struct nfp_fl_lag { * @non_repr_priv: List of offloaded non-repr ports and their priv data * @active_mem_unit: Current active memory unit for flower rules * @total_mem_units: Total number of available memory units for flower rules + * @internal_ports: Internal port ids used in offloaded rules */ struct nfp_flower_priv { struct nfp_app *app; @@ -171,6 +182,7 @@ struct nfp_flower_priv { struct list_head non_repr_priv; unsigned int active_mem_unit; unsigned int total_mem_units; + struct nfp_fl_internal_ports internal_ports; }; /** @@ -249,6 +261,22 @@ struct nfp_fl_stats_frame { __be64 stats_cookie; }; +static inline bool +nfp_flower_internal_port_can_offload(struct nfp_app *app, + struct net_device *netdev) +{ + struct nfp_flower_priv *app_priv = app->priv; + + if (!(app_priv->flower_ext_feats & NFP_FL_FEATS_FLOW_MERGE)) + return false; + if (!netdev->rtnl_link_ops) + return false; + if (!strcmp(netdev->rtnl_link_ops->kind, "openvswitch")) + return true; + + return false; +} + int nfp_flower_metadata_init(struct nfp_app *app, u64 host_ctx_count, unsigned int host_ctx_split); void nfp_flower_metadata_cleanup(struct nfp_app *app); @@ -313,4 +341,6 @@ void __nfp_flower_non_repr_priv_put(struct nfp_flower_non_repr_priv *non_repr_priv); void nfp_flower_non_repr_priv_put(struct nfp_app *app, struct net_device *netdev); +u32 nfp_flower_get_port_id_from_netdev(struct nfp_app *app, + struct net_device *netdev); #endif diff --git a/drivers/net/ethernet/netronome/nfp/flower/match.c b/drivers/net/ethernet/netronome/nfp/flower/match.c index 9b8b843d0340..bfa4bf34911d 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/match.c +++ b/drivers/net/ethernet/netronome/nfp/flower/match.c @@ -326,13 +326,12 @@ int nfp_flower_compile_flow_match(struct nfp_app *app, struct nfp_fl_payload *nfp_flow, enum nfp_flower_tun_type tun_type) { - u32 cmsg_port = 0; + u32 port_id; int err; u8 *ext; u8 *msk; - if (nfp_netdev_is_nfp_repr(netdev)) - cmsg_port = nfp_repr_get_port_id(netdev); + port_id = nfp_flower_get_port_id_from_netdev(app, netdev); memset(nfp_flow->unmasked_data, 0, key_ls->key_size); memset(nfp_flow->mask_data, 0, key_ls->key_size); @@ -358,13 +357,13 @@ int nfp_flower_compile_flow_match(struct nfp_app *app, /* Populate Exact Port data. */ err = nfp_flower_compile_port((struct nfp_flower_in_port *)ext, - cmsg_port, false, tun_type); + port_id, false, tun_type); if (err) return err; /* Populate Mask Port Data. */ err = nfp_flower_compile_port((struct nfp_flower_in_port *)msk, - cmsg_port, true, tun_type); + port_id, true, tun_type); if (err) return err; diff --git a/drivers/net/ethernet/netronome/nfp/flower/offload.c b/drivers/net/ethernet/netronome/nfp/flower/offload.c index 9f16920da81d..af406e6cff98 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/offload.c +++ b/drivers/net/ethernet/netronome/nfp/flower/offload.c @@ -682,7 +682,9 @@ nfp_flower_setup_indr_tc_block(struct net_device *netdev, struct nfp_app *app, struct nfp_flower_priv *priv = app->priv; int err; - if (f->binder_type != TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS) + if (f->binder_type != TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS && + !(f->binder_type == TCF_BLOCK_BINDER_TYPE_CLSACT_EGRESS && + nfp_flower_internal_port_can_offload(app, netdev))) return -EOPNOTSUPP; switch (f->command) { From patchwork Mon Apr 15 14:55:55 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Horman X-Patchwork-Id: 1085679 X-Patchwork-Delegate: davem@davemloft.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="hXKYallj"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 44jWmF0LC8z9s5c for ; Tue, 16 Apr 2019 00:56:29 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727566AbfDOO4Z (ORCPT ); Mon, 15 Apr 2019 10:56:25 -0400 Received: from mail-ed1-f68.google.com ([209.85.208.68]:34744 "EHLO mail-ed1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727809AbfDOO4U (ORCPT ); Mon, 15 Apr 2019 10:56:20 -0400 Received: by mail-ed1-f68.google.com with SMTP id a6so3727358edv.1 for ; Mon, 15 Apr 2019 07:56:19 -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=pa7UZOZEf0TiCcoLusw0mkdQxXjzsSWd4zChxQX8wq8=; b=hXKYalljeedVFG3lU8RBMjv4bHaBIk6N40HzYuQL3MiQ0tjDJRVQFdG3rwSxG8i6Yh u2z0hTDsV0WYOLccJ7Mo3bgOlhZsr+k6ZWYkkQXvbtlDYF3AnGdZn0m4Wmkr8E2E+okj YHbwyBtTO8z7XgIA+jxI4Ig90VvO/e8X+TvnNYvlwMW14TQKB+VLjUWL9sPoSPn+oKPT zYgutjZQ5mGepoFO6ZxdBm9zbJOTnezFkjEcoSr2SoIKK4ZCudP1pGZkNDz7CREonjzU XB/nBSnsZLUY657ZBaIfG3GCCDFWcd6yS/L4dYh6eoJ2JxwiE7HfQQK2X1jBNeg8mZSU FdIw== 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=pa7UZOZEf0TiCcoLusw0mkdQxXjzsSWd4zChxQX8wq8=; b=hJ/f+whRxU0TAzbDEmJrfxN9jVS5yzf/76Z1vK3UokPHWzo6UwUsvvtGIN0B+UEEJG 9NVavRaMFDt4tCJFDN+xlEhPNIEVqpNmKBKrXCo5QM9QiGuwkUNqVINFhUqjshzACmHk f1zmMNJDcQgSgZxkW/41oaq6qazZclFoMdQP9CLugcxqdHPzK3eDN+wqlmSMGw7rmaji c+2+PT8yZPQ0OVFsTVct1ph3tAa75wfOr/yZ2Gt+nYTKQTUMj4alBV19ltkFQVGB6H4r UjwTj33iM5E06rlUnVJTHKQcmz4U+KM664XFLBn9jh720yFYdeX6GQib/oH1Ekii5A6w ITzg== X-Gm-Message-State: APjAAAUBEAsvVJlCgwWsWdAK3pcn1KDCOPGf4nAfPO3M05B3n/dwpOCr bK9x1A0/KYiAQuKkR94shwqDzg== X-Google-Smtp-Source: APXvYqz3aA+8vDO+lJzsOH6YX5wRSIh4BOfsQycYpKPOAhj7b7+3NYbkcOar5DyP+DLs7+rY+tTdDw== X-Received: by 2002:a50:a5a5:: with SMTP id a34mr11203199edc.136.1555340178445; Mon, 15 Apr 2019 07:56:18 -0700 (PDT) Received: from reginn.horms.nl ([2001:982:756:703:d63d:7eff:fe99:ac9d]) by smtp.gmail.com with ESMTPSA id c38sm2540023ede.61.2019.04.15.07.56.16 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 15 Apr 2019 07:56:17 -0700 (PDT) From: Simon Horman To: David Miller , Jakub Kicinski Cc: netdev@vger.kernel.org, oss-drivers@netronome.com, John Hurley , Simon Horman Subject: [PATCH net-next 03/11] nfp: allow fallback packets from non-reprs Date: Mon, 15 Apr 2019 16:55:55 +0200 Message-Id: <20190415145603.32491-4-simon.horman@netronome.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20190415145603.32491-1-simon.horman@netronome.com> References: <20190415145603.32491-1-simon.horman@netronome.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: John Hurley Currently, it is assumed that fallback packets will be from reprs. Modify this to allow an app to receive non-repr ports from the fallback channel - e.g. from an internal port. If such a packet is received, do not update repr stats. Change the naming function calls so as not to imply it will always be a repr netdev returned. Add the option to set a bool value to redirect a fallback packet out the returned port rather than RXing it. Setting of this bool in subsequent patches allows the handling of packets falling back when they are due to egress an internal port. Signed-off-by: John Hurley Acked-by: Jakub Kicinski Signed-off-by: Simon Horman --- drivers/net/ethernet/netronome/nfp/abm/main.c | 5 +++-- drivers/net/ethernet/netronome/nfp/flower/cmsg.c | 4 ++-- drivers/net/ethernet/netronome/nfp/flower/main.c | 4 ++-- drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c | 4 ++-- drivers/net/ethernet/netronome/nfp/nfp_app.h | 13 ++++++++----- drivers/net/ethernet/netronome/nfp/nfp_net_common.c | 16 +++++++++++++--- 6 files changed, 30 insertions(+), 16 deletions(-) diff --git a/drivers/net/ethernet/netronome/nfp/abm/main.c b/drivers/net/ethernet/netronome/nfp/abm/main.c index 4d4ff5844c47..9183b3e85d21 100644 --- a/drivers/net/ethernet/netronome/nfp/abm/main.c +++ b/drivers/net/ethernet/netronome/nfp/abm/main.c @@ -53,7 +53,8 @@ nfp_abm_setup_tc(struct nfp_app *app, struct net_device *netdev, } } -static struct net_device *nfp_abm_repr_get(struct nfp_app *app, u32 port_id) +static struct net_device * +nfp_abm_repr_get(struct nfp_app *app, u32 port_id, bool *redir_egress) { enum nfp_repr_type rtype; struct nfp_reprs *reprs; @@ -549,5 +550,5 @@ const struct nfp_app_type app_abm = { .eswitch_mode_get = nfp_abm_eswitch_mode_get, .eswitch_mode_set = nfp_abm_eswitch_mode_set, - .repr_get = nfp_abm_repr_get, + .dev_get = nfp_abm_repr_get, }; diff --git a/drivers/net/ethernet/netronome/nfp/flower/cmsg.c b/drivers/net/ethernet/netronome/nfp/flower/cmsg.c index e1ffbce3357b..d67f7e10be69 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/cmsg.c +++ b/drivers/net/ethernet/netronome/nfp/flower/cmsg.c @@ -159,7 +159,7 @@ nfp_flower_cmsg_portmod_rx(struct nfp_app *app, struct sk_buff *skb) rtnl_lock(); rcu_read_lock(); - netdev = nfp_app_repr_get(app, be32_to_cpu(msg->portnum)); + netdev = nfp_app_dev_get(app, be32_to_cpu(msg->portnum), NULL); rcu_read_unlock(); if (!netdev) { nfp_flower_cmsg_warn(app, "ctrl msg for unknown port 0x%08x\n", @@ -192,7 +192,7 @@ nfp_flower_cmsg_portreify_rx(struct nfp_app *app, struct sk_buff *skb) msg = nfp_flower_cmsg_get_data(skb); rcu_read_lock(); - exists = !!nfp_app_repr_get(app, be32_to_cpu(msg->portnum)); + exists = !!nfp_app_dev_get(app, be32_to_cpu(msg->portnum), NULL); rcu_read_unlock(); if (!exists) { nfp_flower_cmsg_warn(app, "ctrl msg for unknown port 0x%08x\n", diff --git a/drivers/net/ethernet/netronome/nfp/flower/main.c b/drivers/net/ethernet/netronome/nfp/flower/main.c index d0d8c56cd84a..863607d84f21 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/main.c +++ b/drivers/net/ethernet/netronome/nfp/flower/main.c @@ -216,7 +216,7 @@ nfp_flower_repr_get_type_and_port(struct nfp_app *app, u32 port_id, u8 *port) } static struct net_device * -nfp_flower_repr_get(struct nfp_app *app, u32 port_id) +nfp_flower_repr_get(struct nfp_app *app, u32 port_id, bool *redir_egress) { enum nfp_repr_type repr_type; struct nfp_reprs *reprs; @@ -923,7 +923,7 @@ const struct nfp_app_type app_flower = { .sriov_disable = nfp_flower_sriov_disable, .eswitch_mode_get = eswitch_mode_get, - .repr_get = nfp_flower_repr_get, + .dev_get = nfp_flower_repr_get, .setup_tc = nfp_flower_setup_tc, }; diff --git a/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c b/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c index 4d78be4ec4e9..ad7637eebf89 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c +++ b/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c @@ -171,7 +171,7 @@ void nfp_tunnel_keep_alive(struct nfp_app *app, struct sk_buff *skb) for (i = 0; i < count; i++) { ipv4_addr = payload->tun_info[i].ipv4; port = be32_to_cpu(payload->tun_info[i].egress_port); - netdev = nfp_app_repr_get(app, port); + netdev = nfp_app_dev_get(app, port, NULL); if (!netdev) continue; @@ -366,7 +366,7 @@ void nfp_tunnel_request_route(struct nfp_app *app, struct sk_buff *skb) payload = nfp_flower_cmsg_get_data(skb); - netdev = nfp_app_repr_get(app, be32_to_cpu(payload->ingress_port)); + netdev = nfp_app_dev_get(app, be32_to_cpu(payload->ingress_port), NULL); if (!netdev) goto route_fail_warning; diff --git a/drivers/net/ethernet/netronome/nfp/nfp_app.h b/drivers/net/ethernet/netronome/nfp/nfp_app.h index a6fda07fce43..76d13af46a7a 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_app.h +++ b/drivers/net/ethernet/netronome/nfp/nfp_app.h @@ -79,7 +79,7 @@ extern const struct nfp_app_type app_abm; * @eswitch_mode_set: set SR-IOV eswitch mode (under pf->lock) * @sriov_enable: app-specific sriov initialisation * @sriov_disable: app-specific sriov clean-up - * @repr_get: get representor netdev + * @dev_get: get representor or internal port representing netdev */ struct nfp_app_type { enum nfp_app_id id; @@ -143,7 +143,8 @@ struct nfp_app_type { enum devlink_eswitch_mode (*eswitch_mode_get)(struct nfp_app *app); int (*eswitch_mode_set)(struct nfp_app *app, u16 mode); - struct net_device *(*repr_get)(struct nfp_app *app, u32 id); + struct net_device *(*dev_get)(struct nfp_app *app, u32 id, + bool *redir_egress); }; /** @@ -397,12 +398,14 @@ static inline void nfp_app_sriov_disable(struct nfp_app *app) app->type->sriov_disable(app); } -static inline struct net_device *nfp_app_repr_get(struct nfp_app *app, u32 id) +static inline +struct net_device *nfp_app_dev_get(struct nfp_app *app, u32 id, + bool *redir_egress) { - if (unlikely(!app || !app->type->repr_get)) + if (unlikely(!app || !app->type->dev_get)) return NULL; - return app->type->repr_get(app, id); + return app->type->dev_get(app, id, redir_egress); } struct nfp_app *nfp_app_from_netdev(struct net_device *netdev); diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c index e4be04cdef30..58657fe504d7 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c +++ b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c @@ -1683,6 +1683,7 @@ static int nfp_net_rx(struct nfp_net_rx_ring *rx_ring, int budget) struct nfp_net_rx_buf *rxbuf; struct nfp_net_rx_desc *rxd; struct nfp_meta_parsed meta; + bool redir_egress = false; struct net_device *netdev; dma_addr_t new_dma_addr; u32 meta_len_xdp = 0; @@ -1818,13 +1819,16 @@ static int nfp_net_rx(struct nfp_net_rx_ring *rx_ring, int budget) struct nfp_net *nn; nn = netdev_priv(dp->netdev); - netdev = nfp_app_repr_get(nn->app, meta.portid); + netdev = nfp_app_dev_get(nn->app, meta.portid, + &redir_egress); if (unlikely(!netdev)) { nfp_net_rx_drop(dp, r_vec, rx_ring, rxbuf, NULL); continue; } - nfp_repr_inc_rx_stats(netdev, pkt_len); + + if (nfp_netdev_is_nfp_repr(netdev)) + nfp_repr_inc_rx_stats(netdev, pkt_len); } skb = build_skb(rxbuf->frag, true_bufsz); @@ -1859,7 +1863,13 @@ static int nfp_net_rx(struct nfp_net_rx_ring *rx_ring, int budget) if (meta_len_xdp) skb_metadata_set(skb, meta_len_xdp); - napi_gro_receive(&rx_ring->r_vec->napi, skb); + if (likely(!redir_egress)) { + napi_gro_receive(&rx_ring->r_vec->napi, skb); + } else { + skb->dev = netdev; + __skb_push(skb, ETH_HLEN); + dev_queue_xmit(skb); + } } if (xdp_prog) { From patchwork Mon Apr 15 14:55:56 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Horman X-Patchwork-Id: 1085678 X-Patchwork-Delegate: davem@davemloft.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="m/b1CjPR"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 44jWm9260Sz9s5c for ; Tue, 16 Apr 2019 00:56:25 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727830AbfDOO4Y (ORCPT ); Mon, 15 Apr 2019 10:56:24 -0400 Received: from mail-ed1-f68.google.com ([209.85.208.68]:38313 "EHLO mail-ed1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727810AbfDOO4W (ORCPT ); Mon, 15 Apr 2019 10:56:22 -0400 Received: by mail-ed1-f68.google.com with SMTP id d13so14978146edr.5 for ; Mon, 15 Apr 2019 07:56:20 -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=ZSwYaJzpzehXi4bv+nR7rwKAR+b1gbDdY66lwa49YMs=; b=m/b1CjPR2IuwgCtgBEVK7LCrCYwtitl0qkWiI7tfTkWHPbcFyOoZGOHm9HV/uKru7T z3UzQ1/Gnlz54KC3YP/Rcpmo2Ian1lHdsuAyNYxSkt9Ke3tY3Cli89GzC3JBD0cXOy5L 5M98RnYj2z233vWCkidIBRbtgaaz7vH9LFcmSiNNXi2+YPF9mkxMizQdXNsRBSHehFwp 72ONlX9ztFUi+9VcKD+KL3JkuM3KODpOWrYj2Q/kPFPywkFA/bqTsJrV53w+FywQAqLS ISRyam179bmij670rNVI43jyUDG3uQcYMQg0CLrzZ8ze8U0rV6ymbrt1VmtDmGFbVq/K 2Fzw== 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=ZSwYaJzpzehXi4bv+nR7rwKAR+b1gbDdY66lwa49YMs=; b=hcQKMsj+HjDY+v+yUC60E0J7uzbBdS1XcdFMyBu6X0Dk/EH5LQRITX4kFJR+9ugvA7 kMyRiB9DR9VgE1lf/3nWNNFsWD0WKjASFAekZO2kpsgLRMUZB4qm3v93Y/PjkZHb1+Mw d+OGkVGsxNtcd0OzIDYByrm6JnsVNgcObchktmIqUqufLR/NK+rznCNEgYX/WnsA2uNl xSFJ1CuK4FQHBfASgkbEkVsqdGFULVDItrv6u2jEI82JcvUCYpVb3CeBgLRwbGlDGmGC VDsucYJbjlUCZhSsxKkfGZbEB8DvP50z7iHRdVz4f5y79L4b/75YAgQyyAn1pQfSWRw0 jW3g== X-Gm-Message-State: APjAAAWMucQyC2gFgz7Nflks7KPL+l2DnRBVXr7Bc2On6/JIdBrkKB61 6g76XiIfDrowzptnq3pg/+qk9A== X-Google-Smtp-Source: APXvYqzXq3sjm9lbro59Qq+b4CfsmcK1Rwd8ar0yVy53zQ4iNDlsNtYCeu5PLm2vD4GqDP1eAXmEfw== X-Received: by 2002:a17:906:8381:: with SMTP id p1mr40552259ejx.169.1555340180105; Mon, 15 Apr 2019 07:56:20 -0700 (PDT) Received: from reginn.horms.nl ([2001:982:756:703:d63d:7eff:fe99:ac9d]) by smtp.gmail.com with ESMTPSA id c38sm2540023ede.61.2019.04.15.07.56.18 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 15 Apr 2019 07:56:19 -0700 (PDT) From: Simon Horman To: David Miller , Jakub Kicinski Cc: netdev@vger.kernel.org, oss-drivers@netronome.com, John Hurley , Simon Horman Subject: [PATCH net-next 04/11] nfp: flower: support fallback packets from internal ports Date: Mon, 15 Apr 2019 16:55:56 +0200 Message-Id: <20190415145603.32491-5-simon.horman@netronome.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20190415145603.32491-1-simon.horman@netronome.com> References: <20190415145603.32491-1-simon.horman@netronome.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: John Hurley FW may receive a packet with its ingress port marked as an internal port. If a rule does not exist to match on this port, the packet will be sent to the NFP driver. Modify the flower app to detect packets from such internal ports and convert the ingress port to the correct kernel space netdev. At this point, it is assumed that fallback packets from internal ports are to be sent out said port. Therefore, set the redir_egress bool to true on detection of these ports. Signed-off-by: John Hurley Signed-off-by: Simon Horman --- drivers/net/ethernet/netronome/nfp/flower/main.c | 26 ++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/netronome/nfp/flower/main.c b/drivers/net/ethernet/netronome/nfp/flower/main.c index 863607d84f21..d476917c8f7d 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/main.c +++ b/drivers/net/ethernet/netronome/nfp/flower/main.c @@ -91,6 +91,19 @@ u32 nfp_flower_get_port_id_from_netdev(struct nfp_app *app, return 0; } +static struct net_device * +nfp_flower_get_netdev_from_internal_port_id(struct nfp_app *app, int port_id) +{ + struct nfp_flower_priv *priv = app->priv; + struct net_device *netdev; + + rcu_read_lock(); + netdev = idr_find(&priv->internal_ports.port_ids, port_id); + rcu_read_unlock(); + + return netdev; +} + static void nfp_flower_free_internal_port_id(struct nfp_app *app, struct net_device *netdev) { @@ -216,12 +229,21 @@ nfp_flower_repr_get_type_and_port(struct nfp_app *app, u32 port_id, u8 *port) } static struct net_device * -nfp_flower_repr_get(struct nfp_app *app, u32 port_id, bool *redir_egress) +nfp_flower_dev_get(struct nfp_app *app, u32 port_id, bool *redir_egress) { enum nfp_repr_type repr_type; struct nfp_reprs *reprs; u8 port = 0; + /* Check if the port is internal. */ + if (FIELD_GET(NFP_FLOWER_CMSG_PORT_TYPE, port_id) == + NFP_FLOWER_CMSG_PORT_TYPE_OTHER_PORT) { + if (redir_egress) + *redir_egress = true; + port = FIELD_GET(NFP_FLOWER_CMSG_PORT_PHYS_PORT_NUM, port_id); + return nfp_flower_get_netdev_from_internal_port_id(app, port); + } + repr_type = nfp_flower_repr_get_type_and_port(app, port_id, &port); if (repr_type > NFP_REPR_TYPE_MAX) return NULL; @@ -923,7 +945,7 @@ const struct nfp_app_type app_flower = { .sriov_disable = nfp_flower_sriov_disable, .eswitch_mode_get = eswitch_mode_get, - .dev_get = nfp_flower_repr_get, + .dev_get = nfp_flower_dev_get, .setup_tc = nfp_flower_setup_tc, }; From patchwork Mon Apr 15 14:55:57 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Horman X-Patchwork-Id: 1085686 X-Patchwork-Delegate: davem@davemloft.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="Cvri/kGv"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 44jWmc6HhZz9s55 for ; Tue, 16 Apr 2019 00:56:48 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727872AbfDOO4r (ORCPT ); Mon, 15 Apr 2019 10:56:47 -0400 Received: from mail-ed1-f67.google.com ([209.85.208.67]:43003 "EHLO mail-ed1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727811AbfDOO4X (ORCPT ); Mon, 15 Apr 2019 10:56:23 -0400 Received: by mail-ed1-f67.google.com with SMTP id x61so14949301edc.9 for ; Mon, 15 Apr 2019 07:56:22 -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=EfnnVQD0GmCis36E7CQcIPQrpLFOmMrXysmjDkR4wuM=; b=Cvri/kGvakVuWXrEHKySqI//8Thbl6ABrmTX9V+j/WDI5QDfzCl485/K4IumjvRxIe 2qH249/4261shnSd2qY+WioEIrGnkgU/AaRhmIR+oK1ES0zwpdFGq/sf1stnCTaJbS2V GzXjbu/GoUa8JzEpmbzyQxZOPyjGVtbfcrGkHFcbp6jEHWJ+3Rn0+PXXhS8p/0Ngf4gt axSM724msnX+KpOg2uHruEFAuX6BwHPWOX6U9qP5Ym9OiDysQ6KALawQGir8FSFedI25 pU1FKLVQ5bMktXiqDFPzDey4q4DTs7oz1gDksFMo/J2dInYLZbYBTi19iZt6d2NjjW7g O0Ew== 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=EfnnVQD0GmCis36E7CQcIPQrpLFOmMrXysmjDkR4wuM=; b=frqvumQ0tZruikYqDgp/C6YNWBJ97hVw4w3plLvSUHwmJRMiEr3Kj/5Ch4btmKHcHN Jrl5DeU6UBngacuwyAKULF3r/gzbRAds6Da12UNPo7Kx2dcwAlLAk2bVutG32m0iI6j3 lKkudwz2lnNqtOeBfbbkqBVWyDp9ZobK6ZNWvCd9X587ZavNvhGnVqD7PfWi0NeN2LIj LDCuyP/3O5DmAHrbYq5wU57HSXQ3LvUp0LqOF16SqVKu63mxYXkjOfwMoNNDjp4HCeCF MGmZQMifAov+vEcpU7UwmIKY05XVJGF8O6mr7W5m1hyCZaN+ltePeWtntmv6bIPpfQay 6uXQ== X-Gm-Message-State: APjAAAWacKFYoq53fohKv1afae9OnmAWXtc36H/rFk4dcLnYFyvyDsVU HUaZwSbIE65FMYmY4khU3462pw== X-Google-Smtp-Source: APXvYqzWZIIkqU0gYam1ELe2vQ4iRe5GCWnRNp3JLIMNIu2h0x6NBMexXU5SOgOBm7cMS64VBC14bw== X-Received: by 2002:a17:906:883:: with SMTP id n3mr39916520eje.164.1555340181732; Mon, 15 Apr 2019 07:56:21 -0700 (PDT) Received: from reginn.horms.nl ([2001:982:756:703:d63d:7eff:fe99:ac9d]) by smtp.gmail.com with ESMTPSA id c38sm2540023ede.61.2019.04.15.07.56.20 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 15 Apr 2019 07:56:21 -0700 (PDT) From: Simon Horman To: David Miller , Jakub Kicinski Cc: netdev@vger.kernel.org, oss-drivers@netronome.com, John Hurley , Simon Horman Subject: [PATCH net-next 05/11] nfp: flower: allow tunnels to output to internal port Date: Mon, 15 Apr 2019 16:55:57 +0200 Message-Id: <20190415145603.32491-6-simon.horman@netronome.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20190415145603.32491-1-simon.horman@netronome.com> References: <20190415145603.32491-1-simon.horman@netronome.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: John Hurley The neighbour table in the FW only accepts next hop entries if the egress port is an nfp repr. Modify this to allow the next hop to be an internal port. This means that if a packet is to egress to that port, it will recirculate back into the system with the internal port becoming its ingress port. Signed-off-by: John Hurley Signed-off-by: Simon Horman --- drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c b/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c index ad7637eebf89..faa06edf95ac 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c +++ b/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c @@ -270,9 +270,10 @@ nfp_tun_write_neigh(struct net_device *netdev, struct nfp_app *app, struct flowi4 *flow, struct neighbour *neigh, gfp_t flag) { struct nfp_tun_neigh payload; + u32 port_id; - /* Only offload representor IPv4s for now. */ - if (!nfp_netdev_is_nfp_repr(netdev)) + port_id = nfp_flower_get_port_id_from_netdev(app, netdev); + if (!port_id) return; memset(&payload, 0, sizeof(struct nfp_tun_neigh)); @@ -290,7 +291,7 @@ nfp_tun_write_neigh(struct net_device *netdev, struct nfp_app *app, payload.src_ipv4 = flow->saddr; ether_addr_copy(payload.src_addr, netdev->dev_addr); neigh_ha_snapshot(payload.dst_addr, neigh, netdev); - payload.port_id = cpu_to_be32(nfp_repr_get_port_id(netdev)); + payload.port_id = cpu_to_be32(port_id); /* Add destination of new route to NFP cache. */ nfp_tun_add_route_to_cache(app, payload.dst_ipv4); From patchwork Mon Apr 15 14:55:58 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Horman X-Patchwork-Id: 1085685 X-Patchwork-Delegate: davem@davemloft.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="ev0UMnR4"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 44jWmV3PHJz9s5c for ; Tue, 16 Apr 2019 00:56:42 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727846AbfDOO41 (ORCPT ); Mon, 15 Apr 2019 10:56:27 -0400 Received: from mail-ed1-f68.google.com ([209.85.208.68]:34844 "EHLO mail-ed1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727829AbfDOO4Z (ORCPT ); Mon, 15 Apr 2019 10:56:25 -0400 Received: by mail-ed1-f68.google.com with SMTP id y67so1698999ede.2 for ; Mon, 15 Apr 2019 07:56:24 -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=NNjtMEeCjN6bcKC4UnYxNo/IVHNyHtc5MVVbyFG1dD8=; b=ev0UMnR4wsjiq9D40W2851C+6QuQJbGmg91p7b1zPO/fL4eZD7BV/rLkyFWE9jvyFg EFNt9t5j5x7rfkXr6H5jX4WRwEegz8ZwJ9KknpsXh/nmZwhzz2P18Hg9wmByMEDWmoFw dgrbFrR7PgTi9OFckSeYmHQQNYpWj+lK3pihCkogafvyFpYlbK+DOzlQ1qWF9XWXke5z iFch3kdRpW8HPFtCFmAz+o666gKJj5cfFbBoaq6lHDRg2Mv5u4zl+65Oyuq4AJ8YbOjW Sf7Je1jj+onpHfVsMOzE87EUgxc3y0kayhY6/EBanDacfyPCNHj2Gp7x723JE2hJtUh2 cYrg== 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=NNjtMEeCjN6bcKC4UnYxNo/IVHNyHtc5MVVbyFG1dD8=; b=GWRCzzT3OHCLlhaiLV8M5SRtZikXyKBsGUcCMhJ9Hy1lG893jTvAc/w4SswIqoULjW WQuAp9m88SCsyMPdHXs2inTsAgSNM5A1kcaodL4NiCsNHoM/rFnFfRVScJhDTG2qT1CZ pd12lQlAbhnt+09nqQhhs8m86vPfL5u9X3iGg5sYlHAQV8U40x1cA24bJ/dAxCX+/TZt hJWybEBQaYr7XueGe5UUvyv3W3HlB1meJD9YtA/2msRAS+GTh/Gp6ir7jv01Vc6UO2BK hUOUvbAWfzY8zlv5IIMT/3IknFlLwty3bVfIObcArQ6Fw+4zEWEQuhxCrWIhNcT1EXkU NVpA== X-Gm-Message-State: APjAAAV39WfFbYZewqdb1Fb46yNMWiMYe6cbxV8McBGVMGruWG77QdaS rHgy6N5MlsDRDEWGpBPfEuYyng== X-Google-Smtp-Source: APXvYqw238R+i/Y1nnluTSfFVeZcBD0KceWx/b1Rb2mqqFgNySJAFQglO1539eQeMr8aealHf3SPCg== X-Received: by 2002:a17:906:4e4d:: with SMTP id g13mr40517948ejw.11.1555340183518; Mon, 15 Apr 2019 07:56:23 -0700 (PDT) Received: from reginn.horms.nl ([2001:982:756:703:d63d:7eff:fe99:ac9d]) by smtp.gmail.com with ESMTPSA id c38sm2540023ede.61.2019.04.15.07.56.21 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 15 Apr 2019 07:56:22 -0700 (PDT) From: Simon Horman To: David Miller , Jakub Kicinski Cc: netdev@vger.kernel.org, oss-drivers@netronome.com, John Hurley , Simon Horman Subject: [PATCH net-next 06/11] nfp: flower: get flows by host context Date: Mon, 15 Apr 2019 16:55:58 +0200 Message-Id: <20190415145603.32491-7-simon.horman@netronome.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20190415145603.32491-1-simon.horman@netronome.com> References: <20190415145603.32491-1-simon.horman@netronome.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: John Hurley Each flow is given a context ID that the fw uses (along with its cookie) to identity the flow. The flows stats are updated by the fw via this ID which is a reference to a pre-allocated array entry. In preparation for flow merge code, enable the nfp_fl_payload structure to be accessed via this stats context ID. Rather than increasing the memory requirements of the pre-allocated array, add a new rhashtable to associate each active stats context ID with its rule payload. While adding new code to the compile metadata functions, slightly restructure the existing function to allow for cleaner, easier to read error handling. Signed-off-by: John Hurley Signed-off-by: Simon Horman --- drivers/net/ethernet/netronome/nfp/flower/main.h | 4 + .../net/ethernet/netronome/nfp/flower/metadata.c | 101 +++++++++++++++++---- 2 files changed, 89 insertions(+), 16 deletions(-) diff --git a/drivers/net/ethernet/netronome/nfp/flower/main.h b/drivers/net/ethernet/netronome/nfp/flower/main.h index 485bdc0e1c20..9b34264197c2 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/main.h +++ b/drivers/net/ethernet/netronome/nfp/flower/main.h @@ -140,6 +140,7 @@ struct nfp_fl_internal_ports { * @flow_table: Hash table used to store flower rules * @stats: Stored stats updates for flower rules * @stats_lock: Lock for flower rule stats updates + * @stats_ctx_table: Hash table to map stats contexts to its flow rule * @cmsg_work: Workqueue for control messages processing * @cmsg_skbs_high: List of higher priority skbs for control message * processing @@ -170,6 +171,7 @@ struct nfp_flower_priv { struct rhashtable flow_table; struct nfp_fl_stats *stats; spinlock_t stats_lock; /* lock stats */ + struct rhashtable stats_ctx_table; struct work_struct cmsg_work; struct sk_buff_head cmsg_skbs_high; struct sk_buff_head cmsg_skbs_low; @@ -304,6 +306,8 @@ struct nfp_fl_payload * nfp_flower_search_fl_table(struct nfp_app *app, unsigned long tc_flower_cookie, struct net_device *netdev); struct nfp_fl_payload * +nfp_flower_get_fl_payload_from_ctx(struct nfp_app *app, u32 ctx_id); +struct nfp_fl_payload * nfp_flower_remove_fl_table(struct nfp_app *app, unsigned long tc_flower_cookie); void nfp_flower_rx_flow_stats(struct nfp_app *app, struct sk_buff *skb); diff --git a/drivers/net/ethernet/netronome/nfp/flower/metadata.c b/drivers/net/ethernet/netronome/nfp/flower/metadata.c index 492837b852b6..d68307e5bf16 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/metadata.c +++ b/drivers/net/ethernet/netronome/nfp/flower/metadata.c @@ -24,6 +24,18 @@ struct nfp_fl_flow_table_cmp_arg { unsigned long cookie; }; +struct nfp_fl_stats_ctx_to_flow { + struct rhash_head ht_node; + u32 stats_cxt; + struct nfp_fl_payload *flow; +}; + +static const struct rhashtable_params stats_ctx_table_params = { + .key_offset = offsetof(struct nfp_fl_stats_ctx_to_flow, stats_cxt), + .head_offset = offsetof(struct nfp_fl_stats_ctx_to_flow, ht_node), + .key_len = sizeof(u32), +}; + static int nfp_release_stats_entry(struct nfp_app *app, u32 stats_context_id) { struct nfp_flower_priv *priv = app->priv; @@ -285,25 +297,42 @@ int nfp_compile_flow_metadata(struct nfp_app *app, struct nfp_fl_payload *nfp_flow, struct net_device *netdev) { + struct nfp_fl_stats_ctx_to_flow *ctx_entry; struct nfp_flower_priv *priv = app->priv; struct nfp_fl_payload *check_entry; u8 new_mask_id; u32 stats_cxt; + int err; - if (nfp_get_stats_entry(app, &stats_cxt)) - return -ENOENT; + err = nfp_get_stats_entry(app, &stats_cxt); + if (err) + return err; nfp_flow->meta.host_ctx_id = cpu_to_be32(stats_cxt); nfp_flow->meta.host_cookie = cpu_to_be64(flow->cookie); nfp_flow->ingress_dev = netdev; + ctx_entry = kzalloc(sizeof(*ctx_entry), GFP_KERNEL); + if (!ctx_entry) { + err = -ENOMEM; + goto err_release_stats; + } + + ctx_entry->stats_cxt = stats_cxt; + ctx_entry->flow = nfp_flow; + + if (rhashtable_insert_fast(&priv->stats_ctx_table, &ctx_entry->ht_node, + stats_ctx_table_params)) { + err = -ENOMEM; + goto err_free_ctx_entry; + } + new_mask_id = 0; if (!nfp_check_mask_add(app, nfp_flow->mask_data, nfp_flow->meta.mask_len, &nfp_flow->meta.flags, &new_mask_id)) { - if (nfp_release_stats_entry(app, stats_cxt)) - return -EINVAL; - return -ENOENT; + err = -ENOENT; + goto err_remove_rhash; } nfp_flow->meta.flow_version = cpu_to_be64(priv->flower_version); @@ -317,23 +346,31 @@ int nfp_compile_flow_metadata(struct nfp_app *app, check_entry = nfp_flower_search_fl_table(app, flow->cookie, netdev); if (check_entry) { - if (nfp_release_stats_entry(app, stats_cxt)) - return -EINVAL; - - if (!nfp_check_mask_remove(app, nfp_flow->mask_data, - nfp_flow->meta.mask_len, - NULL, &new_mask_id)) - return -EINVAL; - - return -EEXIST; + err = -EEXIST; + goto err_remove_mask; } return 0; + +err_remove_mask: + nfp_check_mask_remove(app, nfp_flow->mask_data, nfp_flow->meta.mask_len, + NULL, &new_mask_id); +err_remove_rhash: + WARN_ON_ONCE(rhashtable_remove_fast(&priv->stats_ctx_table, + &ctx_entry->ht_node, + stats_ctx_table_params)); +err_free_ctx_entry: + kfree(ctx_entry); +err_release_stats: + nfp_release_stats_entry(app, stats_cxt); + + return err; } int nfp_modify_flow_metadata(struct nfp_app *app, struct nfp_fl_payload *nfp_flow) { + struct nfp_fl_stats_ctx_to_flow *ctx_entry; struct nfp_flower_priv *priv = app->priv; u8 new_mask_id = 0; u32 temp_ctx_id; @@ -348,12 +385,36 @@ int nfp_modify_flow_metadata(struct nfp_app *app, /* Update flow payload with mask ids. */ nfp_flow->unmasked_data[NFP_FL_MASK_ID_LOCATION] = new_mask_id; - /* Release the stats ctx id. */ + /* Release the stats ctx id and ctx to flow table entry. */ temp_ctx_id = be32_to_cpu(nfp_flow->meta.host_ctx_id); + ctx_entry = rhashtable_lookup_fast(&priv->stats_ctx_table, &temp_ctx_id, + stats_ctx_table_params); + if (!ctx_entry) + return -ENOENT; + + WARN_ON_ONCE(rhashtable_remove_fast(&priv->stats_ctx_table, + &ctx_entry->ht_node, + stats_ctx_table_params)); + kfree(ctx_entry); + return nfp_release_stats_entry(app, temp_ctx_id); } +struct nfp_fl_payload * +nfp_flower_get_fl_payload_from_ctx(struct nfp_app *app, u32 ctx_id) +{ + struct nfp_fl_stats_ctx_to_flow *ctx_entry; + struct nfp_flower_priv *priv = app->priv; + + ctx_entry = rhashtable_lookup_fast(&priv->stats_ctx_table, &ctx_id, + stats_ctx_table_params); + if (!ctx_entry) + return NULL; + + return ctx_entry->flow; +} + static int nfp_fl_obj_cmpfn(struct rhashtable_compare_arg *arg, const void *obj) { @@ -403,6 +464,10 @@ int nfp_flower_metadata_init(struct nfp_app *app, u64 host_ctx_count, if (err) return err; + err = rhashtable_init(&priv->stats_ctx_table, &stats_ctx_table_params); + if (err) + goto err_free_flow_table; + get_random_bytes(&priv->mask_id_seed, sizeof(priv->mask_id_seed)); /* Init ring buffer and unallocated mask_ids. */ @@ -410,7 +475,7 @@ int nfp_flower_metadata_init(struct nfp_app *app, u64 host_ctx_count, kmalloc_array(NFP_FLOWER_MASK_ENTRY_RS, NFP_FLOWER_MASK_ELEMENT_RS, GFP_KERNEL); if (!priv->mask_ids.mask_id_free_list.buf) - goto err_free_flow_table; + goto err_free_stats_ctx_table; priv->mask_ids.init_unallocated = NFP_FLOWER_MASK_ENTRY_RS - 1; @@ -447,6 +512,8 @@ int nfp_flower_metadata_init(struct nfp_app *app, u64 host_ctx_count, kfree(priv->mask_ids.last_used); err_free_mask_id: kfree(priv->mask_ids.mask_id_free_list.buf); +err_free_stats_ctx_table: + rhashtable_destroy(&priv->stats_ctx_table); err_free_flow_table: rhashtable_destroy(&priv->flow_table); return -ENOMEM; @@ -461,6 +528,8 @@ void nfp_flower_metadata_cleanup(struct nfp_app *app) rhashtable_free_and_destroy(&priv->flow_table, nfp_check_rhashtable_empty, NULL); + rhashtable_free_and_destroy(&priv->stats_ctx_table, + nfp_check_rhashtable_empty, NULL); kvfree(priv->stats); kfree(priv->mask_ids.mask_id_free_list.buf); kfree(priv->mask_ids.last_used); From patchwork Mon Apr 15 14:55:59 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Horman X-Patchwork-Id: 1085680 X-Patchwork-Delegate: davem@davemloft.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="dRvmoWmH"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 44jWmG65PYz9s8m for ; Tue, 16 Apr 2019 00:56:30 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727849AbfDOO43 (ORCPT ); Mon, 15 Apr 2019 10:56:29 -0400 Received: from mail-ed1-f68.google.com ([209.85.208.68]:45632 "EHLO mail-ed1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727837AbfDOO41 (ORCPT ); Mon, 15 Apr 2019 10:56:27 -0400 Received: by mail-ed1-f68.google.com with SMTP id o26so14933323edv.12 for ; Mon, 15 Apr 2019 07:56:25 -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=0r1DgoKzt2ApbR+KvPSksdJdstwsCNuqp8aRz0+pZjw=; b=dRvmoWmH6GXblpnQbw17ikiIJYo9salHVSIO1InqdTytXi4Zp0WEkbiktTI846abbb YovlobU4scwbGqlTIUS6ztsL5SHdaIBiONvEbS1KPnwZhTKmP/tA/62FP7wK31DaKbox Tw3LlJ3p2JFaW23P/Hoo1/uAkLx4+/WMwm+lFQMvPo90OH0lMk2OooVjzlcIiML/M4v8 +siAYzrn6JQVNhqFRXY8kn8bSWmBMRA6tZ72rd6zZkUQp6iWQz/VqWVzdn1RzipvJZ79 OyLPQXBhRa2nimorgzi2kFczqNotlTSAjFBljPq9sJf7t7NnyuyO4/wENkhGHuYgkjgH GyQA== 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=0r1DgoKzt2ApbR+KvPSksdJdstwsCNuqp8aRz0+pZjw=; b=NL0DDPPCyQxRamAUPJgymAtdeCpkYiOqnYiLqNuSXa5mip0x7dqYeOBGIuwxi8if9G PCJF3yYjxXRs7hU8MXFbYzJSbhipQHODeKvmYY/nhQo94Jj0RMYC6L/snkbZv2f9qq5X MUaOSuQYF18AIgzCv9Nwvg1sKHBLrcv9VBHLM5d2hE01NJnqOIfT4UCEHXcq1lNVKWGK FfVwjVZEsx1Yx/1vvp9kAAf0Zx/glnKvyZwLpaIvO5aGL40Hl99MR9xvgsNCFjk4dkpQ lf/Olh11yO7A9wh0c9xuCWCgyYt5i6kEPx03npgYPoI/1Xkfa+wwSmfk4oPiczZRb02g Yh+g== X-Gm-Message-State: APjAAAWmH6fuily8iEFeE0rj365Bhm2j3g0VKgeF1Qn3Z4Kvuda6tE+l AmyIeKEc0TdvhuEcJGTqJDWrZpRDKYD3FNT9 X-Google-Smtp-Source: APXvYqymErnXT223k6bfKFE+Zs1ohhh/AtIlf5vYTpXsmqDmcoNsK78z2bBxsTfmStvlm5K4os/1bQ== X-Received: by 2002:a17:906:7c5a:: with SMTP id g26mr40317361ejp.121.1555340184789; Mon, 15 Apr 2019 07:56:24 -0700 (PDT) Received: from reginn.horms.nl ([2001:982:756:703:d63d:7eff:fe99:ac9d]) by smtp.gmail.com with ESMTPSA id c38sm2540023ede.61.2019.04.15.07.56.23 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 15 Apr 2019 07:56:24 -0700 (PDT) From: Simon Horman To: David Miller , Jakub Kicinski Cc: netdev@vger.kernel.org, oss-drivers@netronome.com, John Hurley , Simon Horman Subject: [PATCH net-next 07/11] nfp: flower: handle merge hint messages Date: Mon, 15 Apr 2019 16:55:59 +0200 Message-Id: <20190415145603.32491-8-simon.horman@netronome.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20190415145603.32491-1-simon.horman@netronome.com> References: <20190415145603.32491-1-simon.horman@netronome.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: John Hurley If a merge hint is received containing 2 flows that are matched via an implicit recirculation (sending to and matching on an internal port), fw reports that the flows (called sub_flows) may be able to be combined to a single flow. Add infastructure to accept and process merge hint messages. The actual merging of the flows is left as a stub call. Signed-off-by: John Hurley Signed-off-by: Simon Horman --- drivers/net/ethernet/netronome/nfp/flower/cmsg.c | 48 +++++++++++++++++++++- drivers/net/ethernet/netronome/nfp/flower/cmsg.h | 10 +++++ drivers/net/ethernet/netronome/nfp/flower/main.h | 3 ++ .../net/ethernet/netronome/nfp/flower/offload.c | 18 ++++++++ 4 files changed, 78 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/netronome/nfp/flower/cmsg.c b/drivers/net/ethernet/netronome/nfp/flower/cmsg.c index d67f7e10be69..2054a2f0bbc4 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/cmsg.c +++ b/drivers/net/ethernet/netronome/nfp/flower/cmsg.c @@ -205,6 +205,50 @@ nfp_flower_cmsg_portreify_rx(struct nfp_app *app, struct sk_buff *skb) } static void +nfp_flower_cmsg_merge_hint_rx(struct nfp_app *app, struct sk_buff *skb) +{ + unsigned int msg_len = nfp_flower_cmsg_get_data_len(skb); + struct nfp_flower_cmsg_merge_hint *msg; + struct nfp_fl_payload *sub_flows[2]; + int err, i, flow_cnt; + + msg = nfp_flower_cmsg_get_data(skb); + /* msg->count starts at 0 and always assumes at least 1 entry. */ + flow_cnt = msg->count + 1; + + if (msg_len < struct_size(msg, flow, flow_cnt)) { + nfp_flower_cmsg_warn(app, "Merge hint ctrl msg too short - %d bytes but expect %ld\n", + msg_len, struct_size(msg, flow, flow_cnt)); + return; + } + + if (flow_cnt != 2) { + nfp_flower_cmsg_warn(app, "Merge hint contains %d flows - two are expected\n", + flow_cnt); + return; + } + + rtnl_lock(); + for (i = 0; i < flow_cnt; i++) { + u32 ctx = be32_to_cpu(msg->flow[i].host_ctx); + + sub_flows[i] = nfp_flower_get_fl_payload_from_ctx(app, ctx); + if (!sub_flows[i]) { + nfp_flower_cmsg_warn(app, "Invalid flow in merge hint\n"); + goto err_rtnl_unlock; + } + } + + err = nfp_flower_merge_offloaded_flows(app, sub_flows[0], sub_flows[1]); + /* Only warn on memory fail. Hint veto will not break functionality. */ + if (err == -ENOMEM) + nfp_flower_cmsg_warn(app, "Flow merge memory fail.\n"); + +err_rtnl_unlock: + rtnl_unlock(); +} + +static void nfp_flower_cmsg_process_one_rx(struct nfp_app *app, struct sk_buff *skb) { struct nfp_flower_priv *app_priv = app->priv; @@ -223,8 +267,10 @@ nfp_flower_cmsg_process_one_rx(struct nfp_app *app, struct sk_buff *skb) nfp_flower_cmsg_portmod_rx(app, skb); break; case NFP_FLOWER_CMSG_TYPE_MERGE_HINT: - if (app_priv->flower_ext_feats & NFP_FL_FEATS_FLOW_MERGE) + if (app_priv->flower_ext_feats & NFP_FL_FEATS_FLOW_MERGE) { + nfp_flower_cmsg_merge_hint_rx(app, skb); break; + } goto err_default; case NFP_FLOWER_CMSG_TYPE_NO_NEIGH: nfp_tunnel_request_route(app, skb); diff --git a/drivers/net/ethernet/netronome/nfp/flower/cmsg.h b/drivers/net/ethernet/netronome/nfp/flower/cmsg.h index 41a2290eb838..9288595032cc 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/cmsg.h +++ b/drivers/net/ethernet/netronome/nfp/flower/cmsg.h @@ -452,6 +452,16 @@ struct nfp_flower_cmsg_portreify { #define NFP_FLOWER_CMSG_PORTREIFY_INFO_EXIST BIT(0) +/* NFP_FLOWER_CMSG_TYPE_FLOW_MERGE_HINT */ +struct nfp_flower_cmsg_merge_hint { + u8 reserved[3]; + u8 count; + struct { + __be32 host_ctx; + __be64 host_cookie; + } __packed flow[0]; +}; + enum nfp_flower_cmsg_port_type { NFP_FLOWER_CMSG_PORT_TYPE_UNSPEC = 0x0, NFP_FLOWER_CMSG_PORT_TYPE_PHYS_PORT = 0x1, diff --git a/drivers/net/ethernet/netronome/nfp/flower/main.h b/drivers/net/ethernet/netronome/nfp/flower/main.h index 9b34264197c2..311daffb897d 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/main.h +++ b/drivers/net/ethernet/netronome/nfp/flower/main.h @@ -285,6 +285,9 @@ void nfp_flower_metadata_cleanup(struct nfp_app *app); int nfp_flower_setup_tc(struct nfp_app *app, struct net_device *netdev, enum tc_setup_type type, void *type_data); +int nfp_flower_merge_offloaded_flows(struct nfp_app *app, + struct nfp_fl_payload *sub_flow1, + struct nfp_fl_payload *sub_flow2); int nfp_flower_compile_flow_match(struct nfp_app *app, struct tc_cls_flower_offload *flow, struct nfp_fl_key_ls *key_ls, diff --git a/drivers/net/ethernet/netronome/nfp/flower/offload.c b/drivers/net/ethernet/netronome/nfp/flower/offload.c index af406e6cff98..1870b5e1fe39 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/offload.c +++ b/drivers/net/ethernet/netronome/nfp/flower/offload.c @@ -389,6 +389,24 @@ nfp_flower_allocate_new(struct nfp_fl_key_ls *key_layer) } /** + * nfp_flower_merge_offloaded_flows() - Merge 2 existing flows to single flow. + * @app: Pointer to the APP handle + * @sub_flow1: Initial flow matched to produce merge hint + * @sub_flow2: Post recirculation flow matched in merge hint + * + * Combines 2 flows (if valid) to a single flow, removing the initial from hw + * and offloading the new, merged flow. + * + * Return: negative value on error, 0 in success. + */ +int nfp_flower_merge_offloaded_flows(struct nfp_app *app, + struct nfp_fl_payload *sub_flow1, + struct nfp_fl_payload *sub_flow2) +{ + return -EOPNOTSUPP; +} + +/** * nfp_flower_add_offload() - Adds a new flow to hardware. * @app: Pointer to the APP handle * @netdev: netdev structure. From patchwork Mon Apr 15 14:56:00 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Horman X-Patchwork-Id: 1085681 X-Patchwork-Delegate: davem@davemloft.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="tFVjDAG2"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 44jWmK15M3z9s9T for ; Tue, 16 Apr 2019 00:56:33 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727582AbfDOO4b (ORCPT ); Mon, 15 Apr 2019 10:56:31 -0400 Received: from mail-ed1-f66.google.com ([209.85.208.66]:40976 "EHLO mail-ed1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727840AbfDOO43 (ORCPT ); Mon, 15 Apr 2019 10:56:29 -0400 Received: by mail-ed1-f66.google.com with SMTP id g6so11001142edc.8 for ; Mon, 15 Apr 2019 07:56:26 -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=bAP4NNUf3Gcok6izCwpXW8ScV/NxtAWm8tDcqGNgWKI=; b=tFVjDAG2GoyrchT6W07MRpFglCAKfk1LcbJWUnPOC36fUNmUvAM1igtmujWfbX16Vc B/SsieOQonhfv+KivFxXk+ZVU0hBS/Ts5IzaBeoncbXbphf1lc3P2dybSt6JgjTIh6Fs jNNdzayml7JqDXCd2/pNlosbRjNH3HFShte+kE8wC6jAOsZOrzz1KTYFlE9dJV5CRtxE YBjV3P1QqzUcTBYu1fCrwvO4UeWv9tH6pa3Hqr9cWqPJYqaCxwK1KwWJfg5uJkENx0Ya 3yK/VfPwshcxzc5Oj94coOJmWoTgVqMiao7pL6up7xFVExCmJd3MUl8BZBWDK/MDxOgd Rq2g== 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=bAP4NNUf3Gcok6izCwpXW8ScV/NxtAWm8tDcqGNgWKI=; b=d1W0CWfJR9zzlOL2Nqvlv3Yu6GycbJTq57fSW5HPQr9XREMfX7me1nUES7co8wey21 iRGIxCWb2bvzIJtU9b3Qcm4yly5du5PZtE0vVLq4BLGAEP5tbLsHFvWsetypeqsoI9Pp SoYmsI5HpeJtyWOd7pPeCwxwIsId2T10L0OzXg4zLf6WxEUP/RA7XrQ2vnbjkOVg0HrU IYCS7GJtBX/8p9vbUAzB9M5otGPibT5F7kPpshu2c0So/A9fkaCSfNCf7HCVYGy2Q8PL EqRiPQua4EYDR89xjF4h/cMGKHtTwMpFyTi1OARd7iv7ubEF9edLa6vCMctqo1wdWUrW 92tQ== X-Gm-Message-State: APjAAAWhDi9OHnisBHQntH05P5v/Hzz7h4kzgqrwQQUKatk5RREI097/ 8E30TJwfQ4h0No/DjzYRO1oi4A== X-Google-Smtp-Source: APXvYqz+pnz1fSLrZvuC+998xirUXkoOkOscknvhRNxJkxqAI82t6k8L/iO6aNUP42TFgoYXNMZhZw== X-Received: by 2002:a17:906:4b06:: with SMTP id y6mr8234561eju.107.1555340186206; Mon, 15 Apr 2019 07:56:26 -0700 (PDT) Received: from reginn.horms.nl ([2001:982:756:703:d63d:7eff:fe99:ac9d]) by smtp.gmail.com with ESMTPSA id c38sm2540023ede.61.2019.04.15.07.56.24 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 15 Apr 2019 07:56:24 -0700 (PDT) From: Simon Horman To: David Miller , Jakub Kicinski Cc: netdev@vger.kernel.org, oss-drivers@netronome.com, John Hurley , Simon Horman Subject: [PATCH net-next 08/11] nfp: flower: validate merge hint flows Date: Mon, 15 Apr 2019 16:56:00 +0200 Message-Id: <20190415145603.32491-9-simon.horman@netronome.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20190415145603.32491-1-simon.horman@netronome.com> References: <20190415145603.32491-1-simon.horman@netronome.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: John Hurley Two flows can be merged if the second flow (after recirculation) matches on bits that are either matched on or explicitly set by the first flow. This means that if a packet hits flow 1 and recirculates then it is guaranteed to hit flow 2. Add a 'can_merge' function that determines if 2 sub_flows in a merge hint can be validly merged to a single flow. Signed-off-by: John Hurley Signed-off-by: Simon Horman --- .../net/ethernet/netronome/nfp/flower/offload.c | 228 +++++++++++++++++++++ 1 file changed, 228 insertions(+) diff --git a/drivers/net/ethernet/netronome/nfp/flower/offload.c b/drivers/net/ethernet/netronome/nfp/flower/offload.c index 1870b5e1fe39..24e23cba0985 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/offload.c +++ b/drivers/net/ethernet/netronome/nfp/flower/offload.c @@ -55,6 +55,28 @@ BIT(FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS) | \ BIT(FLOW_DISSECTOR_KEY_ENC_PORTS)) +#define NFP_FLOWER_MERGE_FIELDS \ + (NFP_FLOWER_LAYER_PORT | \ + NFP_FLOWER_LAYER_MAC | \ + NFP_FLOWER_LAYER_TP | \ + NFP_FLOWER_LAYER_IPV4 | \ + NFP_FLOWER_LAYER_IPV6) + +struct nfp_flower_merge_check { + union { + struct { + __be16 tci; + struct nfp_flower_mac_mpls l2; + struct nfp_flower_tp_ports l4; + union { + struct nfp_flower_ipv4 ipv4; + struct nfp_flower_ipv6 ipv6; + }; + }; + unsigned long vals[8]; + }; +}; + static int nfp_flower_xmit_flow(struct nfp_app *app, struct nfp_fl_payload *nfp_flow, u8 mtype) @@ -388,6 +410,206 @@ nfp_flower_allocate_new(struct nfp_fl_key_ls *key_layer) return NULL; } +static int +nfp_flower_update_merge_with_actions(struct nfp_fl_payload *flow, + struct nfp_flower_merge_check *merge, + u8 *last_act_id, int *act_out) +{ + struct nfp_fl_set_ipv6_tc_hl_fl *ipv6_tc_hl_fl; + struct nfp_fl_set_ip4_ttl_tos *ipv4_ttl_tos; + struct nfp_fl_set_ip4_addrs *ipv4_add; + struct nfp_fl_set_ipv6_addr *ipv6_add; + struct nfp_fl_push_vlan *push_vlan; + struct nfp_fl_set_tport *tport; + struct nfp_fl_set_eth *eth; + struct nfp_fl_act_head *a; + unsigned int act_off = 0; + u8 act_id = 0; + u8 *ports; + int i; + + while (act_off < flow->meta.act_len) { + a = (struct nfp_fl_act_head *)&flow->action_data[act_off]; + act_id = a->jump_id; + + switch (act_id) { + case NFP_FL_ACTION_OPCODE_OUTPUT: + if (act_out) + (*act_out)++; + break; + case NFP_FL_ACTION_OPCODE_PUSH_VLAN: + push_vlan = (struct nfp_fl_push_vlan *)a; + if (push_vlan->vlan_tci) + merge->tci = cpu_to_be16(0xffff); + break; + case NFP_FL_ACTION_OPCODE_POP_VLAN: + merge->tci = cpu_to_be16(0); + break; + case NFP_FL_ACTION_OPCODE_SET_IPV4_TUNNEL: + /* New tunnel header means l2 to l4 can be matched. */ + eth_broadcast_addr(&merge->l2.mac_dst[0]); + eth_broadcast_addr(&merge->l2.mac_src[0]); + memset(&merge->l4, 0xff, + sizeof(struct nfp_flower_tp_ports)); + memset(&merge->ipv4, 0xff, + sizeof(struct nfp_flower_ipv4)); + break; + case NFP_FL_ACTION_OPCODE_SET_ETHERNET: + eth = (struct nfp_fl_set_eth *)a; + for (i = 0; i < ETH_ALEN; i++) + merge->l2.mac_dst[i] |= eth->eth_addr_mask[i]; + for (i = 0; i < ETH_ALEN; i++) + merge->l2.mac_src[i] |= + eth->eth_addr_mask[ETH_ALEN + i]; + break; + case NFP_FL_ACTION_OPCODE_SET_IPV4_ADDRS: + ipv4_add = (struct nfp_fl_set_ip4_addrs *)a; + merge->ipv4.ipv4_src |= ipv4_add->ipv4_src_mask; + merge->ipv4.ipv4_dst |= ipv4_add->ipv4_dst_mask; + break; + case NFP_FL_ACTION_OPCODE_SET_IPV4_TTL_TOS: + ipv4_ttl_tos = (struct nfp_fl_set_ip4_ttl_tos *)a; + merge->ipv4.ip_ext.ttl |= ipv4_ttl_tos->ipv4_ttl_mask; + merge->ipv4.ip_ext.tos |= ipv4_ttl_tos->ipv4_tos_mask; + break; + case NFP_FL_ACTION_OPCODE_SET_IPV6_SRC: + ipv6_add = (struct nfp_fl_set_ipv6_addr *)a; + for (i = 0; i < 4; i++) + merge->ipv6.ipv6_src.in6_u.u6_addr32[i] |= + ipv6_add->ipv6[i].mask; + break; + case NFP_FL_ACTION_OPCODE_SET_IPV6_DST: + ipv6_add = (struct nfp_fl_set_ipv6_addr *)a; + for (i = 0; i < 4; i++) + merge->ipv6.ipv6_dst.in6_u.u6_addr32[i] |= + ipv6_add->ipv6[i].mask; + break; + case NFP_FL_ACTION_OPCODE_SET_IPV6_TC_HL_FL: + ipv6_tc_hl_fl = (struct nfp_fl_set_ipv6_tc_hl_fl *)a; + merge->ipv6.ip_ext.ttl |= + ipv6_tc_hl_fl->ipv6_hop_limit_mask; + merge->ipv6.ip_ext.tos |= ipv6_tc_hl_fl->ipv6_tc_mask; + merge->ipv6.ipv6_flow_label_exthdr |= + ipv6_tc_hl_fl->ipv6_label_mask; + break; + case NFP_FL_ACTION_OPCODE_SET_UDP: + case NFP_FL_ACTION_OPCODE_SET_TCP: + tport = (struct nfp_fl_set_tport *)a; + ports = (u8 *)&merge->l4.port_src; + for (i = 0; i < 4; i++) + ports[i] |= tport->tp_port_mask[i]; + break; + case NFP_FL_ACTION_OPCODE_PRE_TUNNEL: + case NFP_FL_ACTION_OPCODE_PRE_LAG: + case NFP_FL_ACTION_OPCODE_PUSH_GENEVE: + break; + default: + return -EOPNOTSUPP; + } + + act_off += a->len_lw << NFP_FL_LW_SIZ; + } + + if (last_act_id) + *last_act_id = act_id; + + return 0; +} + +static int +nfp_flower_populate_merge_match(struct nfp_fl_payload *flow, + struct nfp_flower_merge_check *merge, + bool extra_fields) +{ + struct nfp_flower_meta_tci *meta_tci; + u8 *mask = flow->mask_data; + u8 key_layer, match_size; + + memset(merge, 0, sizeof(struct nfp_flower_merge_check)); + + meta_tci = (struct nfp_flower_meta_tci *)mask; + key_layer = meta_tci->nfp_flow_key_layer; + + if (key_layer & ~NFP_FLOWER_MERGE_FIELDS && !extra_fields) + return -EOPNOTSUPP; + + merge->tci = meta_tci->tci; + mask += sizeof(struct nfp_flower_meta_tci); + + if (key_layer & NFP_FLOWER_LAYER_EXT_META) + mask += sizeof(struct nfp_flower_ext_meta); + + mask += sizeof(struct nfp_flower_in_port); + + if (key_layer & NFP_FLOWER_LAYER_MAC) { + match_size = sizeof(struct nfp_flower_mac_mpls); + memcpy(&merge->l2, mask, match_size); + mask += match_size; + } + + if (key_layer & NFP_FLOWER_LAYER_TP) { + match_size = sizeof(struct nfp_flower_tp_ports); + memcpy(&merge->l4, mask, match_size); + mask += match_size; + } + + if (key_layer & NFP_FLOWER_LAYER_IPV4) { + match_size = sizeof(struct nfp_flower_ipv4); + memcpy(&merge->ipv4, mask, match_size); + } + + if (key_layer & NFP_FLOWER_LAYER_IPV6) { + match_size = sizeof(struct nfp_flower_ipv6); + memcpy(&merge->ipv6, mask, match_size); + } + + return 0; +} + +static int +nfp_flower_can_merge(struct nfp_fl_payload *sub_flow1, + struct nfp_fl_payload *sub_flow2) +{ + /* Two flows can be merged if sub_flow2 only matches on bits that are + * either matched by sub_flow1 or set by a sub_flow1 action. This + * ensures that every packet that hits sub_flow1 and recirculates is + * guaranteed to hit sub_flow2. + */ + struct nfp_flower_merge_check sub_flow1_merge, sub_flow2_merge; + int err, act_out = 0; + u8 last_act_id = 0; + + err = nfp_flower_populate_merge_match(sub_flow1, &sub_flow1_merge, + true); + if (err) + return err; + + err = nfp_flower_populate_merge_match(sub_flow2, &sub_flow2_merge, + false); + if (err) + return err; + + err = nfp_flower_update_merge_with_actions(sub_flow1, &sub_flow1_merge, + &last_act_id, &act_out); + if (err) + return err; + + /* Must only be 1 output action and it must be the last in sequence. */ + if (act_out != 1 || last_act_id != NFP_FL_ACTION_OPCODE_OUTPUT) + return -EOPNOTSUPP; + + /* Reject merge if sub_flow2 matches on something that is not matched + * on or set in an action by sub_flow1. + */ + err = bitmap_andnot(sub_flow2_merge.vals, sub_flow2_merge.vals, + sub_flow1_merge.vals, + sizeof(struct nfp_flower_merge_check) * 8); + if (err) + return -EINVAL; + + return 0; +} + /** * nfp_flower_merge_offloaded_flows() - Merge 2 existing flows to single flow. * @app: Pointer to the APP handle @@ -403,6 +625,12 @@ int nfp_flower_merge_offloaded_flows(struct nfp_app *app, struct nfp_fl_payload *sub_flow1, struct nfp_fl_payload *sub_flow2) { + int err; + + err = nfp_flower_can_merge(sub_flow1, sub_flow2); + if (err) + return err; + return -EOPNOTSUPP; } From patchwork Mon Apr 15 14:56:01 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Horman X-Patchwork-Id: 1085682 X-Patchwork-Delegate: davem@davemloft.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="gVkPtAaa"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 44jWmL14k3z9s8m for ; Tue, 16 Apr 2019 00:56:34 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727860AbfDOO4c (ORCPT ); Mon, 15 Apr 2019 10:56:32 -0400 Received: from mail-ed1-f66.google.com ([209.85.208.66]:36983 "EHLO mail-ed1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727838AbfDOO4b (ORCPT ); Mon, 15 Apr 2019 10:56:31 -0400 Received: by mail-ed1-f66.google.com with SMTP id f53so13392771ede.4 for ; Mon, 15 Apr 2019 07:56:28 -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=wiISF+6XC3SDzhv/q7mJfr+85GCnFqV+G+AHvzsf9Jo=; b=gVkPtAaaHMszjr6UD0IS1d70xOJl1//cEq94/17hkWqV6wOL4BzlhZlmu4MejjDXhZ z5R3hQTaxEvk5zxr7HI4fZ2k9Q5CmaBImfMgqHXW7qK5Pear0isCCgGV8oJ/U5zohjEr sZjTShNMPpoalQ/BpuKUrnZ3hh2AmD8rxkuO70d7rNPSrDIxw0oPlyI5Q1ODDtSU+uCa DJXki7pGygA8FT1X5CK1B27DPnj517Z6w0SlmkjjpV7MS1w2IVpStUgSAzxkxNpsEx4l HaBWKgtqUlvt5ROlhlb8+ZLXQ+O4Uy4ZmzG2wnevboBGvnfU3QHlBcLSkCtV3g7zhcY5 8AJw== 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=wiISF+6XC3SDzhv/q7mJfr+85GCnFqV+G+AHvzsf9Jo=; b=EY1XVf84ZUZzhIUB5AZ6qBtz4q+lxY8BxHGLEBzZHRpwcOYadnobdk9ALz6EAybBEO QW+TNRN3H0eE2B7mchmMI8M0K/ZmF4ECllOAmfC0z6IcWTRIhRhQwl33YrO5en8bgZ72 Ny0inyqL7oEXf8jkYVrUjfDYFiwIu3UhMWB53UKEI8b3PlAeJ0P0bI0aO/UKSCfwmRo1 Vdw7n2/n0tW0FFJrHQgU1dmj9OknUnALNNAJPOkwCAhW3A/qRdHBGrfq38I1SLbFgPLd axxQaATreXgFUkPFqpl82HW5nth9yp9tHp2yhB6BL4Zqp1XgdzpMpDqOQcpRLN67BlPF u2xg== X-Gm-Message-State: APjAAAVuPwRj2bFvnEkCEqmXi+D1A5zKWG0MsPgTUODLkGTIhMEvxW+H 9p6hb0giMBXswRy6zVHD/amWr5r6Txdy3+iy X-Google-Smtp-Source: APXvYqwMBVfBCBJfezqvzCVHxdo2ipWblKZY3eTJIRUGhrXHSHYvhqHKg1AnlDVndT5e/0XW4gg7Cw== X-Received: by 2002:a50:a725:: with SMTP id h34mr47706118edc.201.1555340188035; Mon, 15 Apr 2019 07:56:28 -0700 (PDT) Received: from reginn.horms.nl ([2001:982:756:703:d63d:7eff:fe99:ac9d]) by smtp.gmail.com with ESMTPSA id c38sm2540023ede.61.2019.04.15.07.56.26 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 15 Apr 2019 07:56:27 -0700 (PDT) From: Simon Horman To: David Miller , Jakub Kicinski Cc: netdev@vger.kernel.org, oss-drivers@netronome.com, John Hurley , Simon Horman Subject: [PATCH net-next 09/11] nfp: flower: generate merge flow rule Date: Mon, 15 Apr 2019 16:56:01 +0200 Message-Id: <20190415145603.32491-10-simon.horman@netronome.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20190415145603.32491-1-simon.horman@netronome.com> References: <20190415145603.32491-1-simon.horman@netronome.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: John Hurley When combining 2 sub_flows to a single 'merge flow' (assuming the merge is valid), the merge flow should contain the same match fields as sub_flow 1 with actions derived from a combination of sub_flows 1 and 2. This action list should have all actions from sub_flow 1 with the exception of the output action that triggered the 'implicit recirculation' by sending to an internal port, followed by all actions of sub_flow 2. Any pre-actions in either sub_flow should feature at the start of the action list. Add code to generate a new merge flow and populate the match and actions fields based on the sub_flows. The offloading of the flow is left to future patches. Signed-off-by: John Hurley Signed-off-by: Simon Horman --- drivers/net/ethernet/netronome/nfp/flower/main.h | 9 ++ .../net/ethernet/netronome/nfp/flower/offload.c | 142 ++++++++++++++++++++- 2 files changed, 150 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/netronome/nfp/flower/main.h b/drivers/net/ethernet/netronome/nfp/flower/main.h index 311daffb897d..df49cf9d73b3 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/main.h +++ b/drivers/net/ethernet/netronome/nfp/flower/main.h @@ -279,6 +279,15 @@ nfp_flower_internal_port_can_offload(struct nfp_app *app, return false; } +/* The address of the merged flow acts as its cookie. + * Cookies supplied to us by TC flower are also addresses to allocated + * memory and thus this scheme should not generate any collisions. + */ +static inline bool nfp_flower_is_merge_flow(struct nfp_fl_payload *flow_pay) +{ + return flow_pay->tc_flower_cookie == (unsigned long)flow_pay; +} + int nfp_flower_metadata_init(struct nfp_app *app, u64 host_ctx_count, unsigned int host_ctx_split); void nfp_flower_metadata_cleanup(struct nfp_app *app); diff --git a/drivers/net/ethernet/netronome/nfp/flower/offload.c b/drivers/net/ethernet/netronome/nfp/flower/offload.c index 24e23cba0985..1e329667249d 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/offload.c +++ b/drivers/net/ethernet/netronome/nfp/flower/offload.c @@ -610,6 +610,112 @@ nfp_flower_can_merge(struct nfp_fl_payload *sub_flow1, return 0; } +static unsigned int +nfp_flower_copy_pre_actions(char *act_dst, char *act_src, int len, + bool *tunnel_act) +{ + unsigned int act_off = 0, act_len; + struct nfp_fl_act_head *a; + u8 act_id = 0; + + while (act_off < len) { + a = (struct nfp_fl_act_head *)&act_src[act_off]; + act_len = a->len_lw << NFP_FL_LW_SIZ; + act_id = a->jump_id; + + switch (act_id) { + case NFP_FL_ACTION_OPCODE_PRE_TUNNEL: + if (tunnel_act) + *tunnel_act = true; + case NFP_FL_ACTION_OPCODE_PRE_LAG: + memcpy(act_dst + act_off, act_src + act_off, act_len); + break; + default: + return act_off; + } + + act_off += act_len; + } + + return act_off; +} + +static int nfp_fl_verify_post_tun_acts(char *acts, int len) +{ + struct nfp_fl_act_head *a; + unsigned int act_off = 0; + + while (act_off < len) { + a = (struct nfp_fl_act_head *)&acts[act_off]; + if (a->jump_id != NFP_FL_ACTION_OPCODE_OUTPUT) + return -EOPNOTSUPP; + + act_off += a->len_lw << NFP_FL_LW_SIZ; + } + + return 0; +} + +static int +nfp_flower_merge_action(struct nfp_fl_payload *sub_flow1, + struct nfp_fl_payload *sub_flow2, + struct nfp_fl_payload *merge_flow) +{ + unsigned int sub1_act_len, sub2_act_len, pre_off1, pre_off2; + bool tunnel_act = false; + char *merge_act; + int err; + + /* The last action of sub_flow1 must be output - do not merge this. */ + sub1_act_len = sub_flow1->meta.act_len - sizeof(struct nfp_fl_output); + sub2_act_len = sub_flow2->meta.act_len; + + if (!sub2_act_len) + return -EINVAL; + + if (sub1_act_len + sub2_act_len > NFP_FL_MAX_A_SIZ) + return -EINVAL; + + /* A shortcut can only be applied if there is a single action. */ + if (sub1_act_len) + merge_flow->meta.shortcut = cpu_to_be32(NFP_FL_SC_ACT_NULL); + else + merge_flow->meta.shortcut = sub_flow2->meta.shortcut; + + merge_flow->meta.act_len = sub1_act_len + sub2_act_len; + merge_act = merge_flow->action_data; + + /* Copy any pre-actions to the start of merge flow action list. */ + pre_off1 = nfp_flower_copy_pre_actions(merge_act, + sub_flow1->action_data, + sub1_act_len, &tunnel_act); + merge_act += pre_off1; + sub1_act_len -= pre_off1; + pre_off2 = nfp_flower_copy_pre_actions(merge_act, + sub_flow2->action_data, + sub2_act_len, NULL); + merge_act += pre_off2; + sub2_act_len -= pre_off2; + + /* FW does a tunnel push when egressing, therefore, if sub_flow 1 pushes + * a tunnel, sub_flow 2 can only have output actions for a valid merge. + */ + if (tunnel_act) { + char *post_tun_acts = &sub_flow2->action_data[pre_off2]; + + err = nfp_fl_verify_post_tun_acts(post_tun_acts, sub2_act_len); + if (err) + return err; + } + + /* Copy remaining actions from sub_flows 1 and 2. */ + memcpy(merge_act, sub_flow1->action_data + pre_off1, sub1_act_len); + merge_act += sub1_act_len; + memcpy(merge_act, sub_flow2->action_data + pre_off2, sub2_act_len); + + return 0; +} + /** * nfp_flower_merge_offloaded_flows() - Merge 2 existing flows to single flow. * @app: Pointer to the APP handle @@ -625,13 +731,47 @@ int nfp_flower_merge_offloaded_flows(struct nfp_app *app, struct nfp_fl_payload *sub_flow1, struct nfp_fl_payload *sub_flow2) { + struct nfp_fl_payload *merge_flow; + struct nfp_fl_key_ls merge_key_ls; int err; + ASSERT_RTNL(); + + if (sub_flow1 == sub_flow2 || + nfp_flower_is_merge_flow(sub_flow1) || + nfp_flower_is_merge_flow(sub_flow2)) + return -EINVAL; + err = nfp_flower_can_merge(sub_flow1, sub_flow2); if (err) return err; - return -EOPNOTSUPP; + merge_key_ls.key_size = sub_flow1->meta.key_len; + + merge_flow = nfp_flower_allocate_new(&merge_key_ls); + if (!merge_flow) + return -ENOMEM; + + merge_flow->tc_flower_cookie = (unsigned long)merge_flow; + merge_flow->ingress_dev = sub_flow1->ingress_dev; + + memcpy(merge_flow->unmasked_data, sub_flow1->unmasked_data, + sub_flow1->meta.key_len); + memcpy(merge_flow->mask_data, sub_flow1->mask_data, + sub_flow1->meta.mask_len); + + err = nfp_flower_merge_action(sub_flow1, sub_flow2, merge_flow); + if (err) + goto err_destroy_merge_flow; + + err = -EOPNOTSUPP; + +err_destroy_merge_flow: + kfree(merge_flow->action_data); + kfree(merge_flow->mask_data); + kfree(merge_flow->unmasked_data); + kfree(merge_flow); + return err; } /** From patchwork Mon Apr 15 14:56:02 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Horman X-Patchwork-Id: 1085683 X-Patchwork-Delegate: davem@davemloft.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="p+DlwF+y"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 44jWmQ1pdNz9ryj for ; Tue, 16 Apr 2019 00:56:38 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727867AbfDOO4g (ORCPT ); Mon, 15 Apr 2019 10:56:36 -0400 Received: from mail-ed1-f67.google.com ([209.85.208.67]:41997 "EHLO mail-ed1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727837AbfDOO4c (ORCPT ); Mon, 15 Apr 2019 10:56:32 -0400 Received: by mail-ed1-f67.google.com with SMTP id x61so14949749edc.9 for ; Mon, 15 Apr 2019 07:56:30 -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=wEhaYA9MMEKlsHZMtZe9lP9URuSrVY5y5FvPdJTuaYM=; b=p+DlwF+y8h8y1+RtTR9LElfJCyTm+xhps7tlUYOrOt26WloapwQZGpZ9i3Hbkvzyr+ et+Ld1A4pd/ULo4hCUsOO4jFCEDU9SWIRWtKQ7okhRZoW/y+s+qj3vjobp8xYwZxSgGl z52vYwlNmUg59h6gfJJmt4bQ5R7lta3fGM5yCq9LDMQq2UpJ0HJi0RT9GG7pB23KrBkX aPCJbDoAARkhv4L+NNY/e2LUNi8rPrW5gbYc0+hE0p1l5zrgZT/m5MEW0jrB/yL46XWl ycmczNp8RFRzOKtr/ys1APxywhRpqf/L1AUIWTDPuN7NVyUh+yqNa07ahFArqnMNqONx 2G5A== 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=wEhaYA9MMEKlsHZMtZe9lP9URuSrVY5y5FvPdJTuaYM=; b=iYAJUQ6rU6r8/keqG3qL2LKJJRilB925VoWOJgGfsfWbO3gPx3D89WgSig+nvVHjqM w4sG3JztBtHLnywf6FVhut5KxRoRjeIu2rD8RK97S1D53pR9ZfDSMWkXuYoNa9ftgPdR 95snX8VUJoGlPpnOwrkOiPaeXg4uKROitOvi5OfluXcbhTw/2HsEmoVI2cQ4za6j/wn7 vQZawz9d4N4r692haaFLafqAwxg5s+rtr8pxPgIhcYrJQKKbzwRlMzqcpLpBkbaIPvFE 6LGtZmd8X1zbjKurn5olxKwp/CnID1qT+xRHLLxbluXya0o2gyZeXDRZB2mT9cf5kzKT LJtA== X-Gm-Message-State: APjAAAXreWLM36WCjq9GFSZfkRFWYzpzzNh9nPFQ6Gm6U8/5EZkNKbOs kGvjsxa5MPAFtAKkO59yOwkXPw== X-Google-Smtp-Source: APXvYqxbS4vAuebu0566HCWB1dnyPpYBZytiq98yxrkRmMFjw2Uv576jcMdKAvT3LfbIx3xDQN5ybg== X-Received: by 2002:a50:9816:: with SMTP id g22mr14037677edb.236.1555340189535; Mon, 15 Apr 2019 07:56:29 -0700 (PDT) Received: from reginn.horms.nl ([2001:982:756:703:d63d:7eff:fe99:ac9d]) by smtp.gmail.com with ESMTPSA id c38sm2540023ede.61.2019.04.15.07.56.28 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 15 Apr 2019 07:56:28 -0700 (PDT) From: Simon Horman To: David Miller , Jakub Kicinski Cc: netdev@vger.kernel.org, oss-drivers@netronome.com, John Hurley , Simon Horman Subject: [PATCH net-next 10/11] nfp: flower: support stats update for merge flows Date: Mon, 15 Apr 2019 16:56:02 +0200 Message-Id: <20190415145603.32491-11-simon.horman@netronome.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20190415145603.32491-1-simon.horman@netronome.com> References: <20190415145603.32491-1-simon.horman@netronome.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: John Hurley With the merging of 2 sub flows, a new 'merge' flow will be created and written to FW. The TC layer is unaware that the merge flow exists and will request stats from the sub flows. Conversely, the FW treats a merge rule the same as any other rule and sends stats updates to the NFP driver. Add links between merge flows and their sub flows. Use these links to pass merge flow stats updates from FW to the underlying sub flows, ensuring TC stats requests are handled correctly. The updating of sub flow stats is done on (the less time critcal) TC stats requests rather than on FW stats update. Signed-off-by: John Hurley Signed-off-by: Simon Horman --- drivers/net/ethernet/netronome/nfp/flower/main.h | 18 ++++ .../net/ethernet/netronome/nfp/flower/offload.c | 99 ++++++++++++++++++++++ 2 files changed, 117 insertions(+) diff --git a/drivers/net/ethernet/netronome/nfp/flower/main.h b/drivers/net/ethernet/netronome/nfp/flower/main.h index df49cf9d73b3..896f538d6997 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/main.h +++ b/drivers/net/ethernet/netronome/nfp/flower/main.h @@ -252,6 +252,24 @@ struct nfp_fl_payload { char *unmasked_data; char *mask_data; char *action_data; + struct list_head linked_flows; +}; + +struct nfp_fl_payload_link { + /* A link contains a pointer to a merge flow and an associated sub_flow. + * Each merge flow will feature in 2 links to its underlying sub_flows. + * A sub_flow will have at least 1 link to a merge flow or more if it + * has been used to create multiple merge flows. + * + * For a merge flow, 'linked_flows' in its nfp_fl_payload struct lists + * all links to sub_flows (sub_flow.flow) via merge.list. + * For a sub_flow, 'linked_flows' gives all links to merge flows it has + * formed (merge_flow.flow) via sub_flow.list. + */ + struct { + struct list_head list; + struct nfp_fl_payload *flow; + } merge_flow, sub_flow; }; extern const struct rhashtable_params nfp_flower_table_params; diff --git a/drivers/net/ethernet/netronome/nfp/flower/offload.c b/drivers/net/ethernet/netronome/nfp/flower/offload.c index 1e329667249d..1249b89ba660 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/offload.c +++ b/drivers/net/ethernet/netronome/nfp/flower/offload.c @@ -398,6 +398,7 @@ nfp_flower_allocate_new(struct nfp_fl_key_ls *key_layer) flow_pay->nfp_tun_ipv4_addr = 0; flow_pay->meta.flags = 0; + INIT_LIST_HEAD(&flow_pay->linked_flows); return flow_pay; @@ -716,6 +717,43 @@ nfp_flower_merge_action(struct nfp_fl_payload *sub_flow1, return 0; } +/* Flow link code should only be accessed under RTNL. */ +static void nfp_flower_unlink_flow(struct nfp_fl_payload_link *link) +{ + list_del(&link->merge_flow.list); + list_del(&link->sub_flow.list); + kfree(link); +} + +static void nfp_flower_unlink_flows(struct nfp_fl_payload *merge_flow, + struct nfp_fl_payload *sub_flow) +{ + struct nfp_fl_payload_link *link; + + list_for_each_entry(link, &merge_flow->linked_flows, merge_flow.list) + if (link->sub_flow.flow == sub_flow) { + nfp_flower_unlink_flow(link); + return; + } +} + +static int nfp_flower_link_flows(struct nfp_fl_payload *merge_flow, + struct nfp_fl_payload *sub_flow) +{ + struct nfp_fl_payload_link *link; + + link = kmalloc(sizeof(*link), GFP_KERNEL); + if (!link) + return -ENOMEM; + + link->merge_flow.flow = merge_flow; + list_add_tail(&link->merge_flow.list, &merge_flow->linked_flows); + link->sub_flow.flow = sub_flow; + list_add_tail(&link->sub_flow.list, &sub_flow->linked_flows); + + return 0; +} + /** * nfp_flower_merge_offloaded_flows() - Merge 2 existing flows to single flow. * @app: Pointer to the APP handle @@ -764,8 +802,19 @@ int nfp_flower_merge_offloaded_flows(struct nfp_app *app, if (err) goto err_destroy_merge_flow; + err = nfp_flower_link_flows(merge_flow, sub_flow1); + if (err) + goto err_destroy_merge_flow; + + err = nfp_flower_link_flows(merge_flow, sub_flow2); + if (err) + goto err_unlink_sub_flow1; + err = -EOPNOTSUPP; + nfp_flower_unlink_flows(merge_flow, sub_flow2); +err_unlink_sub_flow1: + nfp_flower_unlink_flows(merge_flow, sub_flow1); err_destroy_merge_flow: kfree(merge_flow->action_data); kfree(merge_flow->mask_data); @@ -913,6 +962,52 @@ nfp_flower_del_offload(struct nfp_app *app, struct net_device *netdev, return err; } +static void +__nfp_flower_update_merge_stats(struct nfp_app *app, + struct nfp_fl_payload *merge_flow) +{ + struct nfp_flower_priv *priv = app->priv; + struct nfp_fl_payload_link *link; + struct nfp_fl_payload *sub_flow; + u64 pkts, bytes, used; + u32 ctx_id; + + ctx_id = be32_to_cpu(merge_flow->meta.host_ctx_id); + pkts = priv->stats[ctx_id].pkts; + /* Do not cycle subflows if no stats to distribute. */ + if (!pkts) + return; + bytes = priv->stats[ctx_id].bytes; + used = priv->stats[ctx_id].used; + + /* Reset stats for the merge flow. */ + priv->stats[ctx_id].pkts = 0; + priv->stats[ctx_id].bytes = 0; + + /* The merge flow has received stats updates from firmware. + * Distribute these stats to all subflows that form the merge. + * The stats will collected from TC via the subflows. + */ + list_for_each_entry(link, &merge_flow->linked_flows, merge_flow.list) { + sub_flow = link->sub_flow.flow; + ctx_id = be32_to_cpu(sub_flow->meta.host_ctx_id); + priv->stats[ctx_id].pkts += pkts; + priv->stats[ctx_id].bytes += bytes; + max_t(u64, priv->stats[ctx_id].used, used); + } +} + +static void +nfp_flower_update_merge_stats(struct nfp_app *app, + struct nfp_fl_payload *sub_flow) +{ + struct nfp_fl_payload_link *link; + + /* Get merge flows that the subflow forms to distribute their stats. */ + list_for_each_entry(link, &sub_flow->linked_flows, sub_flow.list) + __nfp_flower_update_merge_stats(app, link->merge_flow.flow); +} + /** * nfp_flower_get_stats() - Populates flow stats obtained from hardware. * @app: Pointer to the APP handle @@ -939,6 +1034,10 @@ nfp_flower_get_stats(struct nfp_app *app, struct net_device *netdev, ctx_id = be32_to_cpu(nfp_flow->meta.host_ctx_id); spin_lock_bh(&priv->stats_lock); + /* If request is for a sub_flow, update stats from merged flows. */ + if (!list_empty(&nfp_flow->linked_flows)) + nfp_flower_update_merge_stats(app, nfp_flow); + flow_stats_update(&flow->stats, priv->stats[ctx_id].bytes, priv->stats[ctx_id].pkts, priv->stats[ctx_id].used); From patchwork Mon Apr 15 14:56:03 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Simon Horman X-Patchwork-Id: 1085684 X-Patchwork-Delegate: davem@davemloft.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="FOFhZkmB"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 44jWmR1KZBz9s55 for ; Tue, 16 Apr 2019 00:56:39 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727862AbfDOO4f (ORCPT ); Mon, 15 Apr 2019 10:56:35 -0400 Received: from mail-ed1-f66.google.com ([209.85.208.66]:33664 "EHLO mail-ed1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727857AbfDOO4e (ORCPT ); Mon, 15 Apr 2019 10:56:34 -0400 Received: by mail-ed1-f66.google.com with SMTP id d55so14183087ede.0 for ; Mon, 15 Apr 2019 07:56:31 -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 :mime-version:content-transfer-encoding; bh=lb4HlCsRlRHgCUisDpg3KTO8ElPyycRWA4LdLgblTxQ=; b=FOFhZkmBq9FmON6gC5zDPST2VU/XH8oFv4Da9SqdUYvj4ImJLJ28ILZ9AxlDO7Q6ye E4Gar5/AOcZGlKG3RwdLwZO/W/Vj+Pg/VVEu64AvYdPerRJGC5nheS6niqWPzXuOMV1D m7dF+nGNMy6qf630kF88H6lbokPbx3eD46JSGSsWi5z+GPYqlgqTiI2WTeyBVp2pwEV2 W68P4Em6lxcSbzNh3DbeH0PwK7wn9TgtAaAP4u+JV5l+P7vcxp+aYgN0lRTjSfCBXtGU Jev/VScQEIcve4F5/DyPaOmexVt8iJWvgY3TL/Kz/1gV8Ff81Nx0o/vHbJHEl0wKq1wX k2yw== 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:mime-version:content-transfer-encoding; bh=lb4HlCsRlRHgCUisDpg3KTO8ElPyycRWA4LdLgblTxQ=; b=OOlx4lccGwF5gmZz7L2z7y+QbUM418PeSQCn4GLB1SRb+Nh8eHXtscAkjjFDWNFbBV T+mlTBkMPiU14S5w7DMWybh6c6DlrpdJ7Lb6NuLrt7JGOgfOyCDy0c/mzntL0rUMZtjN wTE/DIgyTbUfns7jpXtiC57h6NadKDLM9fDoOjoeI1sNuZzR8KM7uaTGBKFHDAIgXfMG rQ/5meefWiSZg+QxhIa8C7BBxE78AKmyjPEGS7+8wB032kWmMi6vGte9JtWmP1jMlP7Q V6lFLwUU6eYjmISqjedcqgqVo8AdJb8peXU+wmQb5gyqbVO/ileJxshP4sgAk9NRteeM QDZA== X-Gm-Message-State: APjAAAWCittWlCUu88zO4PZX9KLzpYURizKjT1BrsJJSKW06wgnmfsxm Gwfg33uEW/cQilaQv8WCQT78SA== X-Google-Smtp-Source: APXvYqw7yIXWF5VrZsaiHWhOiF9clLtLV/7lJXddjhNVZGOxozdvwmjsQ0175YBi1bGKw7hEeNHuhw== X-Received: by 2002:a50:9ea5:: with SMTP id a34mr35477345edf.191.1555340191057; Mon, 15 Apr 2019 07:56:31 -0700 (PDT) Received: from reginn.horms.nl ([2001:982:756:703:d63d:7eff:fe99:ac9d]) by smtp.gmail.com with ESMTPSA id c38sm2540023ede.61.2019.04.15.07.56.29 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 15 Apr 2019 07:56:30 -0700 (PDT) From: Simon Horman To: David Miller , Jakub Kicinski Cc: netdev@vger.kernel.org, oss-drivers@netronome.com, John Hurley , Simon Horman Subject: [PATCH net-next 11/11] nfp: flower: offload merge flows Date: Mon, 15 Apr 2019 16:56:03 +0200 Message-Id: <20190415145603.32491-12-simon.horman@netronome.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20190415145603.32491-1-simon.horman@netronome.com> References: <20190415145603.32491-1-simon.horman@netronome.com> MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: John Hurley A merge flow is formed from 2 sub flows. The match fields of the merge are the same as the first sub flow that has formed it, with the actions being a combination of the first and second sub flow. Therefore, a merge flow should replace sub flow 1 when offloaded. Offload valid merge flows by using a new 'flow mod' message type to replace an existing offloaded rule. Track the deletion of sub flows that are linked to a merge flow and revert offloaded merge rules if required. Signed-off-by: John Hurley Signed-off-by: Simon Horman --- drivers/net/ethernet/netronome/nfp/flower/cmsg.h | 1 + drivers/net/ethernet/netronome/nfp/flower/main.h | 3 + .../net/ethernet/netronome/nfp/flower/metadata.c | 16 +-- .../net/ethernet/netronome/nfp/flower/offload.c | 119 +++++++++++++++++++-- 4 files changed, 126 insertions(+), 13 deletions(-) diff --git a/drivers/net/ethernet/netronome/nfp/flower/cmsg.h b/drivers/net/ethernet/netronome/nfp/flower/cmsg.h index 9288595032cc..a10c29ade5c2 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/cmsg.h +++ b/drivers/net/ethernet/netronome/nfp/flower/cmsg.h @@ -402,6 +402,7 @@ struct nfp_flower_cmsg_hdr { /* Types defined for port related control messages */ enum nfp_flower_cmsg_type_port { NFP_FLOWER_CMSG_TYPE_FLOW_ADD = 0, + NFP_FLOWER_CMSG_TYPE_FLOW_MOD = 1, NFP_FLOWER_CMSG_TYPE_FLOW_DEL = 2, NFP_FLOWER_CMSG_TYPE_LAG_CONFIG = 4, NFP_FLOWER_CMSG_TYPE_PORT_REIFY = 6, diff --git a/drivers/net/ethernet/netronome/nfp/flower/main.h b/drivers/net/ethernet/netronome/nfp/flower/main.h index 896f538d6997..675f43f06526 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/main.h +++ b/drivers/net/ethernet/netronome/nfp/flower/main.h @@ -253,6 +253,7 @@ struct nfp_fl_payload { char *mask_data; char *action_data; struct list_head linked_flows; + bool in_hw; }; struct nfp_fl_payload_link { @@ -329,6 +330,8 @@ int nfp_compile_flow_metadata(struct nfp_app *app, struct tc_cls_flower_offload *flow, struct nfp_fl_payload *nfp_flow, struct net_device *netdev); +void __nfp_modify_flow_metadata(struct nfp_flower_priv *priv, + struct nfp_fl_payload *nfp_flow); int nfp_modify_flow_metadata(struct nfp_app *app, struct nfp_fl_payload *nfp_flow); diff --git a/drivers/net/ethernet/netronome/nfp/flower/metadata.c b/drivers/net/ethernet/netronome/nfp/flower/metadata.c index d68307e5bf16..3d326efdc814 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/metadata.c +++ b/drivers/net/ethernet/netronome/nfp/flower/metadata.c @@ -276,9 +276,6 @@ nfp_check_mask_remove(struct nfp_app *app, char *mask_data, u32 mask_len, if (!mask_entry) return false; - if (meta_flags) - *meta_flags &= ~NFP_FL_META_FLAG_MANAGE_MASK; - *mask_id = mask_entry->mask_id; mask_entry->ref_cnt--; if (!mask_entry->ref_cnt) { @@ -367,6 +364,14 @@ int nfp_compile_flow_metadata(struct nfp_app *app, return err; } +void __nfp_modify_flow_metadata(struct nfp_flower_priv *priv, + struct nfp_fl_payload *nfp_flow) +{ + nfp_flow->meta.flags &= ~NFP_FL_META_FLAG_MANAGE_MASK; + nfp_flow->meta.flow_version = cpu_to_be64(priv->flower_version); + priv->flower_version++; +} + int nfp_modify_flow_metadata(struct nfp_app *app, struct nfp_fl_payload *nfp_flow) { @@ -375,13 +380,12 @@ int nfp_modify_flow_metadata(struct nfp_app *app, u8 new_mask_id = 0; u32 temp_ctx_id; + __nfp_modify_flow_metadata(priv, nfp_flow); + nfp_check_mask_remove(app, nfp_flow->mask_data, nfp_flow->meta.mask_len, &nfp_flow->meta.flags, &new_mask_id); - nfp_flow->meta.flow_version = cpu_to_be64(priv->flower_version); - priv->flower_version++; - /* Update flow payload with mask ids. */ nfp_flow->unmasked_data[NFP_FL_MASK_ID_LOCATION] = new_mask_id; diff --git a/drivers/net/ethernet/netronome/nfp/flower/offload.c b/drivers/net/ethernet/netronome/nfp/flower/offload.c index 1249b89ba660..df81d86ee16b 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/offload.c +++ b/drivers/net/ethernet/netronome/nfp/flower/offload.c @@ -348,7 +348,7 @@ nfp_flower_calculate_key_layers(struct nfp_app *app, break; case cpu_to_be16(ETH_P_IPV6): - key_layer |= NFP_FLOWER_LAYER_IPV6; + key_layer |= NFP_FLOWER_LAYER_IPV6; key_size += sizeof(struct nfp_flower_ipv6); break; @@ -399,6 +399,7 @@ nfp_flower_allocate_new(struct nfp_fl_key_ls *key_layer) flow_pay->nfp_tun_ipv4_addr = 0; flow_pay->meta.flags = 0; INIT_LIST_HEAD(&flow_pay->linked_flows); + flow_pay->in_hw = false; return flow_pay; @@ -769,6 +770,8 @@ int nfp_flower_merge_offloaded_flows(struct nfp_app *app, struct nfp_fl_payload *sub_flow1, struct nfp_fl_payload *sub_flow2) { + struct tc_cls_flower_offload merge_tc_off; + struct nfp_flower_priv *priv = app->priv; struct nfp_fl_payload *merge_flow; struct nfp_fl_key_ls merge_key_ls; int err; @@ -810,8 +813,34 @@ int nfp_flower_merge_offloaded_flows(struct nfp_app *app, if (err) goto err_unlink_sub_flow1; - err = -EOPNOTSUPP; + merge_tc_off.cookie = merge_flow->tc_flower_cookie; + err = nfp_compile_flow_metadata(app, &merge_tc_off, merge_flow, + merge_flow->ingress_dev); + if (err) + goto err_unlink_sub_flow2; + err = rhashtable_insert_fast(&priv->flow_table, &merge_flow->fl_node, + nfp_flower_table_params); + if (err) + goto err_release_metadata; + + err = nfp_flower_xmit_flow(app, merge_flow, + NFP_FLOWER_CMSG_TYPE_FLOW_MOD); + if (err) + goto err_remove_rhash; + + merge_flow->in_hw = true; + sub_flow1->in_hw = false; + + return 0; + +err_remove_rhash: + WARN_ON_ONCE(rhashtable_remove_fast(&priv->flow_table, + &merge_flow->fl_node, + nfp_flower_table_params)); +err_release_metadata: + nfp_modify_flow_metadata(app, merge_flow); +err_unlink_sub_flow2: nfp_flower_unlink_flows(merge_flow, sub_flow2); err_unlink_sub_flow1: nfp_flower_unlink_flows(merge_flow, sub_flow1); @@ -889,6 +918,8 @@ nfp_flower_add_offload(struct nfp_app *app, struct net_device *netdev, if (port) port->tc_offload_cnt++; + flow_pay->in_hw = true; + /* Deallocate flow payload when flower rule has been destroyed. */ kfree(key_layer); @@ -910,6 +941,75 @@ nfp_flower_add_offload(struct nfp_app *app, struct net_device *netdev, return err; } +static void +nfp_flower_remove_merge_flow(struct nfp_app *app, + struct nfp_fl_payload *del_sub_flow, + struct nfp_fl_payload *merge_flow) +{ + struct nfp_flower_priv *priv = app->priv; + struct nfp_fl_payload_link *link, *temp; + struct nfp_fl_payload *origin; + bool mod = false; + int err; + + link = list_first_entry(&merge_flow->linked_flows, + struct nfp_fl_payload_link, merge_flow.list); + origin = link->sub_flow.flow; + + /* Re-add rule the merge had overwritten if it has not been deleted. */ + if (origin != del_sub_flow) + mod = true; + + err = nfp_modify_flow_metadata(app, merge_flow); + if (err) { + nfp_flower_cmsg_warn(app, "Metadata fail for merge flow delete.\n"); + goto err_free_links; + } + + if (!mod) { + err = nfp_flower_xmit_flow(app, merge_flow, + NFP_FLOWER_CMSG_TYPE_FLOW_DEL); + if (err) { + nfp_flower_cmsg_warn(app, "Failed to delete merged flow.\n"); + goto err_free_links; + } + } else { + __nfp_modify_flow_metadata(priv, origin); + err = nfp_flower_xmit_flow(app, origin, + NFP_FLOWER_CMSG_TYPE_FLOW_MOD); + if (err) + nfp_flower_cmsg_warn(app, "Failed to revert merge flow.\n"); + origin->in_hw = true; + } + +err_free_links: + /* Clean any links connected with the merged flow. */ + list_for_each_entry_safe(link, temp, &merge_flow->linked_flows, + merge_flow.list) + nfp_flower_unlink_flow(link); + + kfree(merge_flow->action_data); + kfree(merge_flow->mask_data); + kfree(merge_flow->unmasked_data); + WARN_ON_ONCE(rhashtable_remove_fast(&priv->flow_table, + &merge_flow->fl_node, + nfp_flower_table_params)); + kfree_rcu(merge_flow, rcu); +} + +static void +nfp_flower_del_linked_merge_flows(struct nfp_app *app, + struct nfp_fl_payload *sub_flow) +{ + struct nfp_fl_payload_link *link, *temp; + + /* Remove any merge flow formed from the deleted sub_flow. */ + list_for_each_entry_safe(link, temp, &sub_flow->linked_flows, + sub_flow.list) + nfp_flower_remove_merge_flow(app, sub_flow, + link->merge_flow.flow); +} + /** * nfp_flower_del_offload() - Removes a flow from hardware. * @app: Pointer to the APP handle @@ -917,7 +1017,7 @@ nfp_flower_add_offload(struct nfp_app *app, struct net_device *netdev, * @flow: TC flower classifier offload structure * * Removes a flow from the repeated hash structure and clears the - * action payload. + * action payload. Any flows merged from this are also deleted. * * Return: negative value on error, 0 if removed successfully. */ @@ -939,17 +1039,22 @@ nfp_flower_del_offload(struct nfp_app *app, struct net_device *netdev, err = nfp_modify_flow_metadata(app, nfp_flow); if (err) - goto err_free_flow; + goto err_free_merge_flow; if (nfp_flow->nfp_tun_ipv4_addr) nfp_tunnel_del_ipv4_off(app, nfp_flow->nfp_tun_ipv4_addr); + if (!nfp_flow->in_hw) { + err = 0; + goto err_free_merge_flow; + } + err = nfp_flower_xmit_flow(app, nfp_flow, NFP_FLOWER_CMSG_TYPE_FLOW_DEL); - if (err) - goto err_free_flow; + /* Fall through on error. */ -err_free_flow: +err_free_merge_flow: + nfp_flower_del_linked_merge_flows(app, nfp_flow); if (port) port->tc_offload_cnt--; kfree(nfp_flow->action_data);