From: Ben Pfaff Date: Thu, 26 Dec 2013 06:27:25 +0000 (-0800) Subject: netdev-dummy: Make netdev_rx_wait() wakeups work cross-thread for dummies. X-Git-Tag: sliver-openvswitch-2.1.90-1~10^2~43 X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=98045eda19a14799848a2faec5e9968d2ae5cd1b;p=sliver-openvswitch.git netdev-dummy: Make netdev_rx_wait() wakeups work cross-thread for dummies. Until now, netdev_dummy_rx_wait() has only checked whether the receive queue for the dummy device is currently empty. This has worked OK because in practice packets were queued to dummy devices only from the same thread that attempted to receive them. An upcoming commit will use different threads for these purposes, so this commit switches to a notification method that works cross-thread. Signed-off-by: Ben Pfaff Acked-by: Ethan Jackson --- diff --git a/lib/netdev-dummy.c b/lib/netdev-dummy.c index 8ad9af6c3..6286f6b50 100644 --- a/lib/netdev-dummy.c +++ b/lib/netdev-dummy.c @@ -87,6 +87,7 @@ struct netdev_rx_dummy { struct list node; /* In netdev_dummy's "rxes" list. */ struct list recv_queue; int recv_queue_len; /* list_size(&recv_queue). */ + struct seq *seq; /* Reports newly queued packets. */ }; static unixctl_cb_func netdev_dummy_set_admin_state; @@ -418,6 +419,7 @@ netdev_dummy_rx_construct(struct netdev_rx *rx_) list_push_back(&netdev->rxes, &rx->node); list_init(&rx->recv_queue); rx->recv_queue_len = 0; + rx->seq = seq_create(); ovs_mutex_unlock(&netdev->mutex); return 0; @@ -433,6 +435,7 @@ netdev_dummy_rx_destruct(struct netdev_rx *rx_) list_remove(&rx->node); ofpbuf_list_delete(&rx->recv_queue); ovs_mutex_unlock(&netdev->mutex); + seq_destroy(rx->seq); } static void @@ -485,10 +488,13 @@ netdev_dummy_rx_wait(struct netdev_rx *rx_) { struct netdev_rx_dummy *rx = netdev_rx_dummy_cast(rx_); struct netdev_dummy *netdev = netdev_dummy_cast(rx->up.netdev); + uint64_t seq = seq_read(rx->seq); ovs_mutex_lock(&netdev->mutex); if (!list_is_empty(&rx->recv_queue)) { poll_immediate_wake(); + } else { + seq_wait(rx->seq, seq); } ovs_mutex_unlock(&netdev->mutex); } @@ -504,6 +510,8 @@ netdev_dummy_rx_drain(struct netdev_rx *rx_) rx->recv_queue_len = 0; ovs_mutex_unlock(&netdev->mutex); + seq_change(rx->seq); + return 0; } @@ -795,6 +803,7 @@ netdev_dummy_queue_packet__(struct netdev_rx_dummy *rx, struct ofpbuf *packet) { list_push_back(&rx->recv_queue, &packet->list_node); rx->recv_queue_len++; + seq_change(rx->seq); } static void