提交 d66f2b91 编写于 作者: J Jakub Kicinski 提交者: David S. Miller

bpf: don't rely on the verifier lock for metadata_dst allocation

bpf_skb_set_tunnel_*() functions require allocation of per-cpu
metadata_dst.  The allocation happens upon verification of the
first program using those helpers.  In preparation for removing
the verifier lock, use cmpxchg() to make sure we only allocate
the metadata_dsts once.
Signed-off-by: NJakub Kicinski <jakub.kicinski@netronome.com>
Reviewed-by: NSimon Horman <simon.horman@netronome.com>
Acked-by: NAlexei Starovoitov <ast@kernel.org>
Acked-by: NDaniel Borkmann <daniel@iogearbox.net>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 c9c35995
...@@ -87,6 +87,7 @@ static inline int skb_metadata_dst_cmp(const struct sk_buff *skb_a, ...@@ -87,6 +87,7 @@ static inline int skb_metadata_dst_cmp(const struct sk_buff *skb_a,
void metadata_dst_free(struct metadata_dst *); void metadata_dst_free(struct metadata_dst *);
struct metadata_dst *metadata_dst_alloc(u8 optslen, enum metadata_type type, struct metadata_dst *metadata_dst_alloc(u8 optslen, enum metadata_type type,
gfp_t flags); gfp_t flags);
void metadata_dst_free_percpu(struct metadata_dst __percpu *md_dst);
struct metadata_dst __percpu * struct metadata_dst __percpu *
metadata_dst_alloc_percpu(u8 optslen, enum metadata_type type, gfp_t flags); metadata_dst_alloc_percpu(u8 optslen, enum metadata_type type, gfp_t flags);
......
...@@ -322,3 +322,19 @@ metadata_dst_alloc_percpu(u8 optslen, enum metadata_type type, gfp_t flags) ...@@ -322,3 +322,19 @@ metadata_dst_alloc_percpu(u8 optslen, enum metadata_type type, gfp_t flags)
return md_dst; return md_dst;
} }
EXPORT_SYMBOL_GPL(metadata_dst_alloc_percpu); EXPORT_SYMBOL_GPL(metadata_dst_alloc_percpu);
void metadata_dst_free_percpu(struct metadata_dst __percpu *md_dst)
{
int cpu;
#ifdef CONFIG_DST_CACHE
for_each_possible_cpu(cpu) {
struct metadata_dst *one_md_dst = per_cpu_ptr(md_dst, cpu);
if (one_md_dst->type == METADATA_IP_TUNNEL)
dst_cache_destroy(&one_md_dst->u.tun_info.dst_cache);
}
#endif
free_percpu(md_dst);
}
EXPORT_SYMBOL_GPL(metadata_dst_free_percpu);
...@@ -43,6 +43,7 @@ ...@@ -43,6 +43,7 @@
#include <linux/timer.h> #include <linux/timer.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <asm/unaligned.h> #include <asm/unaligned.h>
#include <asm/cmpxchg.h>
#include <linux/filter.h> #include <linux/filter.h>
#include <linux/ratelimit.h> #include <linux/ratelimit.h>
#include <linux/seccomp.h> #include <linux/seccomp.h>
...@@ -2987,14 +2988,15 @@ static const struct bpf_func_proto * ...@@ -2987,14 +2988,15 @@ static const struct bpf_func_proto *
bpf_get_skb_set_tunnel_proto(enum bpf_func_id which) bpf_get_skb_set_tunnel_proto(enum bpf_func_id which)
{ {
if (!md_dst) { if (!md_dst) {
/* Race is not possible, since it's called from verifier struct metadata_dst __percpu *tmp;
* that is holding verifier mutex.
*/ tmp = metadata_dst_alloc_percpu(IP_TUNNEL_OPTS_MAX,
md_dst = metadata_dst_alloc_percpu(IP_TUNNEL_OPTS_MAX,
METADATA_IP_TUNNEL, METADATA_IP_TUNNEL,
GFP_KERNEL); GFP_KERNEL);
if (!md_dst) if (!tmp)
return NULL; return NULL;
if (cmpxchg(&md_dst, NULL, tmp))
metadata_dst_free_percpu(tmp);
} }
switch (which) { switch (which) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册