From patchwork Mon Nov 11 01:32:16 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aryan Srivastava X-Patchwork-Id: 13870139 X-Patchwork-Delegate: kuba@kernel.org Received: from gate2.alliedtelesis.co.nz (gate2.alliedtelesis.co.nz [202.36.163.20]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8B8AB3B1A2 for ; Mon, 11 Nov 2024 01:32:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=202.36.163.20 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731288759; cv=none; b=Oq1Kg9cdtZyUsBW5yEGHiPROU8nea/mXUQ7Itkbb9Od6MK10idF4DTSjpbRSv2ej1MsnDHG8injwxxO92vATDOvG0ZAtfRRF6K4c9BoaQgryp/IGM32SAloAoy2PdE0neWm1QW3wQSMoZeeiJGMUZjAO11uJkK9qPXrCogPCV/o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731288759; c=relaxed/simple; bh=23UbsY/mqifYQJgheubCjtQcn8SrYehlQFTgvQMQAE4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=uNLhD08QwAFzHiJZrXvAXD6Hn9ZF1L6n/xPFY2WdOfpJ78IgffBSEGfeEDqXXLnWCij9IMHXqxiX7yzYxKBDpWOuyu6viyNDL+cED5u4m1HKGM58tJnicinXXOEccshU8ZN4wBCflqHwJ6CzDJosI4pI9M5WmhNIeQhhrrv0sbQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=alliedtelesis.co.nz; spf=pass smtp.mailfrom=alliedtelesis.co.nz; dkim=pass (2048-bit key) header.d=alliedtelesis.co.nz header.i=@alliedtelesis.co.nz header.b=1ROS159w; arc=none smtp.client-ip=202.36.163.20 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=alliedtelesis.co.nz Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=alliedtelesis.co.nz Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=alliedtelesis.co.nz header.i=@alliedtelesis.co.nz header.b="1ROS159w" Received: from svr-chch-seg1.atlnz.lc (mmarshal3.atlnz.lc [10.32.18.43]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by gate2.alliedtelesis.co.nz (Postfix) with ESMTPS id 5DAF62C05C6; Mon, 11 Nov 2024 14:32:29 +1300 (NZDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=alliedtelesis.co.nz; s=mail181024; t=1731288749; bh=ha6guitHYpw7NDAj6XwH3gG4Gb/JxOADQzIg+ZXDLVs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=1ROS159womHmvSfOnxwXuonITWp3kQsN2tGPvbVZDAI6zhex7LzqQbFzucxi6gvzH Wjdwg4qrmg+KJR7dJWOuvBAaGpuX/h4bHRIuoXOMTu+bhyeSAJrBSBmRH5qBIdAPsM jDg5v6ah5DGPDIwlQzwAmFM2wtokDQgFkTFr7bS+TVxJL3UfxWpqTUvMKTXuK47yiM F0Dbr9IY8QniL7XQPossxuZAH/l5gRmUjESkZyRdaei/FM7E+fS8pBfSRnfbsYCl5S noo0KoyfVSp5tCD12wwuwPzXvjMurJGsacReOYAEdm8GwgTQ7UY8TNJGS0l+RgBYHr WzcYZCR8N+Z/w== Received: from pat.atlnz.lc (Not Verified[10.32.16.33]) by svr-chch-seg1.atlnz.lc with Trustwave SEG (v8,2,6,11305) id ; Mon, 11 Nov 2024 14:32:29 +1300 Received: from aryans-dl.ws.atlnz.lc (aryans-dl.ws.atlnz.lc [10.33.22.38]) by pat.atlnz.lc (Postfix) with ESMTP id 322DC13ECD2; Mon, 11 Nov 2024 14:32:29 +1300 (NZDT) Received: by aryans-dl.ws.atlnz.lc (Postfix, from userid 1844) id 324CC2A151C; Mon, 11 Nov 2024 14:32:29 +1300 (NZDT) From: Aryan Srivastava To: Jiri Pirko , Andrew Lunn Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Aryan Srivastava , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman Subject: [RFC net-next v0 1/2] net: devlink: Add port function for bridge offload Date: Mon, 11 Nov 2024 14:32:16 +1300 Message-ID: <20241111013218.1491641-2-aryan.srivastava@alliedtelesis.co.nz> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20241111013218.1491641-1-aryan.srivastava@alliedtelesis.co.nz> References: <20241111013218.1491641-1-aryan.srivastava@alliedtelesis.co.nz> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-SEG-SpamProfiler-Analysis: v=2.4 cv=ca1xrWDM c=1 sm=1 tr=0 ts=67315ead a=KLBiSEs5mFS1a/PbTCJxuA==:117 a=VlfZXiiP6vEA:10 a=Rn-rybJDi6Mx2ZrNRmMA:9 a=3ZKOabzyN94A:10 X-SEG-SpamProfiler-Score: 0 x-atlnz-ls: pat X-Patchwork-Delegate: kuba@kernel.org X-Patchwork-State: RFC Add configurable devlink port attr for HW offloading. Most drivers (and DSA framework) will offload a bridge port to HW if there is mechanism available to do so. Adding a configurable devlink attr allows users to change this default setting, in cases where HW offload of a bridge port is not desired. Signed-off-by: Aryan Srivastava --- include/net/devlink.h | 13 ++++++++++++ include/uapi/linux/devlink.h | 2 ++ net/devlink/port.c | 41 ++++++++++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+) diff --git a/include/net/devlink.h b/include/net/devlink.h index fbb9a2668e24..64dc3e292c2c 100644 --- a/include/net/devlink.h +++ b/include/net/devlink.h @@ -1613,6 +1613,15 @@ void devlink_free(struct devlink *devlink); * of event queues. Should be used by device drivers to * configure maximum number of event queues * of a function managed by the devlink port. + * @port_fn_bridge_offload_get: Callback used to get port function's bridge + * offload capability. Should be used by device drivers + * to report the current state of offload + * capability of a function managed by the devlink + * port. + * @port_fn_bridge_offload_get: Callback used to set port function's bridge + * offload capability. Should be used by device drivers to + * enable/disable offload capability of a + * function managed by the devlink port. * * Note: Driver should return -EOPNOTSUPP if it doesn't support * port function (@port_fn_*) handling for a particular port. @@ -1668,6 +1677,10 @@ struct devlink_port_ops { int (*port_fn_max_io_eqs_set)(struct devlink_port *devlink_port, u32 max_eqs, struct netlink_ext_ack *extack); + void (*port_fn_bridge_offload_get)(struct devlink_port *devlink_port, + bool *is_enable); + void (*port_fn_bridge_offload_set)(struct devlink_port *devlink_port, + bool enable); }; void devlink_port_init(struct devlink *devlink, diff --git a/include/uapi/linux/devlink.h b/include/uapi/linux/devlink.h index 9401aa343673..e2682bc9ecb1 100644 --- a/include/uapi/linux/devlink.h +++ b/include/uapi/linux/devlink.h @@ -668,6 +668,7 @@ enum devlink_port_fn_attr_cap { DEVLINK_PORT_FN_ATTR_CAP_MIGRATABLE_BIT, DEVLINK_PORT_FN_ATTR_CAP_IPSEC_CRYPTO_BIT, DEVLINK_PORT_FN_ATTR_CAP_IPSEC_PACKET_BIT, + DEVLINK_PORT_FN_ATTR_CAP_BRIDGE_OFFLOAD_BIT, /* Add new caps above */ __DEVLINK_PORT_FN_ATTR_CAPS_MAX, @@ -678,6 +679,7 @@ enum devlink_port_fn_attr_cap { _BITUL(DEVLINK_PORT_FN_ATTR_CAP_MIGRATABLE_BIT) #define DEVLINK_PORT_FN_CAP_IPSEC_CRYPTO _BITUL(DEVLINK_PORT_FN_ATTR_CAP_IPSEC_CRYPTO_BIT) #define DEVLINK_PORT_FN_CAP_IPSEC_PACKET _BITUL(DEVLINK_PORT_FN_ATTR_CAP_IPSEC_PACKET_BIT) +#define DEVLINK_PORT_FN_CAP_BRIDGE_OFFLOAD _BITUL(DEVLINK_PORT_FN_ATTR_CAP_BRIDGE_OFFLOAD_BIT) enum devlink_port_function_attr { DEVLINK_PORT_FUNCTION_ATTR_UNSPEC, diff --git a/net/devlink/port.c b/net/devlink/port.c index be9158b4453c..d7f9276c3601 100644 --- a/net/devlink/port.c +++ b/net/devlink/port.c @@ -148,6 +148,21 @@ static int devlink_port_fn_ipsec_packet_fill(struct devlink_port *devlink_port, return 0; } +static int devlink_port_bridge_offload_fill(struct devlink_port *devlink_port, + struct nla_bitfield32 *caps) +{ + bool is_enable; + + if (!devlink_port->ops->port_fn_bridge_offload_get || + devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_PHYSICAL) + return 0; + + devlink_port->ops->port_fn_bridge_offload_get(devlink_port, &is_enable); + + devlink_port_fn_cap_fill(caps, DEVLINK_PORT_FN_CAP_BRIDGE_OFFLOAD, is_enable); + return 0; +} + static int devlink_port_fn_caps_fill(struct devlink_port *devlink_port, struct sk_buff *msg, struct netlink_ext_ack *extack, @@ -172,6 +187,10 @@ static int devlink_port_fn_caps_fill(struct devlink_port *devlink_port, if (err) return err; + err = devlink_port_bridge_offload_fill(devlink_port, &caps); + if (err) + return err; + if (!caps.selector) return 0; err = nla_put_bitfield32(msg, DEVLINK_PORT_FN_ATTR_CAPS, caps.value, @@ -393,6 +412,12 @@ devlink_port_fn_ipsec_packet_set(struct devlink_port *devlink_port, bool enable, return devlink_port->ops->port_fn_ipsec_packet_set(devlink_port, enable, extack); } +static void +devlink_port_fn_bridge_offload_set(struct devlink_port *devlink_port, bool enable) +{ + return devlink_port->ops->port_fn_bridge_offload_set(devlink_port, enable); +} + static int devlink_port_fn_caps_set(struct devlink_port *devlink_port, const struct nlattr *attr, struct netlink_ext_ack *extack) @@ -431,6 +456,10 @@ static int devlink_port_fn_caps_set(struct devlink_port *devlink_port, if (err) return err; } + if (caps.selector & DEVLINK_PORT_FN_CAP_BRIDGE_OFFLOAD) { + devlink_port_fn_bridge_offload_set(devlink_port, caps_value & + DEVLINK_PORT_FN_CAP_BRIDGE_OFFLOAD); + } return 0; } @@ -765,6 +794,18 @@ static int devlink_port_function_validate(struct devlink_port *devlink_port, return -EOPNOTSUPP; } } + if (caps.selector & DEVLINK_PORT_FN_CAP_BRIDGE_OFFLOAD) { + if (!ops->port_fn_bridge_offload_set) { + NL_SET_ERR_MSG_ATTR(extack, attr, + "Port doesn't support bridge offload function attribute"); + return -EOPNOTSUPP; + } + if (devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_PHYSICAL) { + NL_SET_ERR_MSG_ATTR(extack, attr, + "bridge offload function attribute supported for physical ports only"); + return -EOPNOTSUPP; + } + } } if (tb[DEVLINK_PORT_FN_ATTR_MAX_IO_EQS] && !ops->port_fn_max_io_eqs_set) { From patchwork Mon Nov 11 01:32:17 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aryan Srivastava X-Patchwork-Id: 13870140 X-Patchwork-Delegate: kuba@kernel.org Received: from gate2.alliedtelesis.co.nz (gate2.alliedtelesis.co.nz [202.36.163.20]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7645822EED for ; Mon, 11 Nov 2024 01:32:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=202.36.163.20 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731288760; cv=none; b=qehdzVe/1E1M0qa82/amwRAyZcOggmYp/Vtbq+ujsRylGECIjN1yNlXet1r2IKsPmWDlvWYjqZXRhOI+0sgT2ueMKin0tPE6ZcXk2CSz+B5HHibF2n/mbsRdhD3xH42lXwDtxRQAf4tKOorPlJqJrclFcykFI3JbcFM4l4yKh34= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731288760; c=relaxed/simple; bh=GWjzpgXH45K95bMUM20LixJD6wKYYxknr/0q9jOAuXU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=HevZ0aP3d7fl/MDv1djf4ZeubcXrjoe1btGV/FoGyaSbPqQXlNXdeGPegqbHVLEPATmvz4wIR6paFhYVg88quroOMpp3pDPDNdlxlouif1q2mWboYw0SlVXnLJePvor7NMmNE8F0TM/1UYDhNzlV6eVWWRyjjQ0uPQymRVE6U60= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=alliedtelesis.co.nz; spf=pass smtp.mailfrom=alliedtelesis.co.nz; dkim=pass (2048-bit key) header.d=alliedtelesis.co.nz header.i=@alliedtelesis.co.nz header.b=DULgE7Du; arc=none smtp.client-ip=202.36.163.20 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=alliedtelesis.co.nz Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=alliedtelesis.co.nz Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=alliedtelesis.co.nz header.i=@alliedtelesis.co.nz header.b="DULgE7Du" Received: from svr-chch-seg1.atlnz.lc (mmarshal3.atlnz.lc [10.32.18.43]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by gate2.alliedtelesis.co.nz (Postfix) with ESMTPS id 3BE9B2C06BE; Mon, 11 Nov 2024 14:32:31 +1300 (NZDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=alliedtelesis.co.nz; s=mail181024; t=1731288751; bh=vZiZ+3bz/6/Wnjuj2iYX3hKDfgcWmeQhZAMrYtVLEP8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=DULgE7DuEKPdrEah0QBCNxEq0MVW2yOcOkHqXnYnNFaGDJFrY8SjPmctsPxgrWC1a pnWswVBbaf5KJD230vcavDtKPvjG1pLOoe36KqTwhC+V9NeOR8hceVgFQYo35/H8EW 0mFmxLC5+LDzuXWftCw1q9eb5NUU2bs0wvf/ys56SI5V+okKcVCgbT9W/63CC0guYl mBt3h0jCUPrygPDHjkkDOPgrKYwjnU+TaouHIS16X58lKrxva4xQkugrnmYd+sLVxI lcqnap2YYrQPr9OlLwEtYVqBe99Hm2sS9G0Ft6ByXf3cPXhyabm4MmPJyxIkmJHemQ haLL69fkvi2VQ== Received: from pat.atlnz.lc (Not Verified[10.32.16.33]) by svr-chch-seg1.atlnz.lc with Trustwave SEG (v8,2,6,11305) id ; Mon, 11 Nov 2024 14:32:31 +1300 Received: from aryans-dl.ws.atlnz.lc (aryans-dl.ws.atlnz.lc [10.33.22.38]) by pat.atlnz.lc (Postfix) with ESMTP id 10F8513ECD2; Mon, 11 Nov 2024 14:32:31 +1300 (NZDT) Received: by aryans-dl.ws.atlnz.lc (Postfix, from userid 1844) id 110FF2A151C; Mon, 11 Nov 2024 14:32:31 +1300 (NZDT) From: Aryan Srivastava To: Jiri Pirko , Andrew Lunn Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Aryan Srivastava , Vladimir Oltean , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman Subject: [RFC net-next v0 2/2] net: dsa: add option for bridge port HW offload Date: Mon, 11 Nov 2024 14:32:17 +1300 Message-ID: <20241111013218.1491641-3-aryan.srivastava@alliedtelesis.co.nz> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20241111013218.1491641-1-aryan.srivastava@alliedtelesis.co.nz> References: <20241111013218.1491641-1-aryan.srivastava@alliedtelesis.co.nz> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-SEG-SpamProfiler-Analysis: v=2.4 cv=ca1xrWDM c=1 sm=1 tr=0 ts=67315eaf a=KLBiSEs5mFS1a/PbTCJxuA==:117 a=VlfZXiiP6vEA:10 a=sVghOlvp1KO_yCYPZfwA:9 a=3ZKOabzyN94A:10 X-SEG-SpamProfiler-Score: 0 x-atlnz-ls: pat X-Patchwork-Delegate: kuba@kernel.org X-Patchwork-State: RFC Currently the DSA framework will HW offload any bridge port if there is a driver available to support HW offloading. This may not always be the preferred case. In cases where the ports on the switch chip are being used as purely L3 interfaces, it is preferred that every packet hits the CPU. In the case where these ports are added to a bridge, there is a likelihood of packets completely bypassing the CPU and being switched. This scenario will occur when a L3 port is added to bridge with an L2/L3 port, and both ports happen to be attached to the CPU via a switch-chip. This will result in the switch chip bridging traffic in hardware, where in some cases it would be preferred that packets entering the L3 port always hit the CPU, for various userland operations like packet inspection etc. To prevent this, make the DSA framework aware of the devlink port function attr, bridge_offload, and add a matching field to the port struct. Add get/set functions to configure the field, and read the field when adding a port to a bridge in HW. Signed-off-by: Aryan Srivastava --- include/net/dsa.h | 1 + net/dsa/devlink.c | 27 ++++++++++++++++++++++++++- net/dsa/dsa.c | 1 + net/dsa/port.c | 3 ++- 4 files changed, 30 insertions(+), 2 deletions(-) diff --git a/include/net/dsa.h b/include/net/dsa.h index 72ae65e7246a..32ed8b36f06b 100644 --- a/include/net/dsa.h +++ b/include/net/dsa.h @@ -291,6 +291,7 @@ struct dsa_port { struct device_node *dn; unsigned int ageing_time; + bool bridge_offloading; struct dsa_bridge *bridge; struct devlink_port devlink_port; diff --git a/net/dsa/devlink.c b/net/dsa/devlink.c index f41f9fc2194e..dc98e5311921 100644 --- a/net/dsa/devlink.c +++ b/net/dsa/devlink.c @@ -298,6 +298,31 @@ void dsa_devlink_region_destroy(struct devlink_region *region) } EXPORT_SYMBOL_GPL(dsa_devlink_region_destroy); +static void +dsa_devlink_port_bridge_offload_get(struct devlink_port *dlp, + bool *is_enable) +{ + struct dsa_port *dp = dsa_to_port(dsa_devlink_port_to_ds(dlp), + dsa_devlink_port_to_port(dlp)); + + *is_enable = dp->bridge_offloading; +} + +static void +dsa_devlink_port_bridge_offload_set(struct devlink_port *dlp, + bool enable) +{ + struct dsa_port *dp = dsa_to_port(dsa_devlink_port_to_ds(dlp), + dsa_devlink_port_to_port(dlp)); + + dp->bridge_offloading = enable; +} + +static const struct devlink_port_ops dsa_devlink_port_ops = { + .port_fn_bridge_offload_get = dsa_devlink_port_bridge_offload_get, + .port_fn_bridge_offload_set = dsa_devlink_port_bridge_offload_set, +}; + int dsa_port_devlink_setup(struct dsa_port *dp) { struct devlink_port *dlp = &dp->devlink_port; @@ -341,7 +366,7 @@ int dsa_port_devlink_setup(struct dsa_port *dp) } devlink_port_attrs_set(dlp, &attrs); - err = devlink_port_register(dl, dlp, dp->index); + err = devlink_port_register_with_ops(dl, dlp, dp->index, &dsa_devlink_port_ops); if (err) { if (ds->ops->port_teardown) ds->ops->port_teardown(ds, dp->index); diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c index 5a7c0e565a89..20cf55bd42db 100644 --- a/net/dsa/dsa.c +++ b/net/dsa/dsa.c @@ -529,6 +529,7 @@ static int dsa_port_setup(struct dsa_port *dp) return err; } + dp->bridge_offloading = true; dp->setup = true; return 0; diff --git a/net/dsa/port.c b/net/dsa/port.c index ee0aaec4c8e0..de5908495287 100644 --- a/net/dsa/port.c +++ b/net/dsa/port.c @@ -493,7 +493,8 @@ int dsa_port_bridge_join(struct dsa_port *dp, struct net_device *br, struct net_device *brport_dev; int err; - if (br_mst_enabled(br) && !dsa_port_supports_mst(dp)) + if ((br_mst_enabled(br) && !dsa_port_supports_mst(dp)) || + !dp->bridge_offloading) return -EOPNOTSUPP; /* Here the interface is already bridged. Reflect the current