mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-12 13:55:32 +00:00
Merge branch 'xen-netback-leaks'
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>
This commit is contained in:
commit
d89ede6d8f
2 changed files with 17 additions and 2 deletions
|
@ -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;
|
||||
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue