> You are generating the C files in the end, right? So the code
> shown is what clang gets to compile; or does this come from
> another llvm front end somehow?
yes, we are generating C files, then clang v3.8, then LLVM v4.0. It's
the same compile options used in sample/bpf/Makefile
>
> Also this below looks pretty odd, I'd have expected LLVM to
> either just xor r5 with itself or set it to 0 _once_, and not
> every time it clears some stack mem (oob aside).
>
> [...]
> 78: r5 = 0
> 79: *(u64 *)(r10 - 256) = r5
> 80: r5 = 0
> 81: *(u64 *)(r10 - 264) = r5
> 82: r5 = 0
> 83: *(u64 *)(r10 - 240) = r5
> 84: r5 = 0
> 85: *(u64 *)(r10 - 248) = r5
> 86: r5 = 0
> 87: *(u64 *)(r10 - 224) = r5
> 88: r5 = 0
> 89: *(u64 *)(r10 - 232) = r5
> [...]
>
$(CLANG) \
-D__KERNEL__ -D__ASM_SYSREG_H -Wno-unused-value -Wno-pointer-sign \
-Wno-compare-distinct-pointer-types \
-Wno-gnu-variable-sized-type-not-at-end \
-Wno-tautological-compare \
-O2 -emit-llvm -g -c $< -o -| $(LLC) -O0 -march=bpf -filetype=obj -o $@
Let me try different compiler options, changing "-O" seems to see
something different.
Thanks
--William
>
>>> It seems your prog parses and fills a huge struct on the stack, f.e. eth
>>> dest is filled from
>>> direct packet acces byte by byte (inefficient, but fair enough). The
>>
>>
>> The performance of byte-by-byte load will be bad, but we decide to
>> work on correctness first.
>>
>>> below annotation somehow seems to be off slightly (?), but it's always
>>> patterns like:
>>
>>
>> ya. it is off by 1 line.
>> I do try packing the structure, using
>> #pragma pack(1)
>> but makes no difference.
>>
>> Thanks for your reply~
>> --William
>>
>>>
>>> r1 = *(u8 *)(r2 + 11) ; load byte 1 from pkt into reg (u8)
>>> *(u64 *)(r10 - 408) = r1 ; store byte 1 into stack (u64)
>>>
>>> r1 = *(u8 *)(r2 + 10) ; load byte 2 from pkt into reg (u8)
>>> *(u64 *)(r10 - 416) = r1 ; store byte 2 into stack (u64)
>>>
>>> [...]
>>> ; void* ebpf_packetStart = ((void*)(long)skb->data);
>>> 2: r2 = *(u32 *)(r6 + 0)
>>> [...]
>>> ; hd.ethernet.destination[5] = (u8)((load_byte(ebpf_packetStart,
>>> BYTES(ebpf_packetOffsetInBits) + 5) >> 0));
>>> 9: r1 = *(u8 *)(r2 + 11)
>>> ; hd.ethernet.destination[4] = (u8)((load_byte(ebpf_packetStart,
>>> BYTES(ebpf_packetOffsetInBits) + 4) >> 0));
>>> 10: *(u64 *)(r10 - 408) = r1
>>> 11: r1 = *(u8 *)(r2 + 10)
>>> ; hd.ethernet.destination[3] = (u8)((load_byte(ebpf_packetStart,
>>> BYTES(ebpf_packetOffsetInBits) + 3) >> 0));
>>> 12: *(u64 *)(r10 - 416) = r1
>>> 13: r1 = *(u8 *)(r2 + 9)
>>> ; hd.ethernet.destination[2] = (u8)((load_byte(ebpf_packetStart,
>>> BYTES(ebpf_packetOffsetInBits) + 2) >> 0));
>>> 14: *(u64 *)(r10 - 424) = r1
>>> 15: r1 = *(u8 *)(r2 + 8)
>>> ; hd.ethernet.destination[1] = (u8)((load_byte(ebpf_packetStart,
>>> BYTES(ebpf_packetOffsetInBits) + 1) >> 0));
>>> 16: *(u64 *)(r10 - 432) = r1
>>> 17: r1 = *(u8 *)(r2 + 7)
>>> ; hd.ethernet.destination[0] = (u8)((load_byte(ebpf_packetStart,
>>> BYTES(ebpf_packetOffsetInBits) + 0) >> 0));
>>> 18: *(u64 *)(r10 - 440) = r1
>>> 19: r1 = *(u8 *)(r2 + 6)
>>> [...]
>>>
>>> Despite a struct of:
>>>
>>> struct Ethernet {
>>> char source[6]; /* bit<48> */
>>> char destination[6]; /* bit<48> */
>>> u16 protocol; /* bit<16> */
>>> u8 ebpf_valid;
>>> };
>>>
>>> Maybe packing structs helps a bit (but still shouldn't be such waste,
>>> hmm ...).
>>>
>>>> full C, objdump
>>>> https://gist.github.com/williamtu/5a09b60a951ee5fc062328766403ab4b
>>>> thanks
>>>> _______________________________________________
>>>> iovisor-dev mailing list
>>>> [email protected]
>>>> https://lists.iovisor.org/mailman/listinfo/iovisor-dev
>>>>
>>>
>
_______________________________________________
iovisor-dev mailing list
[email protected]
https://lists.iovisor.org/mailman/listinfo/iovisor-dev