netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jakub Kicinski <jakub.kicinski@netronome.com>
To: netdev@vger.kernel.org
Cc: ast@kernel.org, daniel@iogearbox.net,
	dinan.gunawardena@netronome.com,
	Jakub Kicinski <jakub.kicinski@netronome.com>
Subject: [RFC 02/12] net: cls_bpf: add hardware offload
Date: Wed,  1 Jun 2016 17:50:04 +0100	[thread overview]
Message-ID: <1464799814-4453-3-git-send-email-jakub.kicinski@netronome.com> (raw)
In-Reply-To: <1464799814-4453-1-git-send-email-jakub.kicinski@netronome.com>

This patch adds hardware offload capability to cls_bpf classifier,
similar to what have been done with U32 and flower.

Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Reviewed-by: Dinan Gunawardena <dgunawardena@netronome.com>
Reviewed-by: Simon Horman <simon.horman@netronome.com>
---
 include/linux/netdevice.h |  2 ++
 include/net/pkt_cls.h     | 14 ++++++++++
 net/sched/cls_bpf.c       | 71 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 87 insertions(+)

diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index f45929ce8157..6c8364b8aae9 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -785,6 +785,7 @@ enum {
 	TC_SETUP_MQPRIO,
 	TC_SETUP_CLSU32,
 	TC_SETUP_CLSFLOWER,
+	TC_SETUP_CLSBPF,
 };
 
 struct tc_cls_u32_offload;
@@ -795,6 +796,7 @@ struct tc_to_netdev {
 		u8 tc;
 		struct tc_cls_u32_offload *cls_u32;
 		struct tc_cls_flower_offload *cls_flower;
+		struct tc_cls_bpf_offload *cls_bpf;
 	};
 };
 
diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h
index 0f7efa88f210..10b7e8cdc98c 100644
--- a/include/net/pkt_cls.h
+++ b/include/net/pkt_cls.h
@@ -438,4 +438,18 @@ struct tc_cls_flower_offload {
 	struct tcf_exts *exts;
 };
 
+enum tc_clsbpf_command {
+	TC_CLSBPF_ADD,
+	TC_CLSBPF_REPLACE,
+	TC_CLSBPF_DESTROY,
+};
+
+struct tc_cls_bpf_offload {
+	enum tc_clsbpf_command command;
+	struct tcf_exts *exts;
+	struct bpf_prog *filter;
+	const char *name;
+	bool exts_integrated;
+};
+
 #endif
diff --git a/net/sched/cls_bpf.c b/net/sched/cls_bpf.c
index 7b342c779da7..b7c4c6dd6ad6 100644
--- a/net/sched/cls_bpf.c
+++ b/net/sched/cls_bpf.c
@@ -39,6 +39,7 @@ struct cls_bpf_prog {
 	struct list_head link;
 	struct tcf_result res;
 	bool exts_integrated;
+	bool offloaded;
 	struct tcf_exts exts;
 	u32 handle;
 	union {
@@ -140,6 +141,72 @@ static bool cls_bpf_is_ebpf(const struct cls_bpf_prog *prog)
 	return !prog->bpf_ops;
 }
 
+static int cls_bpf_offload_cmd(struct tcf_proto *tp, struct cls_bpf_prog *prog,
+			       enum tc_clsbpf_command cmd)
+{
+	struct net_device *dev = tp->q->dev_queue->dev;
+	struct tc_cls_bpf_offload bpf_offload = {};
+	struct tc_to_netdev offload;
+
+	offload.type = TC_SETUP_CLSBPF;
+	offload.cls_bpf = &bpf_offload;
+
+	bpf_offload.command = cmd;
+	bpf_offload.exts = &prog->exts;
+	bpf_offload.filter = prog->filter;
+	bpf_offload.name = prog->bpf_name;
+	bpf_offload.exts_integrated = prog->exts_integrated;
+
+	return dev->netdev_ops->ndo_setup_tc(dev, tp->q->handle,
+					     tp->protocol, &offload);
+}
+
+static void cls_bpf_offload(struct tcf_proto *tp, struct cls_bpf_prog *prog,
+			    struct cls_bpf_prog *oldprog)
+{
+	struct net_device *dev = tp->q->dev_queue->dev;
+	struct cls_bpf_prog *obj = prog;
+	enum tc_clsbpf_command cmd;
+
+	if (oldprog && oldprog->offloaded) {
+		if (tc_should_offload(dev, 0)) {
+			cmd = TC_CLSBPF_REPLACE;
+		} else {
+			obj = oldprog;
+			cmd = TC_CLSBPF_DESTROY;
+		}
+	} else {
+		if (!tc_should_offload(dev, 0))
+			return;
+		cmd = TC_CLSBPF_ADD;
+	}
+
+	if (cls_bpf_offload_cmd(tp, obj, cmd))
+		return;
+
+	obj->offloaded = true;
+	if (oldprog)
+		oldprog->offloaded = false;
+}
+
+static void cls_bpf_stop_offload(struct tcf_proto *tp,
+				 struct cls_bpf_prog *prog)
+{
+	struct net_device *dev = tp->q->dev_queue->dev;
+
+	if (!prog->offloaded)
+		return;
+	if (WARN_ON(!tc_should_offload(dev, 0)))
+		return;
+
+	if (cls_bpf_offload_cmd(tp, prog, TC_CLSBPF_DESTROY)) {
+		pr_err("Stopping hardware offload failed!\n");
+		return;
+	}
+
+	prog->offloaded = false;
+}
+
 static int cls_bpf_init(struct tcf_proto *tp)
 {
 	struct cls_bpf_head *head;
@@ -179,6 +246,7 @@ static int cls_bpf_delete(struct tcf_proto *tp, unsigned long arg)
 {
 	struct cls_bpf_prog *prog = (struct cls_bpf_prog *) arg;
 
+	cls_bpf_stop_offload(tp, prog);
 	list_del_rcu(&prog->link);
 	tcf_unbind_filter(tp, &prog->res);
 	call_rcu(&prog->rcu, __cls_bpf_delete_prog);
@@ -195,6 +263,7 @@ static bool cls_bpf_destroy(struct tcf_proto *tp, bool force)
 		return false;
 
 	list_for_each_entry_safe(prog, tmp, &head->plist, link) {
+		cls_bpf_stop_offload(tp, prog);
 		list_del_rcu(&prog->link);
 		tcf_unbind_filter(tp, &prog->res);
 		call_rcu(&prog->rcu, __cls_bpf_delete_prog);
@@ -415,6 +484,8 @@ static int cls_bpf_change(struct net *net, struct sk_buff *in_skb,
 	if (ret < 0)
 		goto errout;
 
+	cls_bpf_offload(tp, prog, oldprog);
+
 	if (oldprog) {
 		list_replace_rcu(&oldprog->link, &prog->link);
 		tcf_unbind_filter(tp, &oldprog->res);
-- 
1.9.1

  parent reply	other threads:[~2016-06-01 16:51 UTC|newest]

Thread overview: 54+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-06-01 16:50 [RFC 00/12] BPF hardware offload via cls_bpf Jakub Kicinski
2016-06-01 16:50 ` [RFC 01/12] add basic register-field manipulation macros Jakub Kicinski
2016-06-01 20:15   ` Hannes Frederic Sowa
2016-06-01 23:08     ` Jakub Kicinski
2016-06-02 12:01       ` Hannes Frederic Sowa
2016-06-01 16:50 ` Jakub Kicinski [this message]
2016-06-01 17:13   ` [RFC 02/12] net: cls_bpf: add hardware offload John Fastabend
2016-06-01 20:59     ` Jakub Kicinski
2016-06-01 19:34   ` Daniel Borkmann
2016-06-02  7:17   ` Jiri Pirko
2016-06-02 12:07     ` Jakub Kicinski
2016-06-01 16:50 ` [RFC 03/12] net: cls_bpf: limit hardware offload by software-only flag Jakub Kicinski
2016-06-01 17:16   ` John Fastabend
2016-06-01 17:16   ` John Fastabend
2016-06-01 19:40   ` Daniel Borkmann
2016-06-01 21:05     ` Jakub Kicinski
2016-06-01 21:21       ` Daniel Borkmann
2016-06-01 21:26         ` Jakub Kicinski
2016-06-01 21:31           ` Daniel Borkmann
2016-06-02  7:24   ` Jiri Pirko
2016-06-01 16:50 ` [RFC 04/12] net: cls_bpf: add support for marking filters as hardware-only Jakub Kicinski
2016-06-01 17:19   ` John Fastabend
2016-06-01 19:57   ` Daniel Borkmann
2016-06-01 16:50 ` [RFC 05/12] nfp: add BPF to NFP code translator Jakub Kicinski
2016-06-01 20:03   ` Daniel Borkmann
2016-06-01 20:09     ` John Fastabend
2016-06-01 20:15     ` Alexei Starovoitov
2016-06-01 21:23       ` Jakub Kicinski
2016-06-02 16:21       ` John Fastabend
2016-06-01 16:50 ` [RFC 06/12] nfp: add hardware cls_bpf offload Jakub Kicinski
2016-06-01 20:20   ` Daniel Borkmann
2016-06-01 20:52     ` Alexei Starovoitov
2016-06-01 21:15       ` Jakub Kicinski
2016-06-01 21:51         ` Alexei Starovoitov
2016-06-01 21:16       ` Daniel Borkmann
2016-06-01 21:36       ` John Fastabend
2016-06-02  6:57         ` Jiri Pirko
2016-06-02 12:13           ` Jakub Kicinski
2016-06-02 12:30             ` Daniel Borkmann
2016-06-01 23:03   ` Daniel Borkmann
2016-06-01 16:50 ` [RFC 07/12] nfp: add skb mark support to the bpf offload Jakub Kicinski
2016-06-01 21:56   ` Alexei Starovoitov
2016-06-01 22:19     ` Jakub Kicinski
2016-06-01 22:30       ` Daniel Borkmann
2016-06-01 23:01         ` Jakub Kicinski
2016-06-01 16:50 ` [RFC 08/12] net: cls_bpf: allow offloaded filters to update stats Jakub Kicinski
2016-06-01 17:20   ` John Fastabend
2016-06-01 22:09   ` Daniel Borkmann
2016-06-01 16:50 ` [RFC 09/12] nfp: report statistics of offloaded filters Jakub Kicinski
2016-06-01 16:50 ` [RFC 10/12] nfp: bpf: optimize register init Jakub Kicinski
2016-06-01 16:50 ` [RFC 11/12] nfp: bpf: add register rename Jakub Kicinski
2016-06-01 16:50 ` [RFC 12/12] nfp: bpf: add denser mode of execution Jakub Kicinski
2016-06-01 22:01   ` Alexei Starovoitov
2016-06-01 22:47     ` Jakub Kicinski

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1464799814-4453-3-git-send-email-jakub.kicinski@netronome.com \
    --to=jakub.kicinski@netronome.com \
    --cc=ast@kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=dinan.gunawardena@netronome.com \
    --cc=netdev@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).