[ovs-dev] [thread-safety 06/11] netdev-vport: Make statistics thread safe.
Ethan Jackson
ethan at nicira.com
Sat Jul 27 01:07:07 UTC 2013
Statistics are the only part of netdev-vport which need to be
manipulated by multiple threads. This patch makes them thread safe.
Signed-off-by: Ethan Jackson <ethan at nicira.com>
---
lib/netdev-vport.c | 12 +++++++++++-
lib/netdev-vport.h | 16 +++++++++++-----
2 files changed, 22 insertions(+), 6 deletions(-)
diff --git a/lib/netdev-vport.c b/lib/netdev-vport.c
index 4214b38..578fff1 100644
--- a/lib/netdev-vport.c
+++ b/lib/netdev-vport.c
@@ -50,7 +50,9 @@ struct netdev_vport {
struct netdev up;
unsigned int change_seq;
uint8_t etheraddr[ETH_ADDR_LEN];
- struct netdev_stats stats;
+
+ struct netdev_stats stats OVS_GUARDED;
+ struct ovs_mutex stats_mutex;
/* Tunnels. */
struct netdev_tunnel_config tnl_cfg;
@@ -165,6 +167,7 @@ netdev_vport_create(const struct netdev_class *netdev_class, const char *name,
netdev_init(&dev->up, name, netdev_class);
dev->change_seq = 1;
eth_addr_random(dev->etheraddr);
+ ovs_mutex_init(&dev->stats_mutex, NULL);
*netdevp = &dev->up;
route_table_register();
@@ -177,6 +180,7 @@ netdev_vport_destroy(struct netdev *netdev_)
{
struct netdev_vport *netdev = netdev_vport_cast(netdev_);
+ ovs_mutex_destroy(&netdev->stats_mutex);
route_table_unregister();
free(netdev->peer);
free(netdev);
@@ -559,8 +563,10 @@ netdev_vport_inc_rx(const struct netdev *netdev,
{
if (is_vport_class(netdev_get_class(netdev))) {
struct netdev_vport *dev = netdev_vport_cast(netdev);
+ ovs_mutex_lock(&dev->stats_mutex);
dev->stats.rx_packets += stats->n_packets;
dev->stats.rx_bytes += stats->n_bytes;
+ ovs_mutex_unlock(&dev->stats_mutex);
}
}
@@ -570,8 +576,10 @@ netdev_vport_inc_tx(const struct netdev *netdev,
{
if (is_vport_class(netdev_get_class(netdev))) {
struct netdev_vport *dev = netdev_vport_cast(netdev);
+ ovs_mutex_lock(&dev->stats_mutex);
dev->stats.tx_packets += stats->n_packets;
dev->stats.tx_bytes += stats->n_bytes;
+ ovs_mutex_unlock(&dev->stats_mutex);
}
}
@@ -619,7 +627,9 @@ static int
get_stats(const struct netdev *netdev, struct netdev_stats *stats)
{
struct netdev_vport *dev = netdev_vport_cast(netdev);
+ ovs_mutex_lock(&dev->stats_mutex);
memcpy(stats, &dev->stats, sizeof *stats);
+ ovs_mutex_unlock(&dev->stats_mutex);
return 0;
}
diff --git a/lib/netdev-vport.h b/lib/netdev-vport.h
index 5394966..7941525 100644
--- a/lib/netdev-vport.h
+++ b/lib/netdev-vport.h
@@ -20,6 +20,13 @@
#include <stdbool.h>
#include <stddef.h>
+/* Thread-safety
+ * =============
+ *
+ * Only netdev_vport_inc_rx() and and netdev_vport_inc_tx() are thread safe.
+ * All other functions are expected to be called exclusively from the main
+ * thread. */
+
struct dpif_linux_vport;
struct dpif_flow_stats;
struct netdev;
@@ -33,11 +40,6 @@ bool netdev_vport_is_patch(const struct netdev *);
const char *netdev_vport_patch_peer(const struct netdev *netdev);
-void netdev_vport_inc_rx(const struct netdev *,
- const struct dpif_flow_stats *);
-void netdev_vport_inc_tx(const struct netdev *,
- const struct dpif_flow_stats *);
-
const char *netdev_vport_class_get_dpif_port(const struct netdev_class *);
enum { NETDEV_VPORT_NAME_BUFSIZE = 16 };
@@ -45,4 +47,8 @@ const char *netdev_vport_get_dpif_port(const struct netdev *,
char namebuf[], size_t bufsize);
char *netdev_vport_get_dpif_port_strdup(const struct netdev *);
+void netdev_vport_inc_rx(const struct netdev *,
+ const struct dpif_flow_stats *);
+void netdev_vport_inc_tx(const struct netdev *,
+ const struct dpif_flow_stats *);
#endif /* netdev-vport.h */
--
1.7.9.5
More information about the dev
mailing list