From patchwork Mon Nov 26 16:27:29 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ioana Radulescu X-Patchwork-Id: 1003316 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=pass (p=none dis=none) header.from=nxp.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=nxp.com header.i=@nxp.com header.b="vxxhjC9i"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 433XQ23qNQz9s3C for ; Tue, 27 Nov 2018 03:27:38 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726778AbeK0DWM (ORCPT ); Mon, 26 Nov 2018 22:22:12 -0500 Received: from mail-eopbgr80084.outbound.protection.outlook.com ([40.107.8.84]:2992 "EHLO EUR04-VI1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726459AbeK0DWM (ORCPT ); Mon, 26 Nov 2018 22:22:12 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nxp.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=mI/Dzg/3WgSv+8mhiXOVs0HJI5gAkhbnGvdFhiV8+5c=; b=vxxhjC9iA70FRbloKnGjuPrI1aDMz92Wgj616AvGtL4WdBiFs+MIyBYIf52Jkqwl4YDl2NO+gixup52k8ZQhxsKm4hww2NAWT6I6RbFoneL/OXxG/4alIRHvz6H3d8MJlOxCBAIA32uhFFhgcXtlh0nfsxZILYCLtYe6TO6XzLg= Received: from AM6PR04MB5000.eurprd04.prod.outlook.com (20.177.33.219) by AM6PR04MB4518.eurprd04.prod.outlook.com (20.176.242.225) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1361.19; Mon, 26 Nov 2018 16:27:29 +0000 Received: from AM6PR04MB5000.eurprd04.prod.outlook.com ([fe80::298c:e496:4be4:3244]) by AM6PR04MB5000.eurprd04.prod.outlook.com ([fe80::298c:e496:4be4:3244%5]) with mapi id 15.20.1361.019; Mon, 26 Nov 2018 16:27:29 +0000 From: Ioana Ciocoi Radulescu To: "netdev@vger.kernel.org" , "davem@davemloft.net" CC: Ioana Ciornei , "dsahern@gmail.com" , Camelia Alexandra Groza Subject: [PATCH v2 net-next 1/8] dpaa2-eth: Add basic XDP support Thread-Topic: [PATCH v2 net-next 1/8] dpaa2-eth: Add basic XDP support Thread-Index: AQHUhaTsVH3p6He7SEyd9Wx9WcYgjA== Date: Mon, 26 Nov 2018 16:27:29 +0000 Message-ID: <1543249591-14563-2-git-send-email-ruxandra.radulescu@nxp.com> References: <1543249591-14563-1-git-send-email-ruxandra.radulescu@nxp.com> In-Reply-To: <1543249591-14563-1-git-send-email-ruxandra.radulescu@nxp.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-clientproxiedby: VI1PR0302CA0012.eurprd03.prod.outlook.com (2603:10a6:800:e9::22) To AM6PR04MB5000.eurprd04.prod.outlook.com (2603:10a6:20b:7::27) authentication-results: spf=none (sender IP is ) smtp.mailfrom=ruxandra.radulescu@nxp.com; x-ms-exchange-messagesentrepresentingtype: 1 x-originating-ip: [86.34.165.90] x-ms-publictraffictype: Email x-microsoft-exchange-diagnostics: 1; AM6PR04MB4518; 6:2KFSMsCMC3UhB1iK3rI2wMc2llEzX2f19+HAOm+EajnkJSj7jhmud7bo8HTU1smEU7VGrXmWX7pToO/uVNZ11GxYtZ+IEIHsZtbY+JCT5hzujyq0xi//64AQUx/ev3zx/LizqPnxZrIiRopip+9q/6QSPus8pCDyCs7Oc9E89U98MRfq2opa75moh1K4kk7JXHZFEYl5+M61gE0tkLSNEaAGDOK5JYenhOMKVbGuu92E/0WkvBXpuinVXBFYcw8zIwsLLHR4jkoPFKCZY6yU2cVCwnunQIOZwd1ye0s6lu03XAErUk5Vd5PsE5+TYDVQ5D8ZfcT4P4x+dpzuWPtkL1bhzArisj2jk5CycA4dHG5uVWoI4B0wLiYv53FIaeDBECiZ5OVhW6BdkIyyQHqnr1zQvcR5CjmOWdrJ0t302owNFI5bAzW8rOImxyY2EXEnbm48cA03KxjV/tHbdMGZNA==; 5:LHD/ISPT8/R8SAab7mshhsSVcZZbnI41GG7S3A2zdTOqBr3muBcllyzyffN8wwVVcUW7FRwYpQjz4pStFxR8GU9PU5rJSp7k6u6UheVG8iYHoC/Pe4ZQhdSPvQTK5Sz7h2op8NViWlxM/oBDaz/rER9FJ2blOCVoKB+3zD7ZIfQ=; 7:A+gynANFxkXYx7nIfh5IqjlgEfQvKg5cPjYseZ3owzp+6Ui2TYdWm92EYANCfBxAmUoLGwDySw++2SZjvRIZrWWQ9H5nDDxE0sgopaJDfpviPljVHdLlTLNRDTHaDR1KUlrmSM29BzC1iMPJur4wEQ== x-ms-office365-filtering-correlation-id: 26a39bd3-55ba-449b-0701-08d653bc0f41 x-ms-office365-filtering-ht: Tenant x-microsoft-antispam: BCL:0; PCL:0; RULEID:(2390098)(7020095)(4652040)(8989299)(5600074)(711020)(4618075)(4534185)(4627221)(201703031133081)(201702281549075)(8990200)(2017052603328)(7153060)(7193020); SRVR:AM6PR04MB4518; x-ms-traffictypediagnostic: AM6PR04MB4518: x-microsoft-antispam-prvs: x-ms-exchange-senderadcheck: 1 x-exchange-antispam-report-cfa-test: BCL:0; PCL:0; RULEID:(8211001083)(6040522)(2401047)(5005006)(8121501046)(93006095)(93001095)(3002001)(3231443)(944501410)(52105112)(10201501046)(6055026)(148016)(149066)(150057)(6041310)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123558120)(20161123564045)(20161123560045)(20161123562045)(201708071742011)(7699051)(76991095); SRVR:AM6PR04MB4518; BCL:0; PCL:0; RULEID:; SRVR:AM6PR04MB4518; x-forefront-prvs: 086831DFB4 x-forefront-antispam-report: SFV:NSPM; SFS:(10009020)(396003)(366004)(376002)(346002)(136003)(39860400002)(199004)(189003)(86362001)(71200400001)(316002)(54906003)(478600001)(110136005)(66066001)(186003)(2906002)(71190400001)(5660300001)(386003)(7736002)(102836004)(26005)(76176011)(6512007)(256004)(14444005)(52116002)(5024004)(2501003)(99286004)(11346002)(446003)(476003)(486006)(2616005)(6436002)(81156014)(305945005)(105586002)(106356001)(68736007)(14454004)(39060400002)(8676002)(8936002)(81166006)(6486002)(4326008)(6506007)(25786009)(97736004)(6116002)(3846002)(36756003)(53936002)(309714004); DIR:OUT; SFP:1101; SCL:1; SRVR:AM6PR04MB4518; H:AM6PR04MB5000.eurprd04.prod.outlook.com; FPR:; SPF:None; LANG:en; PTR:InfoNoRecords; A:1; MX:1; received-spf: None (protection.outlook.com: nxp.com does not designate permitted sender hosts) x-microsoft-antispam-message-info: w8EJGxUOz+Mc3O5zATOqm9FWMWbtvQbj8hhJqYg1/hfsQUDPxOWEFGlnNcf6GJXJYeTWvF5OqnV56KNQ3EQxkjc3YSKAvaf86wwWA1l559yCs0IzZXSZ0EqgSM7JuusU+Q7qJ1csC0yjcX6oE8HaDZrJe0mKZZmNpNXMryUnv8bKUddjuhPr1SKT2stltjQI68HFZvsiR+pBHO4wKkoZ2+estx1rdGmmD46mpQko+KNIpHqiQIKcli1zk4R9f3j6daqzyVKaG7QJYtXQ7j2QhW17w+2d+4a30aqVNQk8xJcEbH9VWAplPlwD93d4xcQLdppU2BxiXkphb9xRNsnN9xOArdB1HAIGIaXQneYJW0M= spamdiagnosticoutput: 1:99 spamdiagnosticmetadata: NSPM MIME-Version: 1.0 X-OriginatorOrg: nxp.com X-MS-Exchange-CrossTenant-Network-Message-Id: 26a39bd3-55ba-449b-0701-08d653bc0f41 X-MS-Exchange-CrossTenant-originalarrivaltime: 26 Nov 2018 16:27:29.7372 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 686ea1d3-bc2b-4c6f-a92c-d99c5c301635 X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM6PR04MB4518 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org We keep one XDP program reference per channel. The only actions supported for now are XDP_DROP and XDP_PASS. Until now we didn't enforce a maximum size for Rx frames based on MTU value. Change that, since for XDP mode we must ensure no scatter-gather frames can be received. Signed-off-by: Ioana Radulescu Acked-by: Camelia Groza Reviewed-by: David Ahern --- v2: - xdp packets count towards the rx packets and bytes counters - add warning message with the maximum supported MTU value for XDP drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 189 ++++++++++++++++++++++- drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h | 6 + 2 files changed, 194 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c index 640967a..d3cfed4 100644 --- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c +++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c @@ -13,7 +13,8 @@ #include #include #include - +#include +#include #include #include "dpaa2-eth.h" @@ -199,6 +200,45 @@ static struct sk_buff *build_frag_skb(struct dpaa2_eth_priv *priv, return skb; } +static u32 run_xdp(struct dpaa2_eth_priv *priv, + struct dpaa2_eth_channel *ch, + struct dpaa2_fd *fd, void *vaddr) +{ + struct bpf_prog *xdp_prog; + struct xdp_buff xdp; + u32 xdp_act = XDP_PASS; + + rcu_read_lock(); + + xdp_prog = READ_ONCE(ch->xdp.prog); + if (!xdp_prog) + goto out; + + xdp.data = vaddr + dpaa2_fd_get_offset(fd); + xdp.data_end = xdp.data + dpaa2_fd_get_len(fd); + xdp.data_hard_start = xdp.data; + xdp_set_data_meta_invalid(&xdp); + + xdp_act = bpf_prog_run_xdp(xdp_prog, &xdp); + + switch (xdp_act) { + case XDP_PASS: + break; + default: + bpf_warn_invalid_xdp_action(xdp_act); + case XDP_ABORTED: + trace_xdp_exception(priv->net_dev, xdp_prog, xdp_act); + case XDP_DROP: + ch->buf_count--; + free_rx_fd(priv, fd, vaddr); + break; + } + +out: + rcu_read_unlock(); + return xdp_act; +} + /* Main Rx frame processing routine */ static void dpaa2_eth_rx(struct dpaa2_eth_priv *priv, struct dpaa2_eth_channel *ch, @@ -215,6 +255,7 @@ static void dpaa2_eth_rx(struct dpaa2_eth_priv *priv, struct dpaa2_fas *fas; void *buf_data; u32 status = 0; + u32 xdp_act; /* Tracing point */ trace_dpaa2_rx_fd(priv->net_dev, fd); @@ -231,8 +272,17 @@ static void dpaa2_eth_rx(struct dpaa2_eth_priv *priv, percpu_extras = this_cpu_ptr(priv->percpu_extras); if (fd_format == dpaa2_fd_single) { + xdp_act = run_xdp(priv, ch, (struct dpaa2_fd *)fd, vaddr); + if (xdp_act != XDP_PASS) { + percpu_stats->rx_packets++; + percpu_stats->rx_bytes += dpaa2_fd_get_len(fd); + return; + } + skb = build_linear_skb(ch, fd, vaddr); } else if (fd_format == dpaa2_fd_sg) { + WARN_ON(priv->xdp_prog); + skb = build_frag_skb(priv, ch, buf_data); skb_free_frag(vaddr); percpu_extras->rx_sg_frames++; @@ -1427,6 +1477,141 @@ static int dpaa2_eth_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) return -EINVAL; } +static bool xdp_mtu_valid(struct dpaa2_eth_priv *priv, int mtu) +{ + int mfl, linear_mfl; + + mfl = DPAA2_ETH_L2_MAX_FRM(mtu); + linear_mfl = DPAA2_ETH_RX_BUF_SIZE - DPAA2_ETH_RX_HWA_SIZE - + dpaa2_eth_rx_head_room(priv); + + if (mfl > linear_mfl) { + netdev_warn(priv->net_dev, "Maximum MTU for XDP is %d\n", + linear_mfl - VLAN_ETH_HLEN); + return false; + } + + return true; +} + +static int set_rx_mfl(struct dpaa2_eth_priv *priv, int mtu, bool has_xdp) +{ + int mfl, err; + + /* We enforce a maximum Rx frame length based on MTU only if we have + * an XDP program attached (in order to avoid Rx S/G frames). + * Otherwise, we accept all incoming frames as long as they are not + * larger than maximum size supported in hardware + */ + if (has_xdp) + mfl = DPAA2_ETH_L2_MAX_FRM(mtu); + else + mfl = DPAA2_ETH_MFL; + + err = dpni_set_max_frame_length(priv->mc_io, 0, priv->mc_token, mfl); + if (err) { + netdev_err(priv->net_dev, "dpni_set_max_frame_length failed\n"); + return err; + } + + return 0; +} + +static int dpaa2_eth_change_mtu(struct net_device *dev, int new_mtu) +{ + struct dpaa2_eth_priv *priv = netdev_priv(dev); + int err; + + if (!priv->xdp_prog) + goto out; + + if (!xdp_mtu_valid(priv, new_mtu)) + return -EINVAL; + + err = set_rx_mfl(priv, new_mtu, true); + if (err) + return err; + +out: + dev->mtu = new_mtu; + return 0; +} + +static int setup_xdp(struct net_device *dev, struct bpf_prog *prog) +{ + struct dpaa2_eth_priv *priv = netdev_priv(dev); + struct dpaa2_eth_channel *ch; + struct bpf_prog *old; + bool up, need_update; + int i, err; + + if (prog && !xdp_mtu_valid(priv, dev->mtu)) + return -EINVAL; + + if (prog) { + prog = bpf_prog_add(prog, priv->num_channels); + if (IS_ERR(prog)) + return PTR_ERR(prog); + } + + up = netif_running(dev); + need_update = (!!priv->xdp_prog != !!prog); + + if (up) + dpaa2_eth_stop(dev); + + /* While in xdp mode, enforce a maximum Rx frame size based on MTU */ + if (need_update) { + err = set_rx_mfl(priv, dev->mtu, !!prog); + if (err) + goto out_err; + } + + old = xchg(&priv->xdp_prog, prog); + if (old) + bpf_prog_put(old); + + for (i = 0; i < priv->num_channels; i++) { + ch = priv->channel[i]; + old = xchg(&ch->xdp.prog, prog); + if (old) + bpf_prog_put(old); + } + + if (up) { + err = dpaa2_eth_open(dev); + if (err) + return err; + } + + return 0; + +out_err: + if (prog) + bpf_prog_sub(prog, priv->num_channels); + if (up) + dpaa2_eth_open(dev); + + return err; +} + +static int dpaa2_eth_xdp(struct net_device *dev, struct netdev_bpf *xdp) +{ + struct dpaa2_eth_priv *priv = netdev_priv(dev); + + switch (xdp->command) { + case XDP_SETUP_PROG: + return setup_xdp(dev, xdp->prog); + case XDP_QUERY_PROG: + xdp->prog_id = priv->xdp_prog ? priv->xdp_prog->aux->id : 0; + break; + default: + return -EINVAL; + } + + return 0; +} + static const struct net_device_ops dpaa2_eth_ops = { .ndo_open = dpaa2_eth_open, .ndo_start_xmit = dpaa2_eth_tx, @@ -1436,6 +1621,8 @@ static const struct net_device_ops dpaa2_eth_ops = { .ndo_set_rx_mode = dpaa2_eth_set_rx_mode, .ndo_set_features = dpaa2_eth_set_features, .ndo_do_ioctl = dpaa2_eth_ioctl, + .ndo_change_mtu = dpaa2_eth_change_mtu, + .ndo_bpf = dpaa2_eth_xdp, }; static void cdan_cb(struct dpaa2_io_notification_ctx *ctx) diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h index 16545e9..2873a15 100644 --- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h +++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h @@ -283,6 +283,10 @@ struct dpaa2_eth_fq { struct dpaa2_eth_fq_stats stats; }; +struct dpaa2_eth_ch_xdp { + struct bpf_prog *prog; +}; + struct dpaa2_eth_channel { struct dpaa2_io_notification_ctx nctx; struct fsl_mc_device *dpcon; @@ -294,6 +298,7 @@ struct dpaa2_eth_channel { struct dpaa2_eth_priv *priv; int buf_count; struct dpaa2_eth_ch_stats stats; + struct dpaa2_eth_ch_xdp xdp; }; struct dpaa2_eth_dist_fields { @@ -353,6 +358,7 @@ struct dpaa2_eth_priv { u64 rx_hash_fields; struct dpaa2_eth_cls_rule *cls_rules; u8 rx_cls_enabled; + struct bpf_prog *xdp_prog; }; #define DPAA2_RXH_SUPPORTED (RXH_L2DA | RXH_VLAN | RXH_L3_PROTO \