diff options
author | Jarno Rajahalme <jrajahalme@nicira.com> | 2014-08-15 15:09:38 -0700 |
---|---|---|
committer | Jarno Rajahalme <jrajahalme@nicira.com> | 2014-08-15 16:40:14 -0700 |
commit | 84067a4c1a5033ad43ed444d1cb7f40ebddbf2e3 (patch) | |
tree | 288c276366b45b138cdaf3f5eddaae6014358f72 /lib/dpif-netdev.c | |
parent | a6f4ad08d365410a348d0fe0aeb771dbe06b0684 (diff) |
lib/dpif-netdev: Clean-up pmd thread signaling.
It could be possible that the thread misses a signal when it reads the
change_seq again after reload. Also, the counter has no dependent
data, so the memory model for the atomic read can be relaxed.
Signed-off-by: Jarno Rajahalme <jrajahalme@nicira.com>
Acked-by: Pravin B Shelar <pshelar@nicira.com>
Diffstat (limited to 'lib/dpif-netdev.c')
-rw-r--r-- | lib/dpif-netdev.c | 27 |
1 files changed, 14 insertions, 13 deletions
diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index a458f24d4..74012936c 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -297,6 +297,8 @@ struct pmd_thread { atomic_uint change_seq; }; +#define PMD_INITIAL_SEQ 1 + /* Interface to netdev-based datapath. */ struct dpif_netdev { struct dpif dpif; @@ -613,10 +615,10 @@ dp_netdev_reload_pmd_threads(struct dp_netdev *dp) for (i = 0; i < dp->n_pmd_threads; i++) { struct pmd_thread *f = &dp->pmd_threads[i]; - int id; + int old_seq; - atomic_add(&f->change_seq, 1, &id); - } + atomic_add_explicit(&f->change_seq, 1, &old_seq, memory_order_relaxed); + } } static uint32_t @@ -1701,7 +1703,7 @@ pmd_thread_main(void *f_) struct dp_netdev *dp = f->dp; unsigned int lc = 0; struct rxq_poll *poll_list; - unsigned int port_seq; + unsigned int port_seq = PMD_INITIAL_SEQ; int poll_cnt; int i; @@ -1711,10 +1713,8 @@ pmd_thread_main(void *f_) pmd_thread_setaffinity_cpu(f->id); reload: poll_cnt = pmd_load_queues(f, &poll_list, poll_cnt); - atomic_read(&f->change_seq, &port_seq); for (;;) { - unsigned int c_port_seq; int i; for (i = 0; i < poll_cnt; i++) { @@ -1722,14 +1722,15 @@ reload: } if (lc++ > 1024) { - ovsrcu_quiesce(); + unsigned int seq; - /* XXX: need completely userspace based signaling method. - * to keep this thread entirely in userspace. - * For now using atomic counter. */ lc = 0; - atomic_read_explicit(&f->change_seq, &c_port_seq, memory_order_consume); - if (c_port_seq != port_seq) { + + ovsrcu_quiesce(); + + atomic_read_explicit(&f->change_seq, &seq, memory_order_relaxed); + if (seq != port_seq) { + port_seq = seq; break; } } @@ -1806,7 +1807,7 @@ dp_netdev_set_pmd_threads(struct dp_netdev *dp, int n) f->dp = dp; f->id = i; - atomic_store(&f->change_seq, 1); + atomic_init(&f->change_seq, PMD_INITIAL_SEQ); /* Each thread will distribute all devices rx-queues among * themselves. */ |