diff options
author | Amit Shah <amit.shah@redhat.com> | 2010-02-12 10:32:15 +0530 |
---|---|---|
committer | Rusty Russell <rusty@rustcorp.com.au> | 2010-02-24 14:23:03 +1030 |
commit | a9cdd4855738906043b8131cfe8055d6cde88ffe (patch) | |
tree | 37ce268d3aceb90145d6d42d29b1f77a5bc1005f /drivers/char | |
parent | 298add723aecd7af461319fe815d935ef2c40d78 (diff) | |
download | talos-op-linux-a9cdd4855738906043b8131cfe8055d6cde88ffe.tar.gz talos-op-linux-a9cdd4855738906043b8131cfe8055d6cde88ffe.zip |
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 = { /* Remove all port-specific data. */ static int remove_port(struct port *port) { + struct port_buffer *buf; + spin_lock_irq(&port->portdev->ports_lock); list_del(&port->list); spin_unlock_irq(&port->portdev->ports_lock); @@ -851,14 +853,17 @@ static int remove_port(struct port *port) if (port->guest_connected) send_control_msg(port, VIRTIO_CONSOLE_PORT_OPEN, 0); - while (port->in_vq->vq_ops->detach_unused_buf(port->in_vq)) - ; - sysfs_remove_group(&port->dev->kobj, &port_attribute_group); device_destroy(pdrvdata.class, port->dev->devt); cdev_del(&port->cdev); + /* Remove unused data this port might have received. */ discard_port_data(port); + + /* Remove buffers we queued up for the Host to send us data in. */ + while ((buf = port->in_vq->vq_ops->detach_unused_buf(port->in_vq))) + free_buf(buf); + kfree(port->name); debugfs_remove(port->debugfs_file); |