Merge tag 'for-netdev' of https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf...
[linux-2.6-microblaze.git] / kernel / bpf / arraymap.c
index c85ff91..1335867 100644 (file)
@@ -82,7 +82,7 @@ static struct bpf_map *array_map_alloc(union bpf_attr *attr)
        bool percpu = attr->map_type == BPF_MAP_TYPE_PERCPU_ARRAY;
        int numa_node = bpf_map_attr_numa_node(attr);
        u32 elem_size, index_mask, max_entries;
-       bool bypass_spec_v1 = bpf_bypass_spec_v1();
+       bool bypass_spec_v1 = bpf_bypass_spec_v1(NULL);
        u64 array_size, mask64;
        struct bpf_array *array;
 
@@ -867,11 +867,11 @@ int bpf_fd_array_map_update_elem(struct bpf_map *map, struct file *map_file,
        }
 
        if (old_ptr)
-               map->ops->map_fd_put_ptr(old_ptr);
+               map->ops->map_fd_put_ptr(map, old_ptr, true);
        return 0;
 }
 
-static long fd_array_map_delete_elem(struct bpf_map *map, void *key)
+static long __fd_array_map_delete_elem(struct bpf_map *map, void *key, bool need_defer)
 {
        struct bpf_array *array = container_of(map, struct bpf_array, map);
        void *old_ptr;
@@ -890,13 +890,18 @@ static long fd_array_map_delete_elem(struct bpf_map *map, void *key)
        }
 
        if (old_ptr) {
-               map->ops->map_fd_put_ptr(old_ptr);
+               map->ops->map_fd_put_ptr(map, old_ptr, need_defer);
                return 0;
        } else {
                return -ENOENT;
        }
 }
 
+static long fd_array_map_delete_elem(struct bpf_map *map, void *key)
+{
+       return __fd_array_map_delete_elem(map, key, true);
+}
+
 static void *prog_fd_array_get_ptr(struct bpf_map *map,
                                   struct file *map_file, int fd)
 {
@@ -913,8 +918,9 @@ static void *prog_fd_array_get_ptr(struct bpf_map *map,
        return prog;
 }
 
-static void prog_fd_array_put_ptr(void *ptr)
+static void prog_fd_array_put_ptr(struct bpf_map *map, void *ptr, bool need_defer)
 {
+       /* bpf_prog is freed after one RCU or tasks trace grace period */
        bpf_prog_put(ptr);
 }
 
@@ -924,13 +930,13 @@ static u32 prog_fd_array_sys_lookup_elem(void *ptr)
 }
 
 /* decrement refcnt of all bpf_progs that are stored in this map */
-static void bpf_fd_array_map_clear(struct bpf_map *map)
+static void bpf_fd_array_map_clear(struct bpf_map *map, bool need_defer)
 {
        struct bpf_array *array = container_of(map, struct bpf_array, map);
        int i;
 
        for (i = 0; i < array->map.max_entries; i++)
-               fd_array_map_delete_elem(map, &i);
+               __fd_array_map_delete_elem(map, &i, need_defer);
 }
 
 static void prog_array_map_seq_show_elem(struct bpf_map *map, void *key,
@@ -1071,7 +1077,7 @@ static void prog_array_map_clear_deferred(struct work_struct *work)
 {
        struct bpf_map *map = container_of(work, struct bpf_array_aux,
                                           work)->map;
-       bpf_fd_array_map_clear(map);
+       bpf_fd_array_map_clear(map, true);
        bpf_map_put(map);
 }
 
@@ -1151,7 +1157,7 @@ static struct bpf_event_entry *bpf_event_entry_gen(struct file *perf_file,
 {
        struct bpf_event_entry *ee;
 
-       ee = kzalloc(sizeof(*ee), GFP_ATOMIC);
+       ee = kzalloc(sizeof(*ee), GFP_KERNEL);
        if (ee) {
                ee->event = perf_file->private_data;
                ee->perf_file = perf_file;
@@ -1201,8 +1207,9 @@ err_out:
        return ee;
 }
 
-static void perf_event_fd_array_put_ptr(void *ptr)
+static void perf_event_fd_array_put_ptr(struct bpf_map *map, void *ptr, bool need_defer)
 {
+       /* bpf_perf_event is freed after one RCU grace period */
        bpf_event_entry_free_rcu(ptr);
 }
 
@@ -1220,7 +1227,7 @@ static void perf_event_fd_array_release(struct bpf_map *map,
        for (i = 0; i < array->map.max_entries; i++) {
                ee = READ_ONCE(array->ptrs[i]);
                if (ee && ee->map_file == map_file)
-                       fd_array_map_delete_elem(map, &i);
+                       __fd_array_map_delete_elem(map, &i, true);
        }
        rcu_read_unlock();
 }
@@ -1228,7 +1235,7 @@ static void perf_event_fd_array_release(struct bpf_map *map,
 static void perf_event_fd_array_map_free(struct bpf_map *map)
 {
        if (map->map_flags & BPF_F_PRESERVE_ELEMS)
-               bpf_fd_array_map_clear(map);
+               bpf_fd_array_map_clear(map, false);
        fd_array_map_free(map);
 }
 
@@ -1256,7 +1263,7 @@ static void *cgroup_fd_array_get_ptr(struct bpf_map *map,
        return cgroup_get_from_fd(fd);
 }
 
-static void cgroup_fd_array_put_ptr(void *ptr)
+static void cgroup_fd_array_put_ptr(struct bpf_map *map, void *ptr, bool need_defer)
 {
        /* cgroup_put free cgrp after a rcu grace period */
        cgroup_put(ptr);
@@ -1264,7 +1271,7 @@ static void cgroup_fd_array_put_ptr(void *ptr)
 
 static void cgroup_fd_array_free(struct bpf_map *map)
 {
-       bpf_fd_array_map_clear(map);
+       bpf_fd_array_map_clear(map, false);
        fd_array_map_free(map);
 }
 
@@ -1309,7 +1316,7 @@ static void array_of_map_free(struct bpf_map *map)
         * is protected by fdget/fdput.
         */
        bpf_map_meta_free(map->inner_map_meta);
-       bpf_fd_array_map_clear(map);
+       bpf_fd_array_map_clear(map, false);
        fd_array_map_free(map);
 }