aboutsummaryrefslogtreecommitdiff
path: root/lib/netdev-linux.c
diff options
context:
space:
mode:
authorBen Pfaff <blp@nicira.com>2013-04-29 14:34:57 -0700
committerBen Pfaff <blp@nicira.com>2013-07-23 11:37:57 -0700
commit238821156596c227f4a32a8c3c4ad891591a1802 (patch)
tree18e6a9a43bea1bd0ff673090574b078e7675c3c6 /lib/netdev-linux.c
parent954b526eed5eb2822b38ea6078bfee26c02c220e (diff)
netdev-linux: Work on thread safety.
Signed-off-by: Ben Pfaff <blp@nicira.com> Acked-by: Andy Zhou <azhou@nicira.com>
Diffstat (limited to 'lib/netdev-linux.c')
-rw-r--r--lib/netdev-linux.c38
1 files changed, 22 insertions, 16 deletions
diff --git a/lib/netdev-linux.c b/lib/netdev-linux.c
index 05877c1a..e1ad4c86 100644
--- a/lib/netdev-linux.c
+++ b/lib/netdev-linux.c
@@ -1340,11 +1340,13 @@ static int
netdev_linux_sys_get_stats(const struct netdev *netdev_,
struct netdev_stats *stats)
{
- static int use_netlink_stats = -1;
+ static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER;
+ static int use_netlink_stats;
int error;
- if (use_netlink_stats < 0) {
+ if (ovsthread_once_start(&once)) {
use_netlink_stats = check_for_working_netlink_stats();
+ ovsthread_once_done(&once);
}
if (use_netlink_stats) {
@@ -3777,30 +3779,35 @@ read_psched(void)
* [5] 2.6.32.21.22 (approx.) from Ubuntu 10.04 on VMware Fusion
* [6] 2.6.34 from kernel.org on KVM
*/
+ static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER;
static const char fn[] = "/proc/net/psched";
unsigned int a, b, c, d;
FILE *stream;
+ if (!ovsthread_once_start(&once)) {
+ return;
+ }
+
ticks_per_s = 1.0;
buffer_hz = 100;
stream = fopen(fn, "r");
if (!stream) {
VLOG_WARN("%s: open failed: %s", fn, ovs_strerror(errno));
- return;
+ goto exit;
}
if (fscanf(stream, "%x %x %x %x", &a, &b, &c, &d) != 4) {
VLOG_WARN("%s: read failed", fn);
fclose(stream);
- return;
+ goto exit;
}
VLOG_DBG("%s: psched parameters are: %u %u %u %u", fn, a, b, c, d);
fclose(stream);
if (!a || !c) {
VLOG_WARN("%s: invalid scheduler parameters", fn);
- return;
+ goto exit;
}
ticks_per_s = (double) a * c / b;
@@ -3811,6 +3818,9 @@ read_psched(void)
fn, a, b, c, d);
}
VLOG_DBG("%s: ticks_per_s=%f buffer_hz=%u", fn, ticks_per_s, buffer_hz);
+
+exit:
+ ovsthread_once_done(&once);
}
/* Returns the number of bytes that can be transmitted in 'ticks' ticks at a
@@ -3818,9 +3828,7 @@ read_psched(void)
static unsigned int
tc_ticks_to_bytes(unsigned int rate, unsigned int ticks)
{
- if (!buffer_hz) {
- read_psched();
- }
+ read_psched();
return (rate * ticks) / ticks_per_s;
}
@@ -3829,9 +3837,7 @@ tc_ticks_to_bytes(unsigned int rate, unsigned int ticks)
static unsigned int
tc_bytes_to_ticks(unsigned int rate, unsigned int size)
{
- if (!buffer_hz) {
- read_psched();
- }
+ read_psched();
return rate ? ((unsigned long long int) ticks_per_s * size) / rate : 0;
}
@@ -3840,9 +3846,7 @@ tc_bytes_to_ticks(unsigned int rate, unsigned int size)
static unsigned int
tc_buffer_per_jiffy(unsigned int rate)
{
- if (!buffer_hz) {
- read_psched();
- }
+ read_psched();
return rate / buffer_hz;
}
@@ -4556,9 +4560,10 @@ netdev_linux_get_ipv4(const struct netdev *netdev, struct in_addr *ip,
static int
af_packet_sock(void)
{
- static int sock = INT_MIN;
+ static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER;
+ static int sock;
- if (sock == INT_MIN) {
+ if (ovsthread_once_start(&once)) {
sock = socket(AF_PACKET, SOCK_RAW, 0);
if (sock >= 0) {
int error = set_nonblocking(sock);
@@ -4571,6 +4576,7 @@ af_packet_sock(void)
VLOG_ERR("failed to create packet socket: %s",
ovs_strerror(errno));
}
+ ovsthread_once_done(&once);
}
return sock;