Итак, согласно заголовку, я пытаюсь загрузить программу 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-лязг 8
Какие-нибудь мысли?
ОБНОВЛЕНИЕ
Только что заметил, что даже следующий фиктивный цикл for, кажется, не развернут, а верификатор bpf жалуется на задний край:
#pragma unroll
for (i = 0; i < 8; i++)
{
int k = i;
mask = bpf_map_lookup_elem(&a_map, &k);
}
Это только мне для этого не имеет никакого смысла?
llvm-objdump -S objfile.o
), чтобы убедиться, что задний фронт исходит из этого конкретного цикла? 3) Если вы гибки в версиях ядра, вам может быть интересно узнать, что linux 5.3 (в настоящее время находится в разработке) поддерживает ограниченные циклы. - person Qeole   schedule 03.07.2019bpf_map_lookup_elem
в дереве исходного кода ядра и найдите EINVAL. - person S.S. Anne   schedule 04.07.2019EINVAL
возвращаетсяbpf_map_lookup_elem
, это не будет связано с задним краем? @ pa5h1nh0 Я часто вижу#pragma clang loop unroll(full)
вместо#pragma unroll
, я думал, что разницы нет, но, может, на всякий случай попробовать другой? - person Qeole   schedule 08.07.2019bpf_map_lookup_elem
возвращает указатель, поэтому искать EINVAL для меня нет смысла. Уже попробовал#pragma clang loop unroll(full)
версию, тот же результат, на самом деле в документации clang указано, что эти два слова являются синонимами. Atm Я вручную разворачиваю петлю, что противно, да ладно. - person pa5h1nh0   schedule 08.07.2019