Re: problems with __sync_add_and_fetch in BPF code

Yonghong Song

On Wed, Jul 18, 2018 at 8:01 AM, Pablo Alvarez via Lists.Iovisor.Org
<> wrote:
Hi Daniel,

Yes. If you look at the bug report, you will see that what it actually
returns is some form of the increment. that is,

__sync_add_and_fetch(myptr, increment)

returns either increment or (increment * 2) (I am not sure which right now)

The fact that other builtins don't compile with LLVM is not too
surprising, given that it's a very restricted subset of C. The fact that
something does compile but then does not produce the promised result...
that's a little more of an issue!

Are there people on this list who have worked on the LLVM BPF compiler?
I might be willing to try to tackle fixing the bug, but I would need
some guidance...

I added the below comment in the bug report:


The table description for bpf_xadd operation is at

// Atomics
class XADD<BPFWidthModifer SizeOp, string OpcodeStr, PatFrag OpNode>
: TYPE_LD_ST<BPF_XADD.Value, SizeOp.Value,
(outs GPR:$dst),
(ins MEMri:$addr, GPR:$val),
"lock *("#OpcodeStr#" *)($addr) += $val",
[(set GPR:$dst, (OpNode ADDRri:$addr, GPR:$val))]> {
bits<4> dst;
bits<20> addr;

let Inst{51-48} = addr{19-16}; // base reg
let Inst{55-52} = dst;
let Inst{47-32} = addr{15-0}; // offset
let BPFClass = BPF_STX;

let Constraints = "$dst = $val" in {
def XADD32 : XADD<BPF_W, "u32", atomic_load_add_32>;
def XADD64 : XADD<BPF_DW, "u64", atomic_load_add_64>;
// undefined def XADD16 : XADD<1, "xadd16", atomic_load_add_16>;
// undefined def XADD8 : XADD<2, "xadd8", atomic_load_add_8>;

Please feel free to take a look how to address this issue.
I can help discussion/review along the way.




Pablo Alvarez

On 07/18/18 09:27, Daniel Zozin wrote:
Hi Pablo,
I'm facing the same problem by compiling and running on kernel 4.15.
Calls to __sync_fetch_and_add keeps returning the same value while the
actual value has been incremented.
Also I add __sync_val_compare_and_swap to your list of primitives
generating compiling errors.

I Investigated a bit but I have no clue on how this can be fixed.


On Wed, Jul 18, 2018 at 1:46 PM, Pablo Alvarez via Lists.Iovisor.Org
<>> wrote:

Hi all,

A while ago, I filed a bug with LLVM about __sync_add_and_fetch as
compiled into eBPF code.

Both it and __sync_fetch_and_add fail to return the correct value of
the item being incremented, returning instead the increment (or
double the increment). This means I end up with race conditions. Has
anyone else run into this, and do you have a workaround for it?

The bug report, sadly, has not been touched by anyone else.


Pablo Alvarez

Daniel Zozin, Dr.
Research Engineer
RiSING - Robust and Secure Distributed Computing
CREATE-NET Research Center
Fondazione Bruno Kessler (FBK)
via alla Cascata 56D
38123 Povo, Trento (Italy)
Tel.: +39 0461 312480
e-mail: d.zozin@... <mailto:d.zozin@...>
GPG KEY: 0x6F66193EC7034588

Le informazioni contenute nella presente comunicazione sono di
natura privata e come tali sono da considerarsi riservate ed
indirizzate esclusivamente ai destinatari indicati e per le finalitĂ 
strettamente legate al relativo contenuto. Se avete ricevuto questo
messaggio per errore, vi preghiamo di eliminarlo e di inviare una
comunicazione all’indirizzo e-mail del mittente.
The information transmitted is intended only for the person or entity to
which it is addressed and may contain confidential and/or privileged
material. If you received this in error, please contact the sender and
delete the material.

Join to automatically receive all group messages.