Signed-off-by: Ben Pfaff <[email protected]>
---
lib/dpif-netdev.c | 29 ++++++++++++++---------------
1 file changed, 14 insertions(+), 15 deletions(-)
diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
index 5bd2d7b..9b6913e 100644
--- a/lib/dpif-netdev.c
+++ b/lib/dpif-netdev.c
@@ -49,6 +49,7 @@
#include "packets.h"
#include "poll-loop.h"
#include "random.h"
+#include "seq.h"
#include "shash.h"
#include "sset.h"
#include "timeval.h"
@@ -101,7 +102,7 @@ struct dp_netdev {
/* Ports. */
struct dp_netdev_port *ports[MAX_PORTS];
struct list port_list;
- unsigned int serial;
+ struct seq *seq;
};
/* A port in a netdev-based datapath. */
@@ -134,7 +135,7 @@ struct dp_netdev_flow {
struct dpif_netdev {
struct dpif dpif;
struct dp_netdev *dp;
- unsigned int dp_serial;
+ uint64_t seq;
};
/* All netdev-based datapaths. */
@@ -218,7 +219,7 @@ create_dpif_netdev(struct dp_netdev *dp)
dpif = xmalloc(sizeof *dpif);
dpif_init(&dpif->dpif, dp->class, dp->name, netflow_id >> 8, netflow_id);
dpif->dp = dp;
- dpif->dp_serial = dp->serial;
+ dpif->seq = seq_read(dp->seq);
return &dpif->dpif;
}
@@ -282,6 +283,7 @@ create_dp_netdev(const char *name, const struct dpif_class
*class,
}
hmap_init(&dp->flow_table);
list_init(&dp->port_list);
+ dp->seq = seq_create();
error = do_add_port(dp, name, "internal", ODPP_LOCAL);
if (error) {
@@ -345,6 +347,7 @@ dp_netdev_free(struct dp_netdev *dp)
}
dp_netdev_purge_queues(dp);
hmap_destroy(&dp->flow_table);
+ seq_destroy(dp->seq);
free(dp->name);
free(dp);
}
@@ -446,7 +449,7 @@ do_add_port(struct dp_netdev *dp, const char *devname,
const char *type,
list_push_back(&dp->port_list, &port->node);
dp->ports[odp_to_u32(port_no)] = port;
- dp->serial++;
+ seq_change(dp->seq);
return 0;
}
@@ -546,7 +549,7 @@ do_del_port(struct dp_netdev *dp, odp_port_t port_no)
list_remove(&port->node);
dp->ports[odp_to_u32(port_no)] = NULL;
- dp->serial++;
+ seq_change(dp->seq);
netdev_close(port->netdev);
netdev_restore_flags(port->sf);
@@ -692,11 +695,13 @@ static int
dpif_netdev_port_poll(const struct dpif *dpif_, char **devnamep OVS_UNUSED)
{
struct dpif_netdev *dpif = dpif_netdev_cast(dpif_);
+ uint64_t new_seq;
int error;
ovs_mutex_lock(&dp_netdev_mutex);
- if (dpif->dp_serial != dpif->dp->serial) {
- dpif->dp_serial = dpif->dp->serial;
+ new_seq = seq_read(dpif->dp->seq);
+ if (dpif->seq != new_seq) {
+ dpif->seq = new_seq;
error = ENOBUFS;
} else {
error = EAGAIN;
@@ -711,14 +716,8 @@ dpif_netdev_port_poll_wait(const struct dpif *dpif_)
{
struct dpif_netdev *dpif = dpif_netdev_cast(dpif_);
- /* XXX In a multithreaded process, there is a race window between this
- * function and the poll_block() in one thread and a change in
- * dpif->dp->serial in another thread. */
-
ovs_mutex_lock(&dp_netdev_mutex);
- if (dpif->dp_serial != dpif->dp->serial) {
- poll_immediate_wake();
- }
+ seq_wait(dpif->dp->seq, dpif->seq);
ovs_mutex_unlock(&dp_netdev_mutex);
}
@@ -1359,7 +1358,7 @@ dpif_dummy_change_port_number(struct unixctl_conn *conn,
int argc OVS_UNUSED,
dp->ports[odp_to_u32(port->port_no)] = NULL;
dp->ports[port_no] = port;
port->port_no = u32_to_odp(port_no);
- dp->serial++;
+ seq_change(dp->seq);
unixctl_command_reply(conn, NULL);
}
--
1.7.10.4
_______________________________________________
dev mailing list
[email protected]
http://openvswitch.org/mailman/listinfo/dev