Итак, в соответствии с заголовком я пытаюсь загрузить программу XDP, когда неожиданно bpf-верификатор начинает выплевывать мне в лицо знаменитую back-edge ошибку:
libbpf: load bpf program failed: Invalid argument
libbpf: -- BEGIN DUMP LOG ---
libbpf:
back-edge from insn 271 to 69
libbpf: -- END LOG --
libbpf: failed to load program 'xdp_prog'
Несмотря на то, что единственный цикл for - с числом итераций, известным во время компиляции - в моем ограниченном коде ebpf C защищен pragma unroll
. Вот фрагмент кода, показывающий задействованный цикл for, определенный в функции __alwais_inline
d:
#pragma unroll
for (i = 0; i < 8; i++)
{
int k = idx + i;
mask = bpf_map_lookup_elem(&a_map, &k);
if (!mask || (mask->an_idx == 0))
return -1;
*m_key = *key;
foo(m_key, mask); // an __alwais_inline func
id = bpf_map_lookup_elem(&b_map, m_key);
if (id)
{
*out_id = *id;
return 0;
}
}
Может быть, проблема в том, что clang не может развернуть цикл? Если это правильно, почему это не помогает, есть ли обходной путь? Недопустимо развертывать цикл вручную, так как это приводит к ужасному, не поддерживаемому и нечитаемому коду.
О, я работаю с:
- ядро 4.19.3
- llvm-clang 8
Есть мысли?
UPDATE
Только что заметил, что даже следующий фиктивный цикл for, похоже, не развернут, поскольку верификатор bpf жалуется на back-edge:
#pragma unroll
for (i = 0; i < 8; i++)
{
int k = i;
mask = bpf_map_lookup_elem(&a_map, &k);
}
Разве только я для этого не имеет никакого смысла?