|
@@ -43,6 +43,7 @@
|
|
|
#include <linux/timer.h>
|
|
|
#include <linux/uaccess.h>
|
|
|
#include <asm/unaligned.h>
|
|
|
+#include <asm/cmpxchg.h>
|
|
|
#include <linux/filter.h>
|
|
|
#include <linux/ratelimit.h>
|
|
|
#include <linux/seccomp.h>
|
|
@@ -2987,14 +2988,15 @@ static const struct bpf_func_proto *
|
|
|
bpf_get_skb_set_tunnel_proto(enum bpf_func_id which)
|
|
|
{
|
|
|
if (!md_dst) {
|
|
|
- /* Race is not possible, since it's called from verifier
|
|
|
- * that is holding verifier mutex.
|
|
|
- */
|
|
|
- md_dst = metadata_dst_alloc_percpu(IP_TUNNEL_OPTS_MAX,
|
|
|
- METADATA_IP_TUNNEL,
|
|
|
- GFP_KERNEL);
|
|
|
- if (!md_dst)
|
|
|
+ struct metadata_dst __percpu *tmp;
|
|
|
+
|
|
|
+ tmp = metadata_dst_alloc_percpu(IP_TUNNEL_OPTS_MAX,
|
|
|
+ METADATA_IP_TUNNEL,
|
|
|
+ GFP_KERNEL);
|
|
|
+ if (!tmp)
|
|
|
return NULL;
|
|
|
+ if (cmpxchg(&md_dst, NULL, tmp))
|
|
|
+ metadata_dst_free_percpu(tmp);
|
|
|
}
|
|
|
|
|
|
switch (which) {
|