aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/bpf/syscall.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index 4f416234251f..53968f82b919 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -748,6 +748,17 @@ err_put:
748 return err; 748 return err;
749} 749}
750 750
751static void maybe_wait_bpf_programs(struct bpf_map *map)
752{
753 /* Wait for any running BPF programs to complete so that
754 * userspace, when we return to it, knows that all programs
755 * that could be running use the new map value.
756 */
757 if (map->map_type == BPF_MAP_TYPE_HASH_OF_MAPS ||
758 map->map_type == BPF_MAP_TYPE_ARRAY_OF_MAPS)
759 synchronize_rcu();
760}
761
751#define BPF_MAP_UPDATE_ELEM_LAST_FIELD flags 762#define BPF_MAP_UPDATE_ELEM_LAST_FIELD flags
752 763
753static int map_update_elem(union bpf_attr *attr) 764static int map_update_elem(union bpf_attr *attr)
@@ -842,6 +853,7 @@ static int map_update_elem(union bpf_attr *attr)
842 } 853 }
843 __this_cpu_dec(bpf_prog_active); 854 __this_cpu_dec(bpf_prog_active);
844 preempt_enable(); 855 preempt_enable();
856 maybe_wait_bpf_programs(map);
845out: 857out:
846free_value: 858free_value:
847 kfree(value); 859 kfree(value);
@@ -894,6 +906,7 @@ static int map_delete_elem(union bpf_attr *attr)
894 rcu_read_unlock(); 906 rcu_read_unlock();
895 __this_cpu_dec(bpf_prog_active); 907 __this_cpu_dec(bpf_prog_active);
896 preempt_enable(); 908 preempt_enable();
909 maybe_wait_bpf_programs(map);
897out: 910out:
898 kfree(key); 911 kfree(key);
899err_put: 912err_put: