virtio: console: fixes, SIGIO
Subsystems (3)
cover virtio: console: fixes, SIGIO
Hi Rusty,
The main thing in these patches is the introduction of injecting SIGIO on host-side connect/disconnect events and when new data is available for ports.
The first two patches fix bugs that I haven't seen, but look like the right thing to do.
These have been tested extensively using the test-virtserial test suite.
Please apply,
Amit.
Amit Shah (4):
virtio: console: Un-block reads on chardev close
virtio: console: Annotate virtcons_remove with __devexit_p
virtio: console: Send SIGIO to processes that request it for host
events
virtio: console: Send SIGIO on new data arrival on ports
drivers/char/virtio_console.c | 32 ++++++++++++++++++++++++++++++-- 1 files changed, 30 insertions(+), 2 deletions(-)
Signature · 1 line
1.7.2.2
PATCH 1/4 virtio: console: Un-block reads on chardev close
If a chardev is closed, any blocked read / poll calls should just return and not attempt to use other state.
--- drivers/char/virtio_console.c | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-)
drivers/char/virtio_console.c +4 -0
@@ -522,6 +522,10 @@ static ssize_t fill_readbuf(struct port *port, char *out_buf, size_t out_count,/* The condition that must be true for polling to end */ static bool will_read_block (struct port *port) { +if (!port->guest_connected) { +/* Port got hot-unplugged. Let's exit. */ +return false; + }return !port_has_data (port) && port->host_connected; }
Signature · 1 line
1.7.2.2
PATCH 2/4 virtio: console: Annotate virtcons_remove with __devexit_p
In reply to Amit Shahvirtcons_remove is called on device unplug. Mark with __devexit_p.
--- drivers/char/virtio_console.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-)
drivers/char/virtio_console.c +2 -2
@@ -1585,7 +1585,7 @@ fail:return err; } -static void virtcons_remove (struct virtio_device *vdev) +static void __devexit virtcons_remove(struct virtio_device *vdev) {struct ports_device *portdev;struct port *port, *port2;
@@ -1631,7 +1631,7 @@ static struct virtio_driver virtio_console = { .driver.owner = THIS_MODULE, .id_table = id_table, .probe = virtcons_probe, - .remove = virtcons_remove, + .remove = __devexit_p(virtcons_remove), .config_changed = config_intr, };
Signature · 1 line
1.7.2.2
PATCH 3/4 virtio: console: Send SIGIO to processes that request it for host events
In reply to Amit ShahA process can request for SIGIO on host connect / disconnect events using the O_ASYNC file flag using fcntl().
If that's requested, and if the guest-side connection for the port is open, any host-side open/close events for that port will raise a SIGIO. The process can then use poll() within the signal handler to find out which port triggered the signal.
--- drivers/char/virtio_console.c | 20 ++++++++++++++++++++ 1 files changed, 20 insertions(+), 0 deletions(-)
drivers/char/virtio_console.c +20 -0
@@ -187,6 +187,9 @@ struct port {/* The 'name' of the port that we expose via sysfs properties */ char *name; +/* We can notify apps of host connect / disconnect events via SIGIO */ +struct fasync_struct *async_queue; +/* The 'id' to identify the port with the Host */ u32 id;
@@ -719,6 +722,14 @@ static int port_fops_open(struct inode *inode, struct file *filp)return 0 ; } +static int port_fops_fasync (int fd,struct file *filp,int mode) +{ +struct port *port; + + port = filp->private_data; +return fasync_helper (fd, filp, mode, &port->async_queue); +} +/* * The file operations that we support: programs in the guest can open * a console device, read from it, write to it, poll for data and
@@ -732,6 +743,7 @@ static const struct file_operations port_fops = { .write = port_fops_write, .poll = port_fops_poll, .release = port_fops_release, + .fasync = port_fops_fasync, };/*
@@ -1011,6 +1023,7 @@ static int add_port(struct ports_device *portdev, u32 id) port->name =NULL ; port->inbuf =NULL ; port->cons.hvc =NULL ; + port->async_queue =NULL ; port->cons.ws.ws_row = port->cons.ws.ws_col =0 ;
@@ -1234,6 +1247,13 @@ static void handle_control_message(struct ports_device *portdev,spin_lock_irq (&port->outvq_lock);reclaim_consumed_buffers (port);spin_unlock_irq (&port->outvq_lock); + +/* +* If the guest is connected, it'll be interested in +* knowing the host connection state changed. +*/ +if (port->async_queue && port->guest_connected) +kill_fasync (&port->async_queue,SIGIO ,POLL_OUT );break ;case VIRTIO_CONSOLE_PORT_NAME :/*
Signature · 1 line
1.7.2.2
PATCH 4/4 virtio: console: Send SIGIO on new data arrival on ports
In reply to Amit ShahSend a SIGIO signal when new data arrives on a port. This is sent only when the process has requested for the signal to be sent using fcntl().
--- drivers/char/virtio_console.c | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-)
drivers/char/virtio_console.c +4 -0
@@ -1350,6 +1350,10 @@ static void in_intr(struct virtqueue *vq)wake_up_interruptible (&port->waitqueue); +/* Send a SIGIO indicating new data in case the process asked for it */ +if (port->async_queue && port->guest_connected) +kill_fasync (&port->async_queue,SIGIO ,POLL_IN ); +if (is_console_port (port) &&hvc_poll (port->cons.hvc))hvc_kick (); }
Signature · 1 line
1.7.2.2
Quoted 6 lines · Amit Shah
Hi Rusty,
The main thing in these patches is the introduction of injecting SIGIO on host-side connect/disconnect events and when new data is available for ports.
Quoted 7 lines
The first two patches fix bugs that I haven't seen, but look like the right thing to do.
These have been tested extensively using the test-virtserial test suite.
Please apply,
Since you haven't picked this up already, I'll send a new series that has more fixes and another call to SIGIO. I'll also split up the series in two patchsets, one for hot-unplug related fixes and one for the SIGIO.
Amit