Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

bpf: Add bpf_ktime_get_coarse_ns helper

The helper uses CLOCK_MONOTONIC_COARSE source of time that is less
accurate but more performant.

We have a BPF CGROUP_SKB firewall that supports event logging through
bpf_perf_event_output(). Each event has a timestamp and currently we use
bpf_ktime_get_ns() for it. Use of bpf_ktime_get_coarse_ns() saves ~15-20
ns in time required for event logging.

bpf_ktime_get_ns():
EgressLogByRemoteEndpoint 113.82ns 8.79M

bpf_ktime_get_coarse_ns():
EgressLogByRemoteEndpoint 95.40ns 10.48M

Signed-off-by: Dmitrii Banshchikov <me@ubique.spb.ru>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Martin KaFai Lau <kafai@fb.com>
Link: https://lore.kernel.org/bpf/20201117184549.257280-1-me@ubique.spb.ru

authored by

Dmitrii Banshchikov and committed by
Daniel Borkmann
d0551261 ea87ae85

+39
+1
include/linux/bpf.h
··· 1842 1842 extern const struct bpf_func_proto bpf_snprintf_btf_proto; 1843 1843 extern const struct bpf_func_proto bpf_per_cpu_ptr_proto; 1844 1844 extern const struct bpf_func_proto bpf_this_cpu_ptr_proto; 1845 + extern const struct bpf_func_proto bpf_ktime_get_coarse_ns_proto; 1845 1846 1846 1847 const struct bpf_func_proto *bpf_tracing_func_proto( 1847 1848 enum bpf_func_id func_id, const struct bpf_prog *prog);
+11
include/uapi/linux/bpf.h
··· 3797 3797 * is cleared if the flag is not specified. 3798 3798 * Return 3799 3799 * **-EINVAL** if invalid *flags* are passed, zero otherwise. 3800 + * 3801 + * u64 bpf_ktime_get_coarse_ns(void) 3802 + * Description 3803 + * Return a coarse-grained version of the time elapsed since 3804 + * system boot, in nanoseconds. Does not include time the system 3805 + * was suspended. 3806 + * 3807 + * See: **clock_gettime**\ (**CLOCK_MONOTONIC_COARSE**) 3808 + * Return 3809 + * Current *ktime*. 3800 3810 */ 3801 3811 #define __BPF_FUNC_MAPPER(FN) \ 3802 3812 FN(unspec), \ ··· 3969 3959 FN(task_storage_delete), \ 3970 3960 FN(get_current_task_btf), \ 3971 3961 FN(bprm_opts_set), \ 3962 + FN(ktime_get_coarse_ns), \ 3972 3963 /* */ 3973 3964 3974 3965 /* integer value in 'imm' field of BPF_CALL instruction selects which helper
+1
kernel/bpf/core.c
··· 2211 2211 const struct bpf_func_proto bpf_get_numa_node_id_proto __weak; 2212 2212 const struct bpf_func_proto bpf_ktime_get_ns_proto __weak; 2213 2213 const struct bpf_func_proto bpf_ktime_get_boot_ns_proto __weak; 2214 + const struct bpf_func_proto bpf_ktime_get_coarse_ns_proto __weak; 2214 2215 2215 2216 const struct bpf_func_proto bpf_get_current_pid_tgid_proto __weak; 2216 2217 const struct bpf_func_proto bpf_get_current_uid_gid_proto __weak;
+13
kernel/bpf/helpers.c
··· 167 167 .ret_type = RET_INTEGER, 168 168 }; 169 169 170 + BPF_CALL_0(bpf_ktime_get_coarse_ns) 171 + { 172 + return ktime_get_coarse_ns(); 173 + } 174 + 175 + const struct bpf_func_proto bpf_ktime_get_coarse_ns_proto = { 176 + .func = bpf_ktime_get_coarse_ns, 177 + .gpl_only = false, 178 + .ret_type = RET_INTEGER, 179 + }; 180 + 170 181 BPF_CALL_0(bpf_get_current_pid_tgid) 171 182 { 172 183 struct task_struct *task = current; ··· 696 685 return &bpf_ktime_get_ns_proto; 697 686 case BPF_FUNC_ktime_get_boot_ns: 698 687 return &bpf_ktime_get_boot_ns_proto; 688 + case BPF_FUNC_ktime_get_coarse_ns: 689 + return &bpf_ktime_get_coarse_ns_proto; 699 690 case BPF_FUNC_ringbuf_output: 700 691 return &bpf_ringbuf_output_proto; 701 692 case BPF_FUNC_ringbuf_reserve:
+2
kernel/trace/bpf_trace.c
··· 1280 1280 return &bpf_ktime_get_ns_proto; 1281 1281 case BPF_FUNC_ktime_get_boot_ns: 1282 1282 return &bpf_ktime_get_boot_ns_proto; 1283 + case BPF_FUNC_ktime_get_coarse_ns: 1284 + return &bpf_ktime_get_coarse_ns_proto; 1283 1285 case BPF_FUNC_tail_call: 1284 1286 return &bpf_tail_call_proto; 1285 1287 case BPF_FUNC_get_current_pid_tgid:
+11
tools/include/uapi/linux/bpf.h
··· 3797 3797 * is cleared if the flag is not specified. 3798 3798 * Return 3799 3799 * **-EINVAL** if invalid *flags* are passed, zero otherwise. 3800 + * 3801 + * u64 bpf_ktime_get_coarse_ns(void) 3802 + * Description 3803 + * Return a coarse-grained version of the time elapsed since 3804 + * system boot, in nanoseconds. Does not include time the system 3805 + * was suspended. 3806 + * 3807 + * See: **clock_gettime**\ (**CLOCK_MONOTONIC_COARSE**) 3808 + * Return 3809 + * Current *ktime*. 3800 3810 */ 3801 3811 #define __BPF_FUNC_MAPPER(FN) \ 3802 3812 FN(unspec), \ ··· 3969 3959 FN(task_storage_delete), \ 3970 3960 FN(get_current_task_btf), \ 3971 3961 FN(bprm_opts_set), \ 3962 + FN(ktime_get_coarse_ns), \ 3972 3963 /* */ 3973 3964 3974 3965 /* integer value in 'imm' field of BPF_CALL instruction selects which helper