Re: [PATCH bpf-next 1/7] libbpf: add BPF-side of USDT support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




On 2022/3/30 11:10 AM, Hengqi Chen wrote:
> On 2022/3/25 1:29 PM, Andrii Nakryiko wrote:
>> Add BPF-side implementation of libbpf-provided USDT support. This
>> consists of single header library, usdt.bpf.h, which is meant to be used
>> from user's BPF-side source code. This header is added to the list of
>> installed libbpf header, along bpf_helpers.h and others.
>>
>> BPF-side implementation consists of two BPF maps:
>>   - spec map, which contains "a USDT spec" which encodes information

...

>> +}
>> +
>> +/* Fetch USDT argument *arg* (zero-indexed) and put its value into *res.
>> + * Returns 0 on success; negative error, otherwise.
>> + * On error *res is guaranteed to be set to zero.
>> + */
>> +__hidden __weak
>> +int bpf_usdt_arg(struct pt_regs *ctx, int arg, long *res)
>> +{
>> +	struct __bpf_usdt_spec *spec;
>> +	struct __bpf_usdt_arg_spec *arg_spec;
>> +	unsigned long val;
>> +	int err, spec_id;
>> +
>> +	*res = 0;
>> +
>> +	spec_id = __bpf_usdt_spec_id(ctx);
>> +	if (spec_id < 0)
>> +		return -ESRCH;
>> +
>> +	spec = bpf_map_lookup_elem(&__bpf_usdt_specs, &spec_id);
>> +	if (!spec)
>> +		return -ESRCH;
>> +
>> +	if (arg >= spec->arg_cnt)
>> +		return -ENOENT;
>> +
>> +	arg_spec = &spec->args[arg];
>> +	switch (arg_spec->arg_type) {
>> +	case BPF_USDT_ARG_CONST:
>> +		val = arg_spec->val_off;
>> +		break;
>> +	case BPF_USDT_ARG_REG:
>> +		err = bpf_probe_read_kernel(&val, sizeof(val), (void *)ctx + arg_spec->reg_off);
>> +		if (err)
>> +			return err;
>> +		break;
>> +	case BPF_USDT_ARG_REG_DEREF:
>> +		err = bpf_probe_read_kernel(&val, sizeof(val), (void *)ctx + arg_spec->reg_off);
>> +		if (err)
>> +			return err;
>> +		err = bpf_probe_read_user(&val, sizeof(val), (void *)val + arg_spec->val_off);
>> +		if (err)
>> +			return err;

Can you elaborate more on these two probe read call ?

I replace bpf_probe_read_kernel with bpf_probe_read_user, it also works.

Thanks.

>> +		break;
>> +	default:
>> +		return -EINVAL;
>> +	}
>> +
>> +	val <<= arg_spec->arg_bitshift;
>> +	if (arg_spec->arg_signed)
>> +		val = ((long)val) >> arg_spec->arg_bitshift;

>> + * BPF_USDT serves the same purpose for USDT handlers as BPF_PROG for
>> + * tp_btf/fentry/fexit BPF programs and BPF_KPROBE for kprobes.
>> + * Original struct pt_regs * context is preserved as 'ctx' argument.
>> + */
>> +#define BPF_USDT(name, args...)						    \
>> +name(struct pt_regs *ctx);						    \
>> +static __attribute__((always_inline)) typeof(name(0))			    \
>> +____##name(struct pt_regs *ctx, ##args);				    \
>> +typeof(name(0)) name(struct pt_regs *ctx)				    \
>> +{									    \
>> +        _Pragma("GCC diagnostic push")					    \
>> +        _Pragma("GCC diagnostic ignored \"-Wint-conversion\"")		    \
>> +        return ____##name(___bpf_usdt_args(args));			    \
>> +        _Pragma("GCC diagnostic pop")					    \
>> +}									    \
>> +static __attribute__((always_inline)) typeof(name(0))			    \
>> +____##name(struct pt_regs *ctx, ##args)
>> +
>> +#endif /* __USDT_BPF_H__ */



[Index of Archives]     [Linux Samsung SoC]     [Linux Rockchip SoC]     [Linux Actions SoC]     [Linux for Synopsys ARC Processors]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]


  Powered by Linux