aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFlorin Coras <fcoras@cisco.com>2019-03-21 13:54:53 -0700
committerFlorin Coras <fcoras@cisco.com>2019-03-21 13:56:02 -0700
commit4b76112dc43b775abd3deb2d9f65458ca08424ee (patch)
tree1251f033f1162b1ef24be81ed8d6f3d48d8ef1ed
parent192b13f96d6b4d1b4cbbb64a3d447329bf2ba900 (diff)
session/fifo: make event unset atomic
Ensures that fifo cursize loads cannot be speculated to before the event unset. Change-Id: Ia7c20c510d58f26a8e9b82d3982c6d4143a3a4d6 Signed-off-by: Florin Coras <fcoras@cisco.com>
-rw-r--r--src/svm/svm_fifo.h4
-rw-r--r--src/vnet/session/application_interface.h10
2 files changed, 8 insertions, 6 deletions
diff --git a/src/svm/svm_fifo.h b/src/svm/svm_fifo.h
index d7146ae1fb0..6c3940dfad5 100644
--- a/src/svm/svm_fifo.h
+++ b/src/svm/svm_fifo.h
@@ -179,12 +179,12 @@ svm_fifo_set_event (svm_fifo_t * f)
/**
* Unsets fifo event flag.
*
- * Also acts as a release barrier.
+ * Also acts as an acquire barrier.
*/
always_inline void
svm_fifo_unset_event (svm_fifo_t * f)
{
- clib_atomic_release (&f->has_event);
+ __atomic_exchange_n (&f->has_event, 0, __ATOMIC_ACQUIRE);
}
svm_fifo_t *svm_fifo_create (u32 data_size_in_bytes);
diff --git a/src/vnet/session/application_interface.h b/src/vnet/session/application_interface.h
index 56d034e18ed..8323e72e768 100644
--- a/src/vnet/session/application_interface.h
+++ b/src/vnet/session/application_interface.h
@@ -475,9 +475,10 @@ app_send_dgram_raw (svm_fifo_t * f, app_session_transport_t * at,
rv = svm_fifo_enqueue_nowait (f, sizeof (hdr), (u8 *) & hdr);
ASSERT (rv == sizeof (hdr));
- if ((rv = svm_fifo_enqueue_nowait (f, actual_write, data)) > 0)
+ rv = svm_fifo_enqueue_nowait (f, actual_write, data);
+ if (do_evt)
{
- if (do_evt && svm_fifo_set_event (f))
+ if (rv > 0 && svm_fifo_set_event (f))
app_send_io_evt_to_vpp (vpp_evt_q, f->master_session_index, evt_type,
noblock);
}
@@ -499,9 +500,10 @@ app_send_stream_raw (svm_fifo_t * f, svm_msg_q_t * vpp_evt_q, u8 * data,
{
int rv;
- if ((rv = svm_fifo_enqueue_nowait (f, len, data)) > 0)
+ rv = svm_fifo_enqueue_nowait (f, len, data);
+ if (do_evt)
{
- if (do_evt && svm_fifo_set_event (f))
+ if (rv > 0 && svm_fifo_set_event (f))
app_send_io_evt_to_vpp (vpp_evt_q, f->master_session_index, evt_type,
noblock);
}