From patchwork Fri Nov 23 16:56:32 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ioana Radulescu X-Patchwork-Id: 1002474 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="MH8IpQ67"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 431jBx2Jg2z9s7T for ; Sat, 24 Nov 2018 03:56:41 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2633128AbeKXDlk (ORCPT ); Fri, 23 Nov 2018 22:41:40 -0500 Received: from mail-eopbgr10064.outbound.protection.outlook.com ([40.107.1.64]:22029 "EHLO EUR02-HE1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S2633119AbeKXDlk (ORCPT ); Fri, 23 Nov 2018 22:41:40 -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=y0/kQ03iDw8huPPBclcRBRxJgv7n+1DqXVFiKHxADDM=; b=MH8IpQ67Q0viFu1l00Sb72lzZdVVxAP9OO80hmoHXHXLd6LS86J981lTwHfQ9Wv3mVrAor4TtYXQwpBivIi6M1UNfyldhi0W+CrUxzVUB3UUEMpdxyJFMBpxy86zl+UXBgsyybpmSAH1lhuJTqwoTk0wn0bwGkl5kGpkMWivT7w= Received: from AM0PR04MB4994.eurprd04.prod.outlook.com (20.177.40.15) by AM0PR04MB5041.eurprd04.prod.outlook.com (20.177.40.146) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1294.27; Fri, 23 Nov 2018 16:56:32 +0000 Received: from AM0PR04MB4994.eurprd04.prod.outlook.com ([fe80::c426:6b56:b6d2:c8f2]) by AM0PR04MB4994.eurprd04.prod.outlook.com ([fe80::c426:6b56:b6d2:c8f2%3]) with mapi id 15.20.1339.030; Fri, 23 Nov 2018 16:56:32 +0000 From: Ioana Ciocoi Radulescu To: "netdev@vger.kernel.org" , "davem@davemloft.net" CC: Ioana Ciornei Subject: [PATCH net-next 1/8] dpaa2-eth: Add basic XDP support Thread-Topic: [PATCH net-next 1/8] dpaa2-eth: Add basic XDP support Thread-Index: AQHUg0186LDqPEUCf0GUGA4wHQ5JDA== Date: Fri, 23 Nov 2018 16:56:32 +0000 Message-ID: <1542992186-26028-2-git-send-email-ruxandra.radulescu@nxp.com> References: <1542992186-26028-1-git-send-email-ruxandra.radulescu@nxp.com> In-Reply-To: <1542992186-26028-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: VI1PR0802CA0024.eurprd08.prod.outlook.com (2603:10a6:800:aa::34) To AM0PR04MB4994.eurprd04.prod.outlook.com (2603:10a6:208:c7::15) 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; AM0PR04MB5041; 6:1IdnKbRbnfmSkMv2Jg+Mr+bO4M5WWjDSvPMZK8PEvqM9pzXpOedZZ4UAUF2HiaGXtq/PGQ3Yda4A5/k5gQcLGNwgTPykuAmImHFMtkugNLlbrQTRVoQO4ntZchelmovwKpFVJ0HX1b/CU3K/dzmdpWA+3n/9vJzeiVg0SFxV2HBEl7eWbu1Coc8oWFdja5h0qo32WuMb9SNthxn/nyZlr7fDl6//F6xboQIEey31jEZY/uGj9u2P3u6pndo6nARnBCbv+NslRZgQPe5pdz0Zc7MrT9rg0lcAquQ83jH8dbhTF6HIcTTFHtwpI3vURhnvQYhpXL9f1c/E1kZRC3VzeM0NLgd8m0SzDXfSYSRaHRz37anJKGgI658pS8cYVyXcetF1V+oCeqmn5RCsW5vWTY1+V7I5wuJLa1pNNDvhEHWjGMzwzbAB0Slu8twVfRV/pEW/Cg9Rsb2Xbuu7z1CTGg==; 5:VL0jbBWQnAJizO5lfmPjI43dPDr5WYcs9Xf0PBI6QKYxDb7AgsZ7thkDidcFx77tf3409qEX+IWW1XlQlFtSYpRxLPSEpQ+3lwrUrzIWdkyER90Z/yG6uGexp4MpeDzOKMpi/tv8rX+wpw5+Y1ZmgoHlv4hLQ+FZJmt6UqlN+dU=; 7:eLyhC9D8K2L0v/N/VChKzpvxNjvQKe7aDI16bRRPjzn0RY6k4BrUZb2fyC/KxFcXWbnt3EM32PhLzmM3NgN3dm43QGbz1nJDAGZfsZedUdjfS0/7g/Btebqi53vrXF7ZzxzO11xd4akNfkYuzjgYCg== x-ms-office365-filtering-correlation-id: 18bbbe10-72ee-4d89-12eb-08d651649ebe 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:AM0PR04MB5041; x-ms-traffictypediagnostic: AM0PR04MB5041: x-microsoft-antispam-prvs: x-exchange-antispam-report-test: UriScan:(185117386973197); x-ms-exchange-senderadcheck: 1 x-exchange-antispam-report-cfa-test: BCL:0; PCL:0; RULEID:(8211001083)(6040522)(2401047)(8121501046)(5005006)(3002001)(3231442)(944501410)(52105112)(93006095)(93001095)(10201501046)(6055026)(148016)(149066)(150057)(6041310)(20161123564045)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123558120)(20161123562045)(20161123560045)(201708071742011)(7699051)(76991095); SRVR:AM0PR04MB5041; BCL:0; PCL:0; RULEID:; SRVR:AM0PR04MB5041; x-forefront-prvs: 086597191B x-forefront-antispam-report: SFV:NSPM; SFS:(10009020)(136003)(346002)(376002)(396003)(39860400002)(366004)(189003)(199004)(68736007)(8676002)(66066001)(81166006)(2616005)(446003)(11346002)(486006)(476003)(2906002)(3846002)(7736002)(6116002)(305945005)(25786009)(110136005)(6486002)(81156014)(14444005)(5024004)(53936002)(316002)(6512007)(478600001)(8936002)(2900100001)(71200400001)(71190400001)(4326008)(5660300001)(86362001)(256004)(186003)(106356001)(52116002)(76176011)(386003)(6436002)(97736004)(102836004)(2501003)(6506007)(105586002)(36756003)(99286004)(26005)(14454004)(309714004); DIR:OUT; SFP:1101; SCL:1; SRVR:AM0PR04MB5041; H:AM0PR04MB4994.eurprd04.prod.outlook.com; FPR:; SPF:None; LANG:en; PTR:InfoNoRecords; MX:1; A:1; received-spf: None (protection.outlook.com: nxp.com does not designate permitted sender hosts) x-microsoft-antispam-message-info: wXzVCafrl/CNIq/5zuS58XpCbjC9/KmU0rgiLHe+dGkchhb6V8TaLqLCrBz/FLgRqWWxIhd8HlST/OSAE6eBALOS79tExpGA4T/Ss3khjLVW4IR0PTEDHI4uJHh+rxVw/P+6oM42oUcAEf5o7KJiE7gMkX33SAG28uqVXK53nND/euEChBuKjEI1z7eYjByQSFRmV7fdRzCQf+QjmntvpTLMTNZRHwhBIh1DZRCwcFgEMSSnDhiw/gS23tH486sGKdsUnq70zsVtAxgEMBy2QKWOqMV5IKn6Bi7295sYhzBcu/vQJhVdBab5PxjhlNWqs5MeQVwPeNhAJhB09ITa6t7gBLBtv/GNs7QHe+RdX2o= spamdiagnosticoutput: 1:99 spamdiagnosticmetadata: NSPM MIME-Version: 1.0 X-OriginatorOrg: nxp.com X-MS-Exchange-CrossTenant-Network-Message-Id: 18bbbe10-72ee-4d89-12eb-08d651649ebe X-MS-Exchange-CrossTenant-originalarrivaltime: 23 Nov 2018 16:56:32.3996 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 686ea1d3-bc2b-4c6f-a92c-d99c5c301635 X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM0PR04MB5041 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 --- drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 182 ++++++++++++++++++++++- drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h | 6 + 2 files changed, 187 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..5340ac9 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,14 @@ 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) + 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 +1474,137 @@ 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); + + return (mfl <= linear_mfl); +} + +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, update_settings; + int i, err; + + if (prog && !xdp_mtu_valid(priv, dev->mtu)) { + netdev_warn(dev, "XDP not supported for MTU %d\n", 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); + update_settings = (!!priv->xdp_prog != !!prog); + + if (up) + dpaa2_eth_stop(dev); + + /* While in xdp mode, enforce a maximum Rx frame size based on MTU */ + if (update_settings) { + 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 +1614,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 \