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 <blp@nicira.com>
Acked-by: Ethan Jackson <ethan@nicira.com>
struct list node; /* In netdev_dummy's "rxes" list. */
struct list recv_queue;
int recv_queue_len; /* list_size(&recv_queue). */
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;
};
static unixctl_cb_func netdev_dummy_set_admin_state;
list_push_back(&netdev->rxes, &rx->node);
list_init(&rx->recv_queue);
rx->recv_queue_len = 0;
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;
ovs_mutex_unlock(&netdev->mutex);
return 0;
list_remove(&rx->node);
ofpbuf_list_delete(&rx->recv_queue);
ovs_mutex_unlock(&netdev->mutex);
list_remove(&rx->node);
ofpbuf_list_delete(&rx->recv_queue);
ovs_mutex_unlock(&netdev->mutex);
{
struct netdev_rx_dummy *rx = netdev_rx_dummy_cast(rx_);
struct netdev_dummy *netdev = netdev_dummy_cast(rx->up.netdev);
{
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();
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);
}
}
ovs_mutex_unlock(&netdev->mutex);
}
rx->recv_queue_len = 0;
ovs_mutex_unlock(&netdev->mutex);
rx->recv_queue_len = 0;
ovs_mutex_unlock(&netdev->mutex);
{
list_push_back(&rx->recv_queue, &packet->list_node);
rx->recv_queue_len++;
{
list_push_back(&rx->recv_queue, &packet->list_node);
rx->recv_queue_len++;