Skip to content

Commit

Permalink
Merge branch 'xen-netback-leaks'
Browse files Browse the repository at this point in the history
Igor Druzhinin says:

====================
xen-netback: fix memory leaks on XenBus disconnect

Just split the initial patch in two as proposed by Wei.

Since the approach for locking netdev statistics is inconsistent (tends not
to have any locking at all) accross the kernel we'd better to rely on our
internal lock for this purpose.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Jan 18, 2017
2 parents 6acbe37 + f16f1df commit d89ede6
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 2 deletions.
6 changes: 4 additions & 2 deletions drivers/net/xen-netback/interface.c
Original file line number Diff line number Diff line change
Expand Up @@ -221,18 +221,18 @@ static struct net_device_stats *xenvif_get_stats(struct net_device *dev)
{
struct xenvif *vif = netdev_priv(dev);
struct xenvif_queue *queue = NULL;
unsigned int num_queues = vif->num_queues;
unsigned long rx_bytes = 0;
unsigned long rx_packets = 0;
unsigned long tx_bytes = 0;
unsigned long tx_packets = 0;
unsigned int index;

spin_lock(&vif->lock);
if (vif->queues == NULL)
goto out;

/* Aggregate tx and rx stats from each queue */
for (index = 0; index < num_queues; ++index) {
for (index = 0; index < vif->num_queues; ++index) {
queue = &vif->queues[index];
rx_bytes += queue->stats.rx_bytes;
rx_packets += queue->stats.rx_packets;
Expand All @@ -241,6 +241,8 @@ static struct net_device_stats *xenvif_get_stats(struct net_device *dev)
}

out:
spin_unlock(&vif->lock);

vif->dev->stats.rx_bytes = rx_bytes;
vif->dev->stats.rx_packets = rx_packets;
vif->dev->stats.tx_bytes = tx_bytes;
Expand Down
13 changes: 13 additions & 0 deletions drivers/net/xen-netback/xenbus.c
Original file line number Diff line number Diff line change
Expand Up @@ -493,11 +493,22 @@ static int backend_create_xenvif(struct backend_info *be)
static void backend_disconnect(struct backend_info *be)
{
if (be->vif) {
unsigned int queue_index;

xen_unregister_watchers(be->vif);
#ifdef CONFIG_DEBUG_FS
xenvif_debugfs_delif(be->vif);
#endif /* CONFIG_DEBUG_FS */
xenvif_disconnect_data(be->vif);
for (queue_index = 0; queue_index < be->vif->num_queues; ++queue_index)
xenvif_deinit_queue(&be->vif->queues[queue_index]);

spin_lock(&be->vif->lock);
vfree(be->vif->queues);
be->vif->num_queues = 0;
be->vif->queues = NULL;
spin_unlock(&be->vif->lock);

xenvif_disconnect_ctrl(be->vif);
}
}
Expand Down Expand Up @@ -1034,6 +1045,8 @@ static void connect(struct backend_info *be)
err:
if (be->vif->num_queues > 0)
xenvif_disconnect_data(be->vif); /* Clean up existing queues */
for (queue_index = 0; queue_index < be->vif->num_queues; ++queue_index)
xenvif_deinit_queue(&be->vif->queues[queue_index]);
vfree(be->vif->queues);
be->vif->queues = NULL;
be->vif->num_queues = 0;
Expand Down

0 comments on commit d89ede6

Please sign in to comment.