GCC's -Wall includes -Wsign-compare while clang does not. Since BPF programs are built with clang we need to add this flag explicitly to catch problematic comparisons like: int i = -1; unsigned int j = 1; if (i < j) // this is false. long i = -1; unsigned int j = 1; if (i < j) // this is true. C standard for reference: - If either operand is unsigned long the other shall be converted to unsigned long. - Otherwise, if one operand is a long int and the other unsigned int, then if a long int can represent all the values of an unsigned int, the unsigned int shall be converted to a long int; otherwise both operands shall be converted to unsigned long int. - Otherwise, if either operand is long, the other shall be converted to long. - Otherwise, if either operand is unsigned, the other shall be converted to unsigned. Unfortunately clang's -Wsign-compare is very noisy. It complains about (s32)a == (u32)b which is safe and doen't have surprising behavior. This patch fixes some of the issues. It needs a follow up to fix the rest. Signed-off-by: Alexei Starovoitov <ast@kernel.org> Signed-off-by: Andrii Nakryiko <andrii@kernel.org> Acked-by: Jiri Olsa <jolsa@kernel.org> Acked-by: Kumar Kartikeya Dwivedi <memxor@gmail.com> Link: https://lore.kernel.org/bpf/20231226191148.48536-2-alexei.starovoitov@gmail.com
56 lines
1.1 KiB
C
56 lines
1.1 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
/* Copyright (C) 2023. Huawei Technologies Co., Ltd */
|
|
#include <vmlinux.h>
|
|
#include <bpf/bpf_tracing.h>
|
|
#include <bpf/bpf_helpers.h>
|
|
|
|
#include "bpf_misc.h"
|
|
#include "bpf_experimental.h"
|
|
|
|
struct node_data {
|
|
__u64 data;
|
|
struct bpf_list_node node;
|
|
};
|
|
|
|
struct map_value {
|
|
struct bpf_list_head head __contains(node_data, node);
|
|
struct bpf_spin_lock lock;
|
|
};
|
|
|
|
struct {
|
|
__uint(type, BPF_MAP_TYPE_ARRAY);
|
|
__type(key, int);
|
|
__type(value, struct map_value);
|
|
__uint(max_entries, 1);
|
|
} array SEC(".maps");
|
|
|
|
char _license[] SEC("license") = "GPL";
|
|
|
|
int pid = 0;
|
|
bool done = false;
|
|
|
|
SEC("fentry/" SYS_PREFIX "sys_nanosleep")
|
|
int add_to_list_in_array(void *ctx)
|
|
{
|
|
struct map_value *value;
|
|
struct node_data *new;
|
|
int zero = 0;
|
|
|
|
if (done || (int)bpf_get_current_pid_tgid() != pid)
|
|
return 0;
|
|
|
|
value = bpf_map_lookup_elem(&array, &zero);
|
|
if (!value)
|
|
return 0;
|
|
|
|
new = bpf_obj_new(typeof(*new));
|
|
if (!new)
|
|
return 0;
|
|
|
|
bpf_spin_lock(&value->lock);
|
|
bpf_list_push_back(&value->head, &new->node);
|
|
bpf_spin_unlock(&value->lock);
|
|
done = true;
|
|
|
|
return 0;
|
|
}
|