aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIgor Druzhinin <igor.druzhinin@citrix.com>2017-01-17 15:49:38 -0500
committerDavid S. Miller <davem@davemloft.net>2017-01-18 15:11:20 -0500
commitf16f1df65f1cf139ff9e9f84661e6573d6bb27fc (patch)
tree6f3d46c2653ace73426558feacde02c97c7adbeb
parent9a6cdf52b85ea5fb21d2bb31e4a7bc61b79923a7 (diff)
xen-netback: protect resource cleaning on XenBus disconnect
vif->lock is used to protect statistics gathering agents from using the queue structure during cleaning. Signed-off-by: Igor Druzhinin <igor.druzhinin@citrix.com> Acked-by: Wei Liu <wei.liu2@citrix.com> Reviewed-by: Paul Durrant <paul.durrant@citrix.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/xen-netback/interface.c6
-rw-r--r--drivers/net/xen-netback/xenbus.c2
2 files changed, 6 insertions, 2 deletions
diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c
index e30ffd29b7e9..579521327b03 100644
--- a/drivers/net/xen-netback/interface.c
+++ b/drivers/net/xen-netback/interface.c
@@ -221,18 +221,18 @@ static struct net_device_stats *xenvif_get_stats(struct net_device *dev)
221{ 221{
222 struct xenvif *vif = netdev_priv(dev); 222 struct xenvif *vif = netdev_priv(dev);
223 struct xenvif_queue *queue = NULL; 223 struct xenvif_queue *queue = NULL;
224 unsigned int num_queues = vif->num_queues;
225 unsigned long rx_bytes = 0; 224 unsigned long rx_bytes = 0;
226 unsigned long rx_packets = 0; 225 unsigned long rx_packets = 0;
227 unsigned long tx_bytes = 0; 226 unsigned long tx_bytes = 0;
228 unsigned long tx_packets = 0; 227 unsigned long tx_packets = 0;
229 unsigned int index; 228 unsigned int index;
230 229
230 spin_lock(&vif->lock);
231 if (vif->queues == NULL) 231 if (vif->queues == NULL)
232 goto out; 232 goto out;
233 233
234 /* Aggregate tx and rx stats from each queue */ 234 /* Aggregate tx and rx stats from each queue */
235 for (index = 0; index < num_queues; ++index) { 235 for (index = 0; index < vif->num_queues; ++index) {
236 queue = &vif->queues[index]; 236 queue = &vif->queues[index];
237 rx_bytes += queue->stats.rx_bytes; 237 rx_bytes += queue->stats.rx_bytes;
238 rx_packets += queue->stats.rx_packets; 238 rx_packets += queue->stats.rx_packets;
@@ -241,6 +241,8 @@ static struct net_device_stats *xenvif_get_stats(struct net_device *dev)
241 } 241 }
242 242
243out: 243out:
244 spin_unlock(&vif->lock);
245
244 vif->dev->stats.rx_bytes = rx_bytes; 246 vif->dev->stats.rx_bytes = rx_bytes;
245 vif->dev->stats.rx_packets = rx_packets; 247 vif->dev->stats.rx_packets = rx_packets;
246 vif->dev->stats.tx_bytes = tx_bytes; 248 vif->dev->stats.tx_bytes = tx_bytes;
diff --git a/drivers/net/xen-netback/xenbus.c b/drivers/net/xen-netback/xenbus.c
index 34e4af9272ea..85b742e1c42f 100644
--- a/drivers/net/xen-netback/xenbus.c
+++ b/drivers/net/xen-netback/xenbus.c
@@ -503,9 +503,11 @@ static void backend_disconnect(struct backend_info *be)
503 for (queue_index = 0; queue_index < be->vif->num_queues; ++queue_index) 503 for (queue_index = 0; queue_index < be->vif->num_queues; ++queue_index)
504 xenvif_deinit_queue(&be->vif->queues[queue_index]); 504 xenvif_deinit_queue(&be->vif->queues[queue_index]);
505 505
506 spin_lock(&be->vif->lock);
506 vfree(be->vif->queues); 507 vfree(be->vif->queues);
507 be->vif->num_queues = 0; 508 be->vif->num_queues = 0;
508 be->vif->queues = NULL; 509 be->vif->queues = NULL;
510 spin_unlock(&be->vif->lock);
509 511
510 xenvif_disconnect_ctrl(be->vif); 512 xenvif_disconnect_ctrl(be->vif);
511 } 513 }