From: Jiri Olsa <jolsa@kernel.org>
To: Alexei Starovoitov <ast@kernel.org>,
Daniel Borkmann <daniel@iogearbox.net>
Cc: netdev@vger.kernel.org, bpf@vger.kernel.org,
Andrii Nakryiko <andriin@fb.com>, Yonghong Song <yhs@fb.com>,
Martin KaFai Lau <kafai@fb.com>,
Jakub Kicinski <jakub.kicinski@netronome.com>,
David Miller <davem@redhat.com>
Subject: [PATCH 5/5] bpf: Allow to resolve bpf trampoline in unwind
Date: Sun, 29 Dec 2019 15:37:40 +0100 [thread overview]
Message-ID: <20191229143740.29143-6-jolsa@kernel.org> (raw)
In-Reply-To: <20191229143740.29143-1-jolsa@kernel.org>
When unwinding the stack we need to identify each
address to successfully continue. Adding latch tree
to keep trampolines for quick lookup during the
unwind.
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
include/linux/bpf.h | 6 ++++++
kernel/bpf/core.c | 2 ++
kernel/bpf/trampoline.c | 35 +++++++++++++++++++++++++++++++++++
3 files changed, 43 insertions(+)
diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index b14e51d56a82..66825c821ac9 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -470,6 +470,7 @@ struct bpf_trampoline {
/* Executable image of trampoline */
void *image;
u64 selector;
+ struct latch_tree_node tnode;
};
#define BPF_DISPATCHER_MAX 48 /* Fits in 2048B */
@@ -502,6 +503,7 @@ struct bpf_trampoline *bpf_trampoline_lookup(u64 key);
int bpf_trampoline_link_prog(struct bpf_prog *prog);
int bpf_trampoline_unlink_prog(struct bpf_prog *prog);
void bpf_trampoline_put(struct bpf_trampoline *tr);
+bool is_bpf_trampoline(void *addr);
void *bpf_jit_alloc_exec_page(void);
#define BPF_DISPATCHER_INIT(name) { \
.mutex = __MUTEX_INITIALIZER(name.mutex), \
@@ -555,6 +557,10 @@ static inline void bpf_trampoline_put(struct bpf_trampoline *tr) {}
static inline void bpf_dispatcher_change_prog(struct bpf_dispatcher *d,
struct bpf_prog *from,
struct bpf_prog *to) {}
+static inline bool is_bpf_trampoline(void *addr)
+{
+ return false;
+}
#endif
struct bpf_func_info_aux {
diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
index 29d47aae0dd1..63a515b5aa7b 100644
--- a/kernel/bpf/core.c
+++ b/kernel/bpf/core.c
@@ -704,6 +704,8 @@ bool is_bpf_text_address(unsigned long addr)
rcu_read_lock();
ret = bpf_prog_kallsyms_find(addr) != NULL;
+ if (!ret)
+ ret = is_bpf_trampoline((void*) addr);
rcu_read_unlock();
return ret;
diff --git a/kernel/bpf/trampoline.c b/kernel/bpf/trampoline.c
index 505f4e4b31d2..4b5f0d0b0072 100644
--- a/kernel/bpf/trampoline.c
+++ b/kernel/bpf/trampoline.c
@@ -4,16 +4,44 @@
#include <linux/bpf.h>
#include <linux/filter.h>
#include <linux/ftrace.h>
+#include <linux/rbtree_latch.h>
/* btf_vmlinux has ~22k attachable functions. 1k htab is enough. */
#define TRAMPOLINE_HASH_BITS 10
#define TRAMPOLINE_TABLE_SIZE (1 << TRAMPOLINE_HASH_BITS)
static struct hlist_head trampoline_table[TRAMPOLINE_TABLE_SIZE];
+static struct latch_tree_root tree __cacheline_aligned;
/* serializes access to trampoline_table */
static DEFINE_MUTEX(trampoline_mutex);
+static __always_inline bool tree_less(struct latch_tree_node *a,
+ struct latch_tree_node *b)
+{
+ struct bpf_trampoline *ta = container_of(a, struct bpf_trampoline, tnode);
+ struct bpf_trampoline *tb = container_of(b, struct bpf_trampoline, tnode);
+
+ return ta->image < tb->image;
+}
+
+static __always_inline int tree_comp(void *addr, struct latch_tree_node *n)
+{
+ struct bpf_trampoline *tr = container_of(n, struct bpf_trampoline, tnode);
+
+ if (addr < tr->image)
+ return -1;
+ if (addr >= tr->image + PAGE_SIZE)
+ return 1;
+
+ return 0;
+}
+
+static const struct latch_tree_ops tree_ops = {
+ .less = tree_less,
+ .comp = tree_comp,
+};
+
void *bpf_jit_alloc_exec_page(void)
{
void *image;
@@ -30,6 +58,11 @@ void *bpf_jit_alloc_exec_page(void)
return image;
}
+bool is_bpf_trampoline(void *addr)
+{
+ return latch_tree_find(addr, &tree, &tree_ops) != NULL;
+}
+
struct bpf_trampoline *bpf_trampoline_lookup(u64 key)
{
struct bpf_trampoline *tr;
@@ -65,6 +98,7 @@ struct bpf_trampoline *bpf_trampoline_lookup(u64 key)
for (i = 0; i < BPF_TRAMP_MAX; i++)
INIT_HLIST_HEAD(&tr->progs_hlist[i]);
tr->image = image;
+ latch_tree_insert(&tr->tnode, &tree, &tree_ops);
out:
mutex_unlock(&trampoline_mutex);
return tr;
@@ -252,6 +286,7 @@ void bpf_trampoline_put(struct bpf_trampoline *tr)
goto out;
bpf_jit_free_exec(tr->image);
hlist_del(&tr->hlist);
+ latch_tree_erase(&tr->tnode, &tree, &tree_ops);
kfree(tr);
out:
mutex_unlock(&trampoline_mutex);
--
2.21.1
next prev parent reply other threads:[~2019-12-29 14:38 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-12-29 14:37 [RFC 0/5] bpf: Add trampoline helpers Jiri Olsa
2019-12-29 14:37 ` [PATCH 1/5] bpf: Allow non struct type for btf ctx access Jiri Olsa
2020-01-06 21:36 ` Yonghong Song
2020-01-07 12:13 ` Jiri Olsa
2020-01-07 15:50 ` Jiri Olsa
2020-01-07 17:55 ` Yonghong Song
2020-01-07 18:28 ` Yonghong Song
2020-01-08 14:38 ` Jiri Olsa
2019-12-29 14:37 ` [PATCH 2/5] bpf: Add bpf_perf_event_output_kfunc Jiri Olsa
2020-01-06 23:27 ` Alexei Starovoitov
2020-01-07 12:25 ` Jiri Olsa
2020-01-07 22:13 ` Alexei Starovoitov
2020-01-08 10:24 ` Jiri Olsa
2019-12-29 14:37 ` [PATCH 3/5] bpf: Add bpf_get_stackid_kfunc Jiri Olsa
2019-12-29 14:37 ` [PATCH 4/5] bpf: Add bpf_get_stack_kfunc Jiri Olsa
2019-12-29 14:37 ` Jiri Olsa [this message]
2020-01-06 23:46 ` [PATCH 5/5] bpf: Allow to resolve bpf trampoline in unwind Alexei Starovoitov
2020-01-07 8:30 ` Daniel Borkmann
2020-01-07 13:15 ` Jiri Olsa
2020-01-07 19:30 ` Daniel Borkmann
2020-01-07 13:05 ` Jiri Olsa
2020-01-07 13:30 ` Björn Töpel
2020-01-13 9:43 ` Jiri Olsa
2020-01-13 12:21 ` Björn Töpel
2020-01-13 12:31 ` Björn Töpel
2020-01-13 12:37 ` Jiri Olsa
2020-02-03 19:58 ` Jiri Olsa
2020-02-03 20:27 ` Björn Töpel
2020-02-03 20:45 ` Toke Høiland-Jørgensen
2020-02-04 8:18 ` Jiri Olsa
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=20191229143740.29143-6-jolsa@kernel.org \
--to=jolsa@kernel.org \
--cc=andriin@fb.com \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=davem@redhat.com \
--cc=jakub.kicinski@netronome.com \
--cc=kafai@fb.com \
--cc=netdev@vger.kernel.org \
--cc=yhs@fb.com \
/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).