• Alexei Starovoitov's avatar
    bpf: Add map side support for bpf timers. · 68134668
    Alexei Starovoitov authored
    Restrict bpf timers to array, hash (both preallocated and kmalloced), and
    lru map types. The per-cpu maps with timers don't make sense, since 'struct
    bpf_timer' is a part of map value. bpf timers in per-cpu maps would mean that
    the number of timers depends on number of possible cpus and timers would not be
    accessible from all cpus. lpm map support can be added in the future.
    The timers in inner maps are supported.
    
    The bpf_map_update/delete_elem() helpers and sys_bpf commands cancel and free
    bpf_timer in a given map element.
    
    Similar to 'struct bpf_spin_lock' BTF is required and it is used to validate
    that map element indeed contains 'struct bpf_timer'.
    
    Make check_and_init_map_value() init both bpf_spin_lock and bpf_timer when
    map element data is reused in preallocated htab and lru maps.
    
    Teach copy_map_value() to support both bpf_spin_lock and bpf_timer in a single
    map element. There could be one of each, but not more than one. Due to 'one
    bpf_timer in one element' restriction do not support timers in global data,
    since global data is a map of single element, but from bpf program side it's
    seen as many global variables and restriction of single global timer would be
    odd. The sys_bpf map_freeze and sys_mmap syscalls are not allowed on maps with
    timers, since user space could have corrupted mmap element and crashed the
    kernel. The maps with timers cannot be readonly. Due to these restrictions
    search for bpf_timer in datasec BTF in case it was placed in the global data to
    report clear error.
    
    The previous patch allowed 'struct bpf_timer' as a first field in a map
    element only. Relax this restriction.
    
    Refactor lru map to s/bpf_lru_push_free/htab_lru_push_free/ to cancel and free
    the timer when lru map deletes an element as a part of it eviction algorithm.
    
    Make sure that bpf program cannot access 'struct bpf_timer' via direct load/store.
    The timer operation are done through helpers only.
    This is similar to 'struct bpf_spin_lock'.
    Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
    Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
    Acked-by: default avatarYonghong Song <yhs@fb.com>
    Acked-by: default avatarMartin KaFai Lau <kafai@fb.com>
    Acked-by: default avatarAndrii Nakryiko <andrii@kernel.org>
    Acked-by: default avatarToke Høiland-Jørgensen <toke@redhat.com>
    Link: https://lore.kernel.org/bpf/20210715005417.78572-5-alexei.starovoitov@gmail.com
    68134668
btf.c 159 KB