[Differential] [Commented On] D1833: Add memory barriers to buf_ring

zbb (Zbigniew Bodek) phabric-noreply at FreeBSD.org
Thu Feb 19 18:15:23 UTC 2015


zbb added a comment.

>From W. Macek:

It was observed on ARM Cortex-A15, that sometimes, the buf_ring_dequeue_sc finction returned the old pointer, which left there from the previous buffer ring pass. With this fix, the issue disappeared.

Inside buf_ring_dequeue_sc, after the cons_head is read, the CPU memory access predictors are capable of preloading the values from the memory for the future use - like a br->br_ring[cons_head], for example. However, this value might not be valid. There is a small "hole" in the logic, between line 165 and 166. If the enqueue function puts the new entry to the ring just after the core prefetches the buf = br->br_ring[cons_head] and before the br->br_prod_tail is read, it will return the wrong, old, value. To prevent this, full memmory barrier must be added before reading br->br_ring[cons_head]. However, that change would negatively impact x86, so it's better to use atomic_load_acq_32 on br->br_prod_tail variable: on Intel it will not change anything (except adding compiler barrier), but on ARM it puts a full dmb() after the br->br_prod_tail is read.

As Andrew suggested, the atomic operation was also added to br->br_cons_head variable.

REVISION DETAIL
  https://reviews.freebsd.org/D1833

To: zbb, imp, kmacy, rpaulo
Cc: andrew, ian, adrian, freebsd-arm


More information about the freebsd-arm mailing list