[ovs-dev] [PATCH] ofproto-dpif-upcall: reduce number of wakeup
Zhou, Han
hzhou8 at ebay.com
Fri Nov 29 06:59:01 UTC 2013
Hi,
On Wed, Sep 25, 2013 at 01:38:58PM +0900, YAMAMOTO Takashi wrote:
> if a queue length is long (ie. non-0), the consumer thread should
> already be busy working on the queue. there's no need to wake it
> up repeatedly.
...
> @@ -530,9 +532,13 @@ recv_upcalls(struct udpif *udpif)
> ovs_mutex_lock(&handler->mutex);
> if (handler->n_upcalls < MAX_QUEUE_LENGTH) {
> list_push_back(&handler->upcalls, &upcall->list_node);
> - handler->n_new_upcalls = ++handler->n_upcalls;
> -
> - if (handler->n_new_upcalls >= FLOW_MISS_MAX_BATCH) {
> + if (handler->n_upcalls == 0) {
> + handler->need_signal = true;
Wakeup is not needed when n_upcalls == 0, but only when n_upcalls > 0.
This is not an issue for the "batch" loop, but has problem for the final
xpthread_cond_signal() at the end of this function:
> @@ -555,8 +561,8 @@ recv_upcalls(struct udpif *udpif)
> for (n = 0; n < udpif->n_handlers; ++n) {
> struct handler *handler = &udpif->handlers[n];
>
> - if (handler->n_new_upcalls) {
> - handler->n_new_upcalls = 0;
> + if (handler->need_signal) {
Here is the problem. need_signal is true even when n_upcalls is 0, and
Still do the wakeup! I had a test that in massive flow setup scenario the
miss_handler threads are still woken up by this final wakeup when there
is only 1 or 2 upcalls, instead of the "batch" wakeup, because dpif_recv()
returns EAGAIN (i.e., the n_upcalls rarely reach the batch size 50). This
condition change from "if (handler->n_new_upcalls)" to
"if (handler->need_signal) just make things worse: there were already
too frequent wakeups and now more of them when there is no upcalls ...
> + handler->need_signal = false;
> ovs_mutex_lock(&handler->mutex);
> xpthread_cond_signal(&handler->wake_cond);
> ovs_mutex_unlock(&handler->mutex);
In addition, in miss_handler code it is "if" condition instead of "while" loop
when checking against the condition n_upcalls for ovs_mutex_cond_wait():
if (!handler->n_upcalls) {
ovs_mutex_cond_wait(&handler->wake_cond, &handler->mutex);
}
So I would like to propose below patch, to avoid unnecessary wakeups and also avoid
wasted handling in miss_handler when no upcalls, and remove the unused var.
---
ofproto/ofproto-dpif-upcall.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/ofproto/ofproto-dpif-upcall.c b/ofproto/ofproto-dpif-upcall.c
index dde6430..744250c 100644
--- a/ofproto/ofproto-dpif-upcall.c
+++ b/ofproto/ofproto-dpif-upcall.c
@@ -58,7 +58,6 @@ struct handler {
struct list upcalls OVS_GUARDED;
size_t n_upcalls OVS_GUARDED;
- size_t n_new_upcalls; /* Only changed by the dispatcher. */
bool need_signal; /* Only changed by the dispatcher. */
pthread_cond_t wake_cond; /* Wakes 'thread' while holding
@@ -406,7 +405,7 @@ udpif_upcall_handler(void *arg)
return NULL;
}
- if (!handler->n_upcalls) {
+ while (!handler->n_upcalls) {
ovs_mutex_cond_wait(&handler->wake_cond, &handler->mutex);
}
@@ -533,10 +532,10 @@ recv_upcalls(struct udpif *udpif)
ovs_mutex_lock(&handler->mutex);
if (handler->n_upcalls < MAX_QUEUE_LENGTH) {
list_push_back(&handler->upcalls, &upcall->list_node);
- if (handler->n_upcalls == 0) {
+ handler->n_upcalls++;
+ if (!handler->need_signal && (handler->n_upcalls > 0)) {
handler->need_signal = true;
}
- handler->n_upcalls++;
if (handler->need_signal &&
handler->n_upcalls >= FLOW_MISS_MAX_BATCH) {
handler->need_signal = false;
---
Best regards,
Han
More information about the dev
mailing list