Commit ed578021 authored by Andrii Nakryiko's avatar Andrii Nakryiko Committed by Alexei Starovoitov

libbpf: Simplify BPF_CORE_READ_BITFIELD_PROBED usage

Streamline BPF_CORE_READ_BITFIELD_PROBED interface to follow
BPF_CORE_READ_BITFIELD (direct) and BPF_CORE_READ, in general, i.e., just
return read result or 0, if underlying bpf_probe_read() failed.

In practice, real applications rarely check bpf_probe_read() result, because
it has to always work or otherwise it's a bug. So propagating internal
bpf_probe_read() error from this macro hurts usability without providing real
benefits in practice. This patch fixes the issue and simplifies usage,
noticeable even in selftest itself.
Signed-off-by: default avatarAndrii Nakryiko <andriin@fb.com>
Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
Acked-by: default avatarYonghong Song <yhs@fb.com>
Link: https://lore.kernel.org/bpf/20191106201500.2582438-1-andriin@fb.com
parent 65a052d5
...@@ -39,32 +39,27 @@ enum bpf_field_info_kind { ...@@ -39,32 +39,27 @@ enum bpf_field_info_kind {
#endif #endif
/* /*
* Extract bitfield, identified by src->field, and put its value into u64 * Extract bitfield, identified by s->field, and return its value as u64.
* *res. All this is done in relocatable manner, so bitfield changes such as * All this is done in relocatable manner, so bitfield changes such as
* signedness, bit size, offset changes, this will be handled automatically. * signedness, bit size, offset changes, this will be handled automatically.
* This version of macro is using bpf_probe_read() to read underlying integer * This version of macro is using bpf_probe_read() to read underlying integer
* storage. Macro functions as an expression and its return type is * storage. Macro functions as an expression and its return type is
* bpf_probe_read()'s return value: 0, on success, <0 on error. * bpf_probe_read()'s return value: 0, on success, <0 on error.
*/ */
#define BPF_CORE_READ_BITFIELD_PROBED(src, field, res) ({ \ #define BPF_CORE_READ_BITFIELD_PROBED(s, field) ({ \
unsigned long long val; \ unsigned long long val = 0; \
\ \
*res = 0; \ __CORE_BITFIELD_PROBE_READ(&val, s, field); \
val = __CORE_BITFIELD_PROBE_READ(res, src, field); \ val <<= __CORE_RELO(s, field, LSHIFT_U64); \
if (!val) { \ if (__CORE_RELO(s, field, SIGNED)) \
*res <<= __CORE_RELO(src, field, LSHIFT_U64); \ val = ((long long)val) >> __CORE_RELO(s, field, RSHIFT_U64); \
val = __CORE_RELO(src, field, RSHIFT_U64); \ else \
if (__CORE_RELO(src, field, SIGNED)) \ val = val >> __CORE_RELO(s, field, RSHIFT_U64); \
*res = ((long long)*res) >> val; \
else \
*res = ((unsigned long long)*res) >> val; \
val = 0; \
} \
val; \ val; \
}) })
/* /*
* Extract bitfield, identified by src->field, and return its value as u64. * Extract bitfield, identified by s->field, and return its value as u64.
* This version of macro is using direct memory reads and should be used from * This version of macro is using direct memory reads and should be used from
* BPF program types that support such functionality (e.g., typed raw * BPF program types that support such functionality (e.g., typed raw
* tracepoints). * tracepoints).
......
...@@ -37,11 +37,6 @@ struct core_reloc_bitfields_output { ...@@ -37,11 +37,6 @@ struct core_reloc_bitfields_output {
int64_t s32; int64_t s32;
}; };
#define TRANSFER_BITFIELD(in, out, field) \
if (BPF_CORE_READ_BITFIELD_PROBED(in, field, &res)) \
return 1; \
out->field = res
SEC("raw_tracepoint/sys_enter") SEC("raw_tracepoint/sys_enter")
int test_core_bitfields(void *ctx) int test_core_bitfields(void *ctx)
{ {
...@@ -49,13 +44,13 @@ int test_core_bitfields(void *ctx) ...@@ -49,13 +44,13 @@ int test_core_bitfields(void *ctx)
struct core_reloc_bitfields_output *out = (void *)&data.out; struct core_reloc_bitfields_output *out = (void *)&data.out;
uint64_t res; uint64_t res;
TRANSFER_BITFIELD(in, out, ub1); out->ub1 = BPF_CORE_READ_BITFIELD_PROBED(in, ub1);
TRANSFER_BITFIELD(in, out, ub2); out->ub2 = BPF_CORE_READ_BITFIELD_PROBED(in, ub2);
TRANSFER_BITFIELD(in, out, ub7); out->ub7 = BPF_CORE_READ_BITFIELD_PROBED(in, ub7);
TRANSFER_BITFIELD(in, out, sb4); out->sb4 = BPF_CORE_READ_BITFIELD_PROBED(in, sb4);
TRANSFER_BITFIELD(in, out, sb20); out->sb20 = BPF_CORE_READ_BITFIELD_PROBED(in, sb20);
TRANSFER_BITFIELD(in, out, u32); out->u32 = BPF_CORE_READ_BITFIELD_PROBED(in, u32);
TRANSFER_BITFIELD(in, out, s32); out->s32 = BPF_CORE_READ_BITFIELD_PROBED(in, s32);
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment