platform/linux-generic/odp_packet_socket.c:

static inline void mmap_rx_user_ready(struct tpacket2_hdr *hdr)
{
        hdr->tp_status = TP_STATUS_KERNEL;
        __sync_synchronize();
}

static inline void mmap_tx_user_ready(struct tpacket2_hdr *hdr)
{
        hdr->tp_status = TP_STATUS_SEND_REQUEST;
        __sync_synchronize();
}

Why are there calls to __sync_synchronize() (i.e. full HW and compiler
barrier) here?

If we are releasing something (which typically associated with a store
to a shared flag), the barrier should come *before* the store (so to
separate accesses to the shared data from the store to the shared flag
which releases the data), not after. If the barrier is after the
store(s), the store to the shared flag could actually be visible
before the stores to the shared data (e.g. the packet to transmit).

I don't think this code is actually sharing data with other threads
without any (other) synchronization. A bit further down, there is a
call to sendto() which informs the kernel of the updated data. Or is
this system call just an optimization (look at my data now!) or is it
necessary for the kernel to have a look at the data? Is there always a
corresponding call to recvfrom() before RX data is accessed?

A system call (ARM SWI instruction) causes an (SWI) exception and
exceptions are implicit barriers (DSB, wait for all previous memory
accesses to complete) to my best knowledge. You don't want exceptions
caused by user space memory accesses to occur in kernel space.

If you are using explicit barriers, you are probably doing it wrong.

-- Ola

_______________________________________________
lng-odp mailing list
lng-odp@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/lng-odp

Reply via email to