diff options
author | Amit Shah <amit.shah@redhat.com> | 2010-02-12 00:02:15 -0500 |
---|---|---|
committer | Rusty Russell <rusty@rustcorp.com.au> | 2010-02-23 22:53:03 -0500 |
commit | a9cdd4855738906043b8131cfe8055d6cde88ffe (patch) | |
tree | 37ce268d3aceb90145d6d42d29b1f77a5bc1005f /drivers/char | |
parent | 298add723aecd7af461319fe815d935ef2c40d78 (diff) |
virtio: console: Ensure no memleaks in case of unused buffers
If unused data exists in in_vq, ensure we flush that first and then
detach unused buffers, which will ensure all buffers from the in_vq are
removed.
Also ensure we free the buffers after detaching them.
Signed-off-by: Amit Shah <amit.shah@redhat.com>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Diffstat (limited to 'drivers/char')
-rw-r--r-- | drivers/char/virtio_console.c | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index a3f1f73bac3a..69d2e616dd0c 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c | |||
@@ -838,6 +838,8 @@ static const struct file_operations port_debugfs_ops = { | |||
838 | /* Remove all port-specific data. */ | 838 | /* Remove all port-specific data. */ |
839 | static int remove_port(struct port *port) | 839 | static int remove_port(struct port *port) |
840 | { | 840 | { |
841 | struct port_buffer *buf; | ||
842 | |||
841 | spin_lock_irq(&port->portdev->ports_lock); | 843 | spin_lock_irq(&port->portdev->ports_lock); |
842 | list_del(&port->list); | 844 | list_del(&port->list); |
843 | spin_unlock_irq(&port->portdev->ports_lock); | 845 | spin_unlock_irq(&port->portdev->ports_lock); |
@@ -851,14 +853,17 @@ static int remove_port(struct port *port) | |||
851 | if (port->guest_connected) | 853 | if (port->guest_connected) |
852 | send_control_msg(port, VIRTIO_CONSOLE_PORT_OPEN, 0); | 854 | send_control_msg(port, VIRTIO_CONSOLE_PORT_OPEN, 0); |
853 | 855 | ||
854 | while (port->in_vq->vq_ops->detach_unused_buf(port->in_vq)) | ||
855 | ; | ||
856 | |||
857 | sysfs_remove_group(&port->dev->kobj, &port_attribute_group); | 856 | sysfs_remove_group(&port->dev->kobj, &port_attribute_group); |
858 | device_destroy(pdrvdata.class, port->dev->devt); | 857 | device_destroy(pdrvdata.class, port->dev->devt); |
859 | cdev_del(&port->cdev); | 858 | cdev_del(&port->cdev); |
860 | 859 | ||
860 | /* Remove unused data this port might have received. */ | ||
861 | discard_port_data(port); | 861 | discard_port_data(port); |
862 | |||
863 | /* Remove buffers we queued up for the Host to send us data in. */ | ||
864 | while ((buf = port->in_vq->vq_ops->detach_unused_buf(port->in_vq))) | ||
865 | free_buf(buf); | ||
866 | |||
862 | kfree(port->name); | 867 | kfree(port->name); |
863 | 868 | ||
864 | debugfs_remove(port->debugfs_file); | 869 | debugfs_remove(port->debugfs_file); |