|
@@ -748,6 +748,17 @@ err_put:
|
|
|
return err;
|
|
|
}
|
|
|
|
|
|
+static void maybe_wait_bpf_programs(struct bpf_map *map)
|
|
|
+{
|
|
|
+ /* Wait for any running BPF programs to complete so that
|
|
|
+ * userspace, when we return to it, knows that all programs
|
|
|
+ * that could be running use the new map value.
|
|
|
+ */
|
|
|
+ if (map->map_type == BPF_MAP_TYPE_HASH_OF_MAPS ||
|
|
|
+ map->map_type == BPF_MAP_TYPE_ARRAY_OF_MAPS)
|
|
|
+ synchronize_rcu();
|
|
|
+}
|
|
|
+
|
|
|
#define BPF_MAP_UPDATE_ELEM_LAST_FIELD flags
|
|
|
|
|
|
static int map_update_elem(union bpf_attr *attr)
|
|
@@ -842,6 +853,7 @@ static int map_update_elem(union bpf_attr *attr)
|
|
|
}
|
|
|
__this_cpu_dec(bpf_prog_active);
|
|
|
preempt_enable();
|
|
|
+ maybe_wait_bpf_programs(map);
|
|
|
out:
|
|
|
free_value:
|
|
|
kfree(value);
|
|
@@ -894,6 +906,7 @@ static int map_delete_elem(union bpf_attr *attr)
|
|
|
rcu_read_unlock();
|
|
|
__this_cpu_dec(bpf_prog_active);
|
|
|
preempt_enable();
|
|
|
+ maybe_wait_bpf_programs(map);
|
|
|
out:
|
|
|
kfree(key);
|
|
|
err_put:
|