diff mbox

[v3,5/7] net: introduce lock to protect net clients

Message ID 1372304329-6931-6-git-send-email-pingfank@linux.vnet.ibm.com
State New
Headers show

Commit Message

pingfan liu June 27, 2013, 3:38 a.m. UTC
Signed-off-by: Liu Ping Fan <pingfank@linux.vnet.ibm.com>
---
 net/net.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

Comments

pingfan liu July 4, 2013, 2:48 a.m. UTC | #1
On Thu, Jun 27, 2013 at 11:38 AM, Liu Ping Fan <qemulist@gmail.com> wrote:
Append commit log:

NetClientStates come and go into the net_clients in parallel. So use
lock to protect it.

Stefanha,
I will add lock in net_cleanup() as discussed in another thread.


Regards,
Pingfan

> Signed-off-by: Liu Ping Fan <pingfank@linux.vnet.ibm.com>
> ---
>  net/net.c | 20 ++++++++++++++++++++
>  1 file changed, 20 insertions(+)
>
> diff --git a/net/net.c b/net/net.c
> index 6fc50d8..9f951b8 100644
> --- a/net/net.c
> +++ b/net/net.c
> @@ -45,6 +45,7 @@
>  # define CONFIG_NET_BRIDGE
>  #endif
>
> +static QemuMutex net_clients_lock;
>  static QTAILQ_HEAD(, NetClientState) net_clients;
>
>  int default_net = 1;
> @@ -165,6 +166,7 @@ static char *assign_name(NetClientState *nc1, const char *model)
>      char buf[256];
>      int id = 0;
>
> +    qemu_mutex_lock(&net_clients_lock);
>      QTAILQ_FOREACH(nc, &net_clients, next) {
>          if (nc == nc1) {
>              continue;
> @@ -173,6 +175,7 @@ static char *assign_name(NetClientState *nc1, const char *model)
>              id++;
>          }
>      }
> +    qemu_mutex_unlock(&net_clients_lock);
>
>      snprintf(buf, sizeof(buf), "%s.%d", model, id);
>
> @@ -205,7 +208,9 @@ static void qemu_net_client_setup(NetClientState *nc,
>          peer->peer = nc;
>      }
>      qemu_mutex_init(&nc->peer_lock);
> +    qemu_mutex_lock(&net_clients_lock);
>      QTAILQ_INSERT_TAIL(&net_clients, nc, next);
> +    qemu_mutex_unlock(&net_clients_lock);
>
>      nc->send_queue = qemu_new_net_queue(nc);
>      nc->destructor = destructor;
> @@ -281,7 +286,9 @@ void *qemu_get_nic_opaque(NetClientState *nc)
>
>  static void qemu_cleanup_net_client(NetClientState *nc)
>  {
> +    qemu_mutex_lock(&net_clients_lock);
>      QTAILQ_REMOVE(&net_clients, nc, next);
> +    qemu_mutex_unlock(&net_clients_lock);
>
>      if (nc->info->cleanup) {
>          nc->info->cleanup(nc);
> @@ -406,6 +413,7 @@ void qemu_foreach_nic(qemu_nic_foreach func, void *opaque)
>  {
>      NetClientState *nc;
>
> +    qemu_mutex_lock(&net_clients_lock);
>      QTAILQ_FOREACH(nc, &net_clients, next) {
>          if (nc->info->type == NET_CLIENT_OPTIONS_KIND_NIC) {
>              if (nc->queue_index == 0) {
> @@ -413,6 +421,7 @@ void qemu_foreach_nic(qemu_nic_foreach func, void *opaque)
>              }
>          }
>      }
> +    qemu_mutex_unlock(&net_clients_lock);
>  }
>
>  int qemu_can_send_packet_nolock(NetClientState *sender)
> @@ -615,13 +624,16 @@ NetClientState *qemu_find_netdev(const char *id)
>  {
>      NetClientState *nc;
>
> +    qemu_mutex_lock(&net_clients_lock);
>      QTAILQ_FOREACH(nc, &net_clients, next) {
>          if (nc->info->type == NET_CLIENT_OPTIONS_KIND_NIC)
>              continue;
>          if (!strcmp(nc->name, id)) {
> +            qemu_mutex_unlock(&net_clients_lock);
>              return nc;
>          }
>      }
> +    qemu_mutex_unlock(&net_clients_lock);
>
>      return NULL;
>  }
> @@ -632,6 +644,7 @@ int qemu_find_net_clients_except(const char *id, NetClientState **ncs,
>      NetClientState *nc;
>      int ret = 0;
>
> +    qemu_mutex_lock(&net_clients_lock);
>      QTAILQ_FOREACH(nc, &net_clients, next) {
>          if (nc->info->type == type) {
>              continue;
> @@ -643,6 +656,7 @@ int qemu_find_net_clients_except(const char *id, NetClientState **ncs,
>              ret++;
>          }
>      }
> +    qemu_mutex_unlock(&net_clients_lock);
>
>      return ret;
>  }
> @@ -1024,6 +1038,7 @@ void do_info_network(Monitor *mon, const QDict *qdict)
>
>      net_hub_info(mon);
>
> +    qemu_mutex_lock(&net_clients_lock);
>      QTAILQ_FOREACH(nc, &net_clients, next) {
>          peer = nc->peer;
>          type = nc->info->type;
> @@ -1041,6 +1056,7 @@ void do_info_network(Monitor *mon, const QDict *qdict)
>              print_net_client(mon, peer);
>          }
>      }
> +    qemu_mutex_unlock(&net_clients_lock);
>  }
>
>  void qmp_set_link(const char *name, bool up, Error **errp)
> @@ -1094,6 +1110,7 @@ void net_cleanup(void)
>              qemu_del_net_client(nc);
>          }
>      }
> +    qemu_mutex_destroy(&net_clients_lock);
>  }
>
>  void net_check_clients(void)
> @@ -1115,6 +1132,7 @@ void net_check_clients(void)
>
>      net_hub_check_clients();
>
> +    qemu_mutex_lock(&net_clients_lock);
>      QTAILQ_FOREACH(nc, &net_clients, next) {
>          if (!nc->peer) {
>              fprintf(stderr, "Warning: %s %s has no peer\n",
> @@ -1122,6 +1140,7 @@ void net_check_clients(void)
>                      "nic" : "netdev", nc->name);
>          }
>      }
> +    qemu_mutex_unlock(&net_clients_lock);
>
>      /* Check that all NICs requested via -net nic actually got created.
>       * NICs created via -device don't need to be checked here because
> @@ -1179,6 +1198,7 @@ int net_init_clients(void)
>  #endif
>      }
>
> +    qemu_mutex_init(&net_clients_lock);
>      QTAILQ_INIT(&net_clients);
>
>      if (qemu_opts_foreach(qemu_find_opts("netdev"), net_init_netdev, NULL, 1) == -1)
> --
> 1.8.1.4
>
diff mbox

Patch

diff --git a/net/net.c b/net/net.c
index 6fc50d8..9f951b8 100644
--- a/net/net.c
+++ b/net/net.c
@@ -45,6 +45,7 @@ 
 # define CONFIG_NET_BRIDGE
 #endif
 
+static QemuMutex net_clients_lock;
 static QTAILQ_HEAD(, NetClientState) net_clients;
 
 int default_net = 1;
@@ -165,6 +166,7 @@  static char *assign_name(NetClientState *nc1, const char *model)
     char buf[256];
     int id = 0;
 
+    qemu_mutex_lock(&net_clients_lock);
     QTAILQ_FOREACH(nc, &net_clients, next) {
         if (nc == nc1) {
             continue;
@@ -173,6 +175,7 @@  static char *assign_name(NetClientState *nc1, const char *model)
             id++;
         }
     }
+    qemu_mutex_unlock(&net_clients_lock);
 
     snprintf(buf, sizeof(buf), "%s.%d", model, id);
 
@@ -205,7 +208,9 @@  static void qemu_net_client_setup(NetClientState *nc,
         peer->peer = nc;
     }
     qemu_mutex_init(&nc->peer_lock);
+    qemu_mutex_lock(&net_clients_lock);
     QTAILQ_INSERT_TAIL(&net_clients, nc, next);
+    qemu_mutex_unlock(&net_clients_lock);
 
     nc->send_queue = qemu_new_net_queue(nc);
     nc->destructor = destructor;
@@ -281,7 +286,9 @@  void *qemu_get_nic_opaque(NetClientState *nc)
 
 static void qemu_cleanup_net_client(NetClientState *nc)
 {
+    qemu_mutex_lock(&net_clients_lock);
     QTAILQ_REMOVE(&net_clients, nc, next);
+    qemu_mutex_unlock(&net_clients_lock);
 
     if (nc->info->cleanup) {
         nc->info->cleanup(nc);
@@ -406,6 +413,7 @@  void qemu_foreach_nic(qemu_nic_foreach func, void *opaque)
 {
     NetClientState *nc;
 
+    qemu_mutex_lock(&net_clients_lock);
     QTAILQ_FOREACH(nc, &net_clients, next) {
         if (nc->info->type == NET_CLIENT_OPTIONS_KIND_NIC) {
             if (nc->queue_index == 0) {
@@ -413,6 +421,7 @@  void qemu_foreach_nic(qemu_nic_foreach func, void *opaque)
             }
         }
     }
+    qemu_mutex_unlock(&net_clients_lock);
 }
 
 int qemu_can_send_packet_nolock(NetClientState *sender)
@@ -615,13 +624,16 @@  NetClientState *qemu_find_netdev(const char *id)
 {
     NetClientState *nc;
 
+    qemu_mutex_lock(&net_clients_lock);
     QTAILQ_FOREACH(nc, &net_clients, next) {
         if (nc->info->type == NET_CLIENT_OPTIONS_KIND_NIC)
             continue;
         if (!strcmp(nc->name, id)) {
+            qemu_mutex_unlock(&net_clients_lock);
             return nc;
         }
     }
+    qemu_mutex_unlock(&net_clients_lock);
 
     return NULL;
 }
@@ -632,6 +644,7 @@  int qemu_find_net_clients_except(const char *id, NetClientState **ncs,
     NetClientState *nc;
     int ret = 0;
 
+    qemu_mutex_lock(&net_clients_lock);
     QTAILQ_FOREACH(nc, &net_clients, next) {
         if (nc->info->type == type) {
             continue;
@@ -643,6 +656,7 @@  int qemu_find_net_clients_except(const char *id, NetClientState **ncs,
             ret++;
         }
     }
+    qemu_mutex_unlock(&net_clients_lock);
 
     return ret;
 }
@@ -1024,6 +1038,7 @@  void do_info_network(Monitor *mon, const QDict *qdict)
 
     net_hub_info(mon);
 
+    qemu_mutex_lock(&net_clients_lock);
     QTAILQ_FOREACH(nc, &net_clients, next) {
         peer = nc->peer;
         type = nc->info->type;
@@ -1041,6 +1056,7 @@  void do_info_network(Monitor *mon, const QDict *qdict)
             print_net_client(mon, peer);
         }
     }
+    qemu_mutex_unlock(&net_clients_lock);
 }
 
 void qmp_set_link(const char *name, bool up, Error **errp)
@@ -1094,6 +1110,7 @@  void net_cleanup(void)
             qemu_del_net_client(nc);
         }
     }
+    qemu_mutex_destroy(&net_clients_lock);
 }
 
 void net_check_clients(void)
@@ -1115,6 +1132,7 @@  void net_check_clients(void)
 
     net_hub_check_clients();
 
+    qemu_mutex_lock(&net_clients_lock);
     QTAILQ_FOREACH(nc, &net_clients, next) {
         if (!nc->peer) {
             fprintf(stderr, "Warning: %s %s has no peer\n",
@@ -1122,6 +1140,7 @@  void net_check_clients(void)
                     "nic" : "netdev", nc->name);
         }
     }
+    qemu_mutex_unlock(&net_clients_lock);
 
     /* Check that all NICs requested via -net nic actually got created.
      * NICs created via -device don't need to be checked here because
@@ -1179,6 +1198,7 @@  int net_init_clients(void)
 #endif
     }
 
+    qemu_mutex_init(&net_clients_lock);
     QTAILQ_INIT(&net_clients);
 
     if (qemu_opts_foreach(qemu_find_opts("netdev"), net_init_netdev, NULL, 1) == -1)