Merge tag 'x86_mm_for_6.2_v2' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
[linux-block.git] / kernel / bpf / core.c
index b0525ea2527213fac14882149109238512f430b7..6cca66b39d01fa56bdab87e61b8fca31dad4eadb 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/log2.h>
 #include <linux/bpf_verifier.h>
 #include <linux/nodemask.h>
+#include <linux/bpf_mem_alloc.h>
 
 #include <asm/barrier.h>
 #include <asm/unaligned.h>
@@ -60,6 +61,9 @@
 #define CTX    regs[BPF_REG_CTX]
 #define IMM    insn->imm
 
+struct bpf_mem_alloc bpf_global_ma;
+bool bpf_global_ma_set;
+
 /* No hurry in this branch
  *
  * Exported for the bpf jit load helper.
@@ -1030,7 +1034,7 @@ bpf_jit_binary_alloc(unsigned int proglen, u8 **image_ptr,
        hdr->size = size;
        hole = min_t(unsigned int, size - (proglen + sizeof(*hdr)),
                     PAGE_SIZE - sizeof(*hdr));
-       start = prandom_u32_max(hole) & ~(alignment - 1);
+       start = get_random_u32_below(hole) & ~(alignment - 1);
 
        /* Leave a random number of instructions before BPF code. */
        *image_ptr = &hdr->image[start];
@@ -1092,7 +1096,7 @@ bpf_jit_binary_pack_alloc(unsigned int proglen, u8 **image_ptr,
 
        hole = min_t(unsigned int, size - (proglen + sizeof(*ro_header)),
                     BPF_PROG_CHUNK_SIZE - sizeof(*ro_header));
-       start = prandom_u32_max(hole) & ~(alignment - 1);
+       start = get_random_u32_below(hole) & ~(alignment - 1);
 
        *image_ptr = &ro_header->image[start];
        *rw_image = &(*rw_header)->image[start];
@@ -2249,8 +2253,14 @@ static void __bpf_prog_array_free_sleepable_cb(struct rcu_head *rcu)
 {
        struct bpf_prog_array *progs;
 
+       /* If RCU Tasks Trace grace period implies RCU grace period, there is
+        * no need to call kfree_rcu(), just call kfree() directly.
+        */
        progs = container_of(rcu, struct bpf_prog_array, rcu);
-       kfree_rcu(progs, rcu);
+       if (rcu_trace_implies_rcu_gp())
+               kfree(progs);
+       else
+               kfree_rcu(progs, rcu);
 }
 
 void bpf_prog_array_free_sleepable(struct bpf_prog_array *progs)
@@ -2738,6 +2748,18 @@ int __weak bpf_arch_text_invalidate(void *dst, size_t len)
        return -ENOTSUPP;
 }
 
+#ifdef CONFIG_BPF_SYSCALL
+static int __init bpf_global_ma_init(void)
+{
+       int ret;
+
+       ret = bpf_mem_alloc_init(&bpf_global_ma, 0, false);
+       bpf_global_ma_set = !ret;
+       return ret;
+}
+late_initcall(bpf_global_ma_init);
+#endif
+
 DEFINE_STATIC_KEY_FALSE(bpf_stats_enabled_key);
 EXPORT_SYMBOL(bpf_stats_enabled_key);