{"id":834099,"url":"http://patchwork.ozlabs.org/api/1.2/patches/834099/?format=json","web_url":"http://patchwork.ozlabs.org/project/netdev/patch/20171103205630.1083-11-jakub.kicinski@netronome.com/","project":{"id":7,"url":"http://patchwork.ozlabs.org/api/1.2/projects/7/?format=json","name":"Linux network development","link_name":"netdev","list_id":"netdev.vger.kernel.org","list_email":"netdev@vger.kernel.org","web_url":null,"scm_url":null,"webscm_url":null,"list_archive_url":"","list_archive_url_format":"","commit_url_format":""},"msgid":"<20171103205630.1083-11-jakub.kicinski@netronome.com>","list_archive_url":null,"date":"2017-11-03T20:56:25","name":"[net-next,v2,10/15] nfp: bpf: refactor offload logic","commit_ref":null,"pull_url":null,"state":"accepted","archived":true,"hash":"1aa25f2016378e320683648f74bf09b0e32b6cc9","submitter":{"id":67484,"url":"http://patchwork.ozlabs.org/api/1.2/people/67484/?format=json","name":"Jakub Kicinski","email":"jakub.kicinski@netronome.com"},"delegate":{"id":34,"url":"http://patchwork.ozlabs.org/api/1.2/users/34/?format=json","username":"davem","first_name":"David","last_name":"Miller","email":"davem@davemloft.net"},"mbox":"http://patchwork.ozlabs.org/project/netdev/patch/20171103205630.1083-11-jakub.kicinski@netronome.com/mbox/","series":[{"id":11839,"url":"http://patchwork.ozlabs.org/api/1.2/series/11839/?format=json","web_url":"http://patchwork.ozlabs.org/project/netdev/list/?series=11839","date":"2017-11-03T20:56:15","name":"bpf: add offload as a first class citizen","version":2,"mbox":"http://patchwork.ozlabs.org/series/11839/mbox/"}],"comments":"http://patchwork.ozlabs.org/api/patches/834099/comments/","check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/834099/checks/","tags":{},"related":[],"headers":{"Return-Path":"<netdev-owner@vger.kernel.org>","X-Original-To":"patchwork-incoming@ozlabs.org","Delivered-To":"patchwork-incoming@ozlabs.org","Authentication-Results":["ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=vger.kernel.org\n\t(client-ip=209.132.180.67; helo=vger.kernel.org;\n\tenvelope-from=netdev-owner@vger.kernel.org;\n\treceiver=<UNKNOWN>)","ozlabs.org; dkim=pass (2048-bit key;\n\tunprotected) header.d=netronome-com.20150623.gappssmtp.com\n\theader.i=@netronome-com.20150623.gappssmtp.com\n\theader.b=\"M/ql/ELN\"; dkim-atps=neutral"],"Received":["from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id 3yTDmb5Rjlz9s7p\n\tfor <patchwork-incoming@ozlabs.org>;\n\tSat,  4 Nov 2017 07:57:35 +1100 (AEDT)","(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1755960AbdKCU5e (ORCPT <rfc822;patchwork-incoming@ozlabs.org>);\n\tFri, 3 Nov 2017 16:57:34 -0400","from mail-pf0-f196.google.com ([209.85.192.196]:54951 \"EHLO\n\tmail-pf0-f196.google.com\" rhost-flags-OK-OK-OK-OK) by vger.kernel.org\n\twith ESMTP id S1754725AbdKCU4z (ORCPT\n\t<rfc822;netdev@vger.kernel.org>); Fri, 3 Nov 2017 16:56:55 -0400","by mail-pf0-f196.google.com with SMTP id n89so3027172pfk.11\n\tfor <netdev@vger.kernel.org>; Fri, 03 Nov 2017 13:56:55 -0700 (PDT)","from jkicinski-Precision-T1700.netronome.com ([75.53.12.129])\n\tby smtp.gmail.com with ESMTPSA id\n\to10sm9989029pgq.69.2017.11.03.13.56.53\n\t(version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128);\n\tFri, 03 Nov 2017 13:56:53 -0700 (PDT)"],"DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=netronome-com.20150623.gappssmtp.com; s=20150623;\n\th=from:to:cc:subject:date:message-id:in-reply-to:references;\n\tbh=0mMVF3+8LKEWuA1UFgwJblR2pue/dl1yO7apzLlfzIk=;\n\tb=M/ql/ELNkVsKMBiioAdcvH+bNdWmbg12U8HMIt9EAMIY+EWCi41M5NCoX7S2PPQDp+\n\t6B0FsC8VBMXjsnC9lCb49pnrKI4+Z9fm21N19XItAhVuuh8P+6HgceWyumMQJdzo4Lqh\n\tDV8O3/eEWHKg/Kcp2SzS643tl05AXaZLQYHIZPHo09PCs01Kwm2BE50UtHFE3lwuhIZv\n\toSnEbS6DzZcMXxPwbgU8MV/HxsqKNr8rCrMP8ob2DrpchmJyYBD1WDLTCu02R9EJ1SeK\n\tOVmbPzrP7sh1Qx6TaDOlQOTkYvJvrEXtY64L3zFp8kGnx5Sa1X6f3A6qaqM7e3jZwCkG\n\tLZOw==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to\n\t:references;\n\tbh=0mMVF3+8LKEWuA1UFgwJblR2pue/dl1yO7apzLlfzIk=;\n\tb=G9b5arygN1VAr3pA5Ja4Hm1VkJcE98qU1XRUlS7+XbixJVBLlyVGjfFbs5DhZqOk5m\n\tlJxWpc9uIeRdruY0Txm1IaytqZNLdp8jvRxHCSUuJ/l0grIy3Ac8BzMjSRarlil0vjcG\n\tkgH2gdtiDPWUQaqj2kfZm3APEi99/DGyyLlhWZLK7d4q4V8bGnUOOc6X0I0bO76GVGVF\n\t+s6g0b/3+Urtf271x77qYmUo2D9XCh9n68rjV7BcJ0xg1PqRnkzo6n8adwC1ULXILdOm\n\tEmv8c0/LEDV8hzDb3kF5n6LL+ipza24afQ3M6ijaZn0EHlFuR0EuYHZl72e9TR41rclk\n\tp6wA==","X-Gm-Message-State":"AMCzsaUg4xe66PWtulC90W1DvN+FHPEZY4ha9QBrhn8RQ1gKNNONOl25\n\tw+0yDeV38MySQA/BRsPrkRTN+fwl","X-Google-Smtp-Source":"ABhQp+QsFC44RAnN5eHFGobiEAFnZGQCHysu8MYwFQP4iyckcW9myovmmgAJIhwqnZcgrF7gnhUZpw==","X-Received":"by 10.99.135.199 with SMTP id i190mr8306447pge.5.1509742614289; \n\tFri, 03 Nov 2017 13:56:54 -0700 (PDT)","From":"Jakub Kicinski <jakub.kicinski@netronome.com>","To":"netdev@vger.kernel.org","Cc":"oss-drivers@netronome.com, alexei.starovoitov@gmail.com,\n\tdaniel@iogearbox.net, Jakub Kicinski <jakub.kicinski@netronome.com>","Subject":"[PATCH net-next v2 10/15] nfp: bpf: refactor offload logic","Date":"Fri,  3 Nov 2017 13:56:25 -0700","Message-Id":"<20171103205630.1083-11-jakub.kicinski@netronome.com>","X-Mailer":"git-send-email 2.14.1","In-Reply-To":"<20171103205630.1083-1-jakub.kicinski@netronome.com>","References":"<20171103205630.1083-1-jakub.kicinski@netronome.com>","Sender":"netdev-owner@vger.kernel.org","Precedence":"bulk","List-ID":"<netdev.vger.kernel.org>","X-Mailing-List":"netdev@vger.kernel.org"},"content":"We currently create a fake cls_bpf offload object when we want\nto offload XDP.  Simplify and clarify the code by moving the\nTC/XDP specific logic out of common offload code.  This is easy\nnow that we don't support legacy TC actions.  We only need the\nbpf program and state of the skip_sw flag.\n\nTemporarily set @code to NULL in nfp_net_bpf_offload(), compilers\nseem to have trouble recognizing it's always initialized.  Next\npatches will eliminate that variable.\n\nSigned-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>\nReviewed-by: Quentin Monnet <quentin.monnet@netronome.com>\n---\n drivers/net/ethernet/netronome/nfp/bpf/main.c    | 67 +++++++++++-----------\n drivers/net/ethernet/netronome/nfp/bpf/main.h    |  4 +-\n drivers/net/ethernet/netronome/nfp/bpf/offload.c | 73 ++++++++++--------------\n 3 files changed, 67 insertions(+), 77 deletions(-)","diff":"diff --git a/drivers/net/ethernet/netronome/nfp/bpf/main.c b/drivers/net/ethernet/netronome/nfp/bpf/main.c\nindex 2ff97f12c160..9e1286346d42 100644\n--- a/drivers/net/ethernet/netronome/nfp/bpf/main.c\n+++ b/drivers/net/ethernet/netronome/nfp/bpf/main.c\n@@ -54,28 +54,25 @@ static int\n nfp_bpf_xdp_offload(struct nfp_app *app, struct nfp_net *nn,\n \t\t    struct bpf_prog *prog)\n {\n-\tstruct tc_cls_bpf_offload cmd = {\n-\t\t.prog = prog,\n-\t};\n+\tbool running, xdp_running;\n \tint ret;\n \n \tif (!nfp_net_ebpf_capable(nn))\n \t\treturn -EINVAL;\n \n-\tif (nn->dp.ctrl & NFP_NET_CFG_CTRL_BPF) {\n-\t\tif (!nn->dp.bpf_offload_xdp)\n-\t\t\treturn prog ? -EBUSY : 0;\n-\t\tcmd.command = prog ? TC_CLSBPF_REPLACE : TC_CLSBPF_DESTROY;\n-\t} else {\n-\t\tif (!prog)\n-\t\t\treturn 0;\n-\t\tcmd.command = TC_CLSBPF_ADD;\n-\t}\n+\trunning = nn->dp.ctrl & NFP_NET_CFG_CTRL_BPF;\n+\txdp_running = running && nn->dp.bpf_offload_xdp;\n+\n+\tif (!prog && !xdp_running)\n+\t\treturn 0;\n+\tif (prog && running && !xdp_running)\n+\t\treturn -EBUSY;\n \n-\tret = nfp_net_bpf_offload(nn, &cmd);\n+\tret = nfp_net_bpf_offload(nn, prog, running, true);\n \t/* Stop offload if replace not possible */\n-\tif (ret && cmd.command == TC_CLSBPF_REPLACE)\n+\tif (ret && prog)\n \t\tnfp_bpf_xdp_offload(app, nn, NULL);\n+\n \tnn->dp.bpf_offload_xdp = prog && !ret;\n \treturn ret;\n }\n@@ -96,27 +93,33 @@ static int nfp_bpf_setup_tc_block_cb(enum tc_setup_type type,\n {\n \tstruct tc_cls_bpf_offload *cls_bpf = type_data;\n \tstruct nfp_net *nn = cb_priv;\n+\tbool skip_sw;\n+\n+\tif (type != TC_SETUP_CLSBPF ||\n+\t    !tc_can_offload(nn->dp.netdev) ||\n+\t    !nfp_net_ebpf_capable(nn) ||\n+\t    cls_bpf->common.protocol != htons(ETH_P_ALL) ||\n+\t    cls_bpf->common.chain_index)\n+\t\treturn -EOPNOTSUPP;\n+\tif (nn->dp.bpf_offload_xdp)\n+\t\treturn -EBUSY;\n \n-\tif (!tc_can_offload(nn->dp.netdev))\n+\t/* Only support TC direct action */\n+\tif (!cls_bpf->exts_integrated ||\n+\t    tcf_exts_has_actions(cls_bpf->exts)) {\n+\t\tnn_err(nn, \"only direct action with no legacy actions supported\\n\");\n \t\treturn -EOPNOTSUPP;\n+\t}\n \n-\tswitch (type) {\n-\tcase TC_SETUP_CLSBPF:\n-\t\tif (!nfp_net_ebpf_capable(nn) ||\n-\t\t    cls_bpf->common.protocol != htons(ETH_P_ALL) ||\n-\t\t    cls_bpf->common.chain_index)\n-\t\t\treturn -EOPNOTSUPP;\n-\t\tif (nn->dp.bpf_offload_xdp)\n-\t\t\treturn -EBUSY;\n-\n-\t\t/* Only support TC direct action */\n-\t\tif (!cls_bpf->exts_integrated ||\n-\t\t    tcf_exts_has_actions(cls_bpf->exts)) {\n-\t\t\tnn_err(nn, \"only direct action with no legacy actions supported\\n\");\n-\t\t\treturn -EOPNOTSUPP;\n-\t\t}\n-\n-\t\treturn nfp_net_bpf_offload(nn, cls_bpf);\n+\tskip_sw = !!(cls_bpf->gen_flags & TCA_CLS_FLAGS_SKIP_SW);\n+\n+\tswitch (cls_bpf->command) {\n+\tcase TC_CLSBPF_REPLACE:\n+\t\treturn nfp_net_bpf_offload(nn, cls_bpf->prog, true, !skip_sw);\n+\tcase TC_CLSBPF_ADD:\n+\t\treturn nfp_net_bpf_offload(nn, cls_bpf->prog, false, !skip_sw);\n+\tcase TC_CLSBPF_DESTROY:\n+\t\treturn nfp_net_bpf_offload(nn, NULL, true, !skip_sw);\n \tdefault:\n \t\treturn -EOPNOTSUPP;\n \t}\ndiff --git a/drivers/net/ethernet/netronome/nfp/bpf/main.h b/drivers/net/ethernet/netronome/nfp/bpf/main.h\nindex 9f0df6a9786d..6dddab95d57a 100644\n--- a/drivers/net/ethernet/netronome/nfp/bpf/main.h\n+++ b/drivers/net/ethernet/netronome/nfp/bpf/main.h\n@@ -181,8 +181,8 @@ nfp_bpf_jit(struct bpf_prog *filter, void *prog,\n int nfp_prog_verify(struct nfp_prog *nfp_prog, struct bpf_prog *prog);\n \n struct nfp_net;\n-struct tc_cls_bpf_offload;\n \n-int nfp_net_bpf_offload(struct nfp_net *nn, struct tc_cls_bpf_offload *cls_bpf);\n+int nfp_net_bpf_offload(struct nfp_net *nn, struct bpf_prog *prog,\n+\t\t\tbool old_prog, bool sw_fallback);\n \n #endif\ndiff --git a/drivers/net/ethernet/netronome/nfp/bpf/offload.c b/drivers/net/ethernet/netronome/nfp/bpf/offload.c\nindex 268ba1ba82db..c09efa1a9649 100644\n--- a/drivers/net/ethernet/netronome/nfp/bpf/offload.c\n+++ b/drivers/net/ethernet/netronome/nfp/bpf/offload.c\n@@ -52,8 +52,7 @@\n #include \"../nfp_net.h\"\n \n static int\n-nfp_net_bpf_offload_prepare(struct nfp_net *nn,\n-\t\t\t    struct tc_cls_bpf_offload *cls_bpf,\n+nfp_net_bpf_offload_prepare(struct nfp_net *nn, struct bpf_prog *prog,\n \t\t\t    struct nfp_bpf_result *res,\n \t\t\t    void **code, dma_addr_t *dma_addr, u16 max_instr)\n {\n@@ -73,9 +72,9 @@ nfp_net_bpf_offload_prepare(struct nfp_net *nn,\n \tdone_off = nn_readw(nn, NFP_NET_CFG_BPF_DONE);\n \n \tstack_size = nn_readb(nn, NFP_NET_CFG_BPF_STACK_SZ) * 64;\n-\tif (cls_bpf->prog->aux->stack_depth > stack_size) {\n+\tif (prog->aux->stack_depth > stack_size) {\n \t\tnn_info(nn, \"stack too large: program %dB > FW stack %dB\\n\",\n-\t\t\tcls_bpf->prog->aux->stack_depth, stack_size);\n+\t\t\tprog->aux->stack_depth, stack_size);\n \t\treturn -EOPNOTSUPP;\n \t}\n \n@@ -83,8 +82,7 @@ nfp_net_bpf_offload_prepare(struct nfp_net *nn,\n \tif (!*code)\n \t\treturn -ENOMEM;\n \n-\tret = nfp_bpf_jit(cls_bpf->prog, *code, start_off, done_off,\n-\t\t\t  max_instr, res);\n+\tret = nfp_bpf_jit(prog, *code, start_off, done_off, max_instr, res);\n \tif (ret)\n \t\tgoto out;\n \n@@ -96,13 +94,13 @@ nfp_net_bpf_offload_prepare(struct nfp_net *nn,\n }\n \n static void\n-nfp_net_bpf_load_and_start(struct nfp_net *nn, u32 tc_flags,\n+nfp_net_bpf_load_and_start(struct nfp_net *nn, bool sw_fallback,\n \t\t\t   void *code, dma_addr_t dma_addr,\n \t\t\t   unsigned int code_sz, unsigned int n_instr)\n {\n \tint err;\n \n-\tnn->dp.bpf_offload_skip_sw = !!(tc_flags & TCA_CLS_FLAGS_SKIP_SW);\n+\tnn->dp.bpf_offload_skip_sw = !sw_fallback;\n \n \tnn_writew(nn, NFP_NET_CFG_BPF_SIZE, n_instr);\n \tnn_writeq(nn, NFP_NET_CFG_BPF_ADDR, dma_addr);\n@@ -134,7 +132,8 @@ static int nfp_net_bpf_stop(struct nfp_net *nn)\n \treturn nfp_net_reconfig(nn, NFP_NET_CFG_UPDATE_GEN);\n }\n \n-int nfp_net_bpf_offload(struct nfp_net *nn, struct tc_cls_bpf_offload *cls_bpf)\n+int nfp_net_bpf_offload(struct nfp_net *nn, struct bpf_prog *prog,\n+\t\t\tbool old_prog, bool sw_fallback)\n {\n \tstruct nfp_bpf_result res;\n \tdma_addr_t dma_addr;\n@@ -142,49 +141,37 @@ int nfp_net_bpf_offload(struct nfp_net *nn, struct tc_cls_bpf_offload *cls_bpf)\n \tvoid *code;\n \tint err;\n \n+\t/* There is nothing stopping us from implementing seamless\n+\t * replace but the simple method of loading I adopted in\n+\t * the firmware does not handle atomic replace (i.e. we have to\n+\t * stop the BPF offload and re-enable it).  Leaking-in a few\n+\t * frames which didn't have BPF applied in the hardware should\n+\t * be fine if software fallback is available, though.\n+\t */\n+\tif (prog && old_prog && nn->dp.bpf_offload_skip_sw)\n+\t\treturn -EBUSY;\n+\n+\t/* Something else is loaded, different program type? */\n+\tif (!old_prog && nn->dp.ctrl & NFP_NET_CFG_CTRL_BPF)\n+\t\treturn -EBUSY;\n+\n \tmax_instr = nn_readw(nn, NFP_NET_CFG_BPF_MAX_LEN);\n+\tcode = NULL;\n \n-\tswitch (cls_bpf->command) {\n-\tcase TC_CLSBPF_REPLACE:\n-\t\t/* There is nothing stopping us from implementing seamless\n-\t\t * replace but the simple method of loading I adopted in\n-\t\t * the firmware does not handle atomic replace (i.e. we have to\n-\t\t * stop the BPF offload and re-enable it).  Leaking-in a few\n-\t\t * frames which didn't have BPF applied in the hardware should\n-\t\t * be fine if software fallback is available, though.\n-\t\t */\n-\t\tif (nn->dp.bpf_offload_skip_sw)\n-\t\t\treturn -EBUSY;\n-\n-\t\terr = nfp_net_bpf_offload_prepare(nn, cls_bpf, &res, &code,\n+\tif (prog) {\n+\t\terr = nfp_net_bpf_offload_prepare(nn, prog, &res, &code,\n \t\t\t\t\t\t  &dma_addr, max_instr);\n \t\tif (err)\n \t\t\treturn err;\n+\t}\n \n+\tif (old_prog)\n \t\tnfp_net_bpf_stop(nn);\n-\t\tnfp_net_bpf_load_and_start(nn, cls_bpf->gen_flags, code,\n-\t\t\t\t\t   dma_addr, max_instr * sizeof(u64),\n-\t\t\t\t\t   res.n_instr);\n-\t\treturn 0;\n-\n-\tcase TC_CLSBPF_ADD:\n-\t\tif (nn->dp.ctrl & NFP_NET_CFG_CTRL_BPF)\n-\t\t\treturn -EBUSY;\n-\n-\t\terr = nfp_net_bpf_offload_prepare(nn, cls_bpf, &res, &code,\n-\t\t\t\t\t\t  &dma_addr, max_instr);\n-\t\tif (err)\n-\t\t\treturn err;\n \n-\t\tnfp_net_bpf_load_and_start(nn, cls_bpf->gen_flags, code,\n+\tif (prog)\n+\t\tnfp_net_bpf_load_and_start(nn, sw_fallback, code,\n \t\t\t\t\t   dma_addr, max_instr * sizeof(u64),\n \t\t\t\t\t   res.n_instr);\n-\t\treturn 0;\n \n-\tcase TC_CLSBPF_DESTROY:\n-\t\treturn nfp_net_bpf_stop(nn);\n-\n-\tdefault:\n-\t\treturn -EOPNOTSUPP;\n-\t}\n+\treturn 0;\n }\n","prefixes":["net-next","v2","10/15"]}