From: Hendrik Brueckner <hidden> Date: 2008-10-14 09:15:46
Hello,
I work on a network-based hvc console backend for s390 that allows
to get "full-screen" terminal access to z/VM guest machines.
The solution consists of a HVC backend that provides the terminal interface;
and a tool to connect to the terminal via a z/VM specific communication
protocol.
The network-based backend differs in a few aspects from the notifier-based
model of the HVC console; because it has to deal with (dis)connects and must
take care of virtual tty hangups. Therefore, I would like to introduce a third
notifier for hangups (see patch 1).
Further I found out that if put_char() returns 0 in particular cases, the hvc
console starts to loop. I tried to address this problem with patch 3 and I hope
that it will work for all backends.
Finally, I would like to add a function that allows to resize the terminal
window of a HVC terminal (patch 4).
Here is an overview about the complete patch series:
Patch 1 adds a hangup notifier
Patch 2 adds tty driver flag TTY_DRIVER_RESET_TERMIOS
Patch 3 fixes a loop if put_char() returns 0
Patch 4 adds a function to resize the tty window
Patch 5 removes __devexit of hvc_remove() for use in __(dev)init sections
Any review feedback would be greatly appreciated.
Thank you in advance.
Regards,
Hendrik
--
Hendrik Brueckner
D/3303 Linux on System z Development
Tel: +49 7031 16-1073
Fax: +49 7031 16-3456
eMail: brueckner@linux.vnet.ibm.com
IBM Deutschland Research & Development GmbH, Schoenaicher Str. 220, 71032 Boeblingen
IBM Deutschland Research & Development GmbH
Vorsitzender des Aufsichtsrats: Martin Jetter
Geschaeftsfuehrung: Erich Baier
Sitz der Gesellschaft: Boeblingen
Registergericht: Amtsgericht Stuttgart, HRB 243294
From: Hendrik Brueckner <hidden> Date: 2008-10-14 09:14:26
From: Hendrik Brueckner <redacted>
Removed __devexit annotation of hvc_remove() to avoid a section mismatch
if the backend initialization fails and hvc_remove() must be used to
clean up allocated hvc structs (called in section __init or __devinit).
Acked-by: Christian Borntraeger <redacted>
Signed-off-by: Hendrik Brueckner <redacted>
---
drivers/char/hvc_console.c | 2 +-
drivers/char/hvc_console.h | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
@@ -81,7 +81,7 @@ extern int hvc_instantiate(uint32_t vterexternstructhvc_struct*__devinithvc_alloc(uint32_tvtermno,intdata,structhv_ops*ops,intoutbuf_size);/* remove a vterm from hvc tty operation (module_exit or hotplug remove) */-externint__devexithvc_remove(structhvc_struct*hp);+externinthvc_remove(structhvc_struct*hp);/* data available */inthvc_poll(structhvc_struct*hp);
--
Hendrik Brueckner
D/3303 Linux on System z Development
Tel: +49 7031 16-1073
Fax: +49 7031 16-3456
eMail: brueckner@linux.vnet.ibm.com
IBM Deutschland Research & Development GmbH, Schoenaicher Str. 220, 71032 Boeblingen
IBM Deutschland Research & Development GmbH
Vorsitzender des Aufsichtsrats: Martin Jetter
Geschaeftsfuehrung: Erich Baier
Sitz der Gesellschaft: Boeblingen
Registergericht: Amtsgericht Stuttgart, HRB 243294
From: Hendrik Brueckner <hidden> Date: 2008-10-14 09:14:39
From: Hendrik Brueckner <redacted>
If put_char() routine of a hvc console backend returns 0, then the
hvc console starts looping in the following scenarios:
1. hvc_console_print()
If put_char() returns 0 then the while loop may loop forever.
I have added the missing check for 0 to throw away console messages.
2. khvcd may loop:
The thread calls hvc_poll() --> hvc_push()... if there are still
buffered data then the HVC_POLL_WRITE bit is set and causes the
khvcd thread to loop (if yield() returns immediately).
However, instead of looping, the khvcd thread could sleep for
MIN_TIMEOUT (doing the same as for get_chars()).
The MIN_TIMEOUT is set if hvc_push() was not able to write
data to the backend. If data has been written, the timeout is
set to 0 to immediately re-schedule hvc_poll().
Reviewed-by: Christian Borntraeger <redacted>
Tested-by: Christian Borntraeger <redacted> (virtio_console)
Signed-off-by: Hendrik Brueckner <redacted>
---
drivers/char/hvc_console.c | 20 +++++++++++---------
1 file changed, 11 insertions(+), 9 deletions(-)
@@ -538,16 +540,20 @@ int hvc_poll(struct hvc_struct *hp)charbuf[N_INBUF]__ALIGNED__;unsignedlongflags;intread_total=0;+intwritten_total=0;spin_lock_irqsave(&hp->lock,flags);/* Push pending writes */if(hp->n_outbuf>0)-hvc_push(hp);+written_total=hvc_push(hp);/* Reschedule us if still some write pending */-if(hp->n_outbuf>0)+if(hp->n_outbuf>0){poll_mask|=HVC_POLL_WRITE;+/* If hvc_push() was not able to write, sleep a few msecs */+timeout=(written_total)?0:MIN_TIMEOUT;+}/* No tty attached, just skip */tty=hp->tty;
@@ -659,10 +665,6 @@ static int khvcd(void *unused)poll_mask|=HVC_POLL_READ;if(hvc_kicked)continue;-if(poll_mask&HVC_POLL_WRITE){-yield();-continue;-}set_current_state(TASK_INTERRUPTIBLE);if(!hvc_kicked){if(poll_mask==0)
--
Hendrik Brueckner
D/3303 Linux on System z Development
Tel: +49 7031 16-1073
Fax: +49 7031 16-3456
eMail: brueckner@linux.vnet.ibm.com
IBM Deutschland Research & Development GmbH, Schoenaicher Str. 220, 71032 Boeblingen
IBM Deutschland Research & Development GmbH
Vorsitzender des Aufsichtsrats: Martin Jetter
Geschaeftsfuehrung: Erich Baier
Sitz der Gesellschaft: Boeblingen
Registergericht: Amtsgericht Stuttgart, HRB 243294
From: Hendrik Brueckner <hidden> Date: 2008-10-14 09:15:59
From: Hendrik Brueckner <redacted>
After a tty hangup() or close() operation, processes might not reset the
termio settings to a sane state. In order to reset the termios to its
default settings the tty driver flag TTY_DRIVER_RESET_TERMIOS has been added.
TTY driver flag description from include/linux/tty_driver.h:
TTY_DRIVER_RESET_TERMIOS --- requests the tty layer to reset the
termios setting when the last process has closed the device.
Used for PTY's, in particular.
Acked-by: Christian Borntraeger <redacted>
Signed-off-by: Hendrik Brueckner <redacted>
---
drivers/char/hvc_console.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
@@ -796,7 +796,7 @@ static int hvc_init(void)drv->minor_start=HVC_MINOR;drv->type=TTY_DRIVER_TYPE_SYSTEM;drv->init_termios=tty_std_termios;-drv->flags=TTY_DRIVER_REAL_RAW;+drv->flags=TTY_DRIVER_REAL_RAW|TTY_DRIVER_RESET_TERMIOS;tty_set_operations(drv,&hvc_ops);/* Always start the kthread because there can be hotplug vty adapters
--
Hendrik Brueckner
D/3303 Linux on System z Development
Tel: +49 7031 16-1073
Fax: +49 7031 16-3456
eMail: brueckner@linux.vnet.ibm.com
IBM Deutschland Research & Development GmbH, Schoenaicher Str. 220, 71032 Boeblingen
IBM Deutschland Research & Development GmbH
Vorsitzender des Aufsichtsrats: Martin Jetter
Geschaeftsfuehrung: Erich Baier
Sitz der Gesellschaft: Boeblingen
Registergericht: Amtsgericht Stuttgart, HRB 243294
From: Hendrik Brueckner <hidden> Date: 2008-10-14 09:16:28
From: Hendrik Brueckner <redacted>
I have added a hangup notifier that can be used by hvc console
backends to handle a tty hangup. The default irq hangup notifier
calls the notifier_del_irq() for compatibility.
Acked-by: Christian Borntraeger <redacted>
Signed-off-by: Hendrik Brueckner <redacted>
---
drivers/char/hvc_console.c | 4 ++--
drivers/char/hvc_console.h | 4 +++-
drivers/char/hvc_irq.c | 5 +++++
drivers/char/hvc_iseries.c | 1 +
drivers/char/hvc_vio.c | 1 +
drivers/char/hvc_xen.c | 1 +
drivers/char/virtio_console.c | 1 +
7 files changed, 14 insertions(+), 3 deletions(-)
@@ -65,9 +65,10 @@ struct hv_ops {int(*get_chars)(uint32_tvtermno,char*buf,intcount);int(*put_chars)(uint32_tvtermno,constchar*buf,intcount);-/* Callbacks for notification. Called in open and close */+/* Callbacks for notification. Called in open, close and hangup */int(*notifier_add)(structhvc_struct*hp,intirq);void(*notifier_del)(structhvc_struct*hp,intirq);+void(*notifier_hangup)(structhvc_struct*hp,intirq);};/* Register a vterm and a slot index for use as a console (console_init) */
@@ -86,6 +87,7 @@ void hvc_kick(void);/* default notifier for irq based notification */externintnotifier_add_irq(structhvc_struct*hp,intdata);externvoidnotifier_del_irq(structhvc_struct*hp,intdata);+externvoidnotifier_hangup_irq(structhvc_struct*hp,intdata);#if defined(CONFIG_XMON) && defined(CONFIG_SMP)---a/drivers/char/hvc_irq.c2008-10-0816:08:40.000000000+0200+++b/drivers/char/hvc_irq.c2008-10-0910:30:13.000000000+0200
@@ -198,6 +198,7 @@ static int __devinit virtcons_probe(struvirtio_cons.put_chars=put_chars;virtio_cons.notifier_add=notifier_add_vio;virtio_cons.notifier_del=notifier_del_vio;+virtio_cons.notifier_hangup=notifier_del_vio;/* The first argument of hvc_alloc() is the virtual console number, so*weusezero.Thesecondargumentistheparameterforthe
--
Hendrik Brueckner
D/3303 Linux on System z Development
Tel: +49 7031 16-1073
Fax: +49 7031 16-3456
eMail: brueckner@linux.vnet.ibm.com
IBM Deutschland Research & Development GmbH, Schoenaicher Str. 220, 71032 Boeblingen
IBM Deutschland Research & Development GmbH
Vorsitzender des Aufsichtsrats: Martin Jetter
Geschaeftsfuehrung: Erich Baier
Sitz der Gesellschaft: Boeblingen
Registergericht: Amtsgericht Stuttgart, HRB 243294
From: Hendrik Brueckner <hidden> Date: 2008-10-14 09:16:44
From: Hendrik Brueckner <redacted>
The patch provides the hvc_resize() function to update the terminal
window dimensions (struct winsize) for a specified hvc console.
The function stores the new window size and schedules a function
that finally updates the tty winsize and signals the change to
user space (SIGWINCH).
Because the winsize update must acquire a mutex and might sleep,
the function is scheduled instead of being called from hvc_poll()
or khvcd.
Acked-by: Christian Borntraeger <redacted>
Signed-off-by: Hendrik Brueckner <redacted>
---
drivers/char/hvc_console.c | 61 +++++++++++++++++++++++++++++++++++++++++++++
drivers/char/hvc_console.h | 6 ++++
2 files changed, 67 insertions(+)
@@ -84,6 +87,9 @@ extern int __devexit hvc_remove(struct hinthvc_poll(structhvc_struct*hp);voidhvc_kick(void);+/* Resize hvc tty terminal window */+externvoidhvc_resize(structhvc_struct*hp,structwinsizews);+/* default notifier for irq based notification */externintnotifier_add_irq(structhvc_struct*hp,intdata);externvoidnotifier_del_irq(structhvc_struct*hp,intdata);
--
Hendrik Brueckner
D/3303 Linux on System z Development
Tel: +49 7031 16-1073
Fax: +49 7031 16-3456
eMail: brueckner@linux.vnet.ibm.com
IBM Deutschland Research & Development GmbH, Schoenaicher Str. 220, 71032 Boeblingen
IBM Deutschland Research & Development GmbH
Vorsitzender des Aufsichtsrats: Martin Jetter
Geschaeftsfuehrung: Erich Baier
Sitz der Gesellschaft: Boeblingen
Registergericht: Amtsgericht Stuttgart, HRB 243294
On Tue, 14 Oct 2008 11:12:49 +0200
Hendrik Brueckner [off-list ref] wrote:
From: Hendrik Brueckner <redacted>
After a tty hangup() or close() operation, processes might not reset the
termio settings to a sane state.
That is the job of the getty task normally. pty is special as the reissue
of the same pty is done as a new device (with new state).
Setting this on the hvc would parallel the PC vt console behaviour but
differ from most other ports.
Anyway its a policy question for PPC64 so if thats how you want it to work
Acked-by: Alan Cox <redacted>
See tty_do_resize() for all of this stuff in the latest git. If you can't
use tty_do_resize from your work queue then please let me know why as I'd
like everyone to be using one abstraction.
We also now have a "resize" operation for devices that want to react to a
resize from TIOCSWINSZ
From: Hendrik Brueckner <hidden> Date: 2008-10-14 15:02:24
On Tue, Oct 14, 2008 at 10:44:28AM +0100, Alan Cox wrote:
quoted
+ hp = container_of(work, struct hvc_struct, tty_resize);
+ if (!hp || !hp->tty)
+ return;
What locks hp->tty here, it can go NULL after the test on a hangup it
seems ?
You are right. Thanks.
See tty_do_resize() for all of this stuff in the latest git. If you can't
use tty_do_resize from your work queue then please let me know why as I'd
like everyone to be using one abstraction.
I have looked at it and I have corrected my patch to use tty_do_resize().
Since tty_do_resize() cannot be called holding the hp spinlock; the code uses
now tty_kref_get/put to keep track of the tty object. I am not sure if the
use of the kref's is correct here, so please let me know if there is a better
solution.
Thanks.
Regards,
Hendrik
[RFC PATCH 4/5 v2] hvc_console: Add tty window resizing using tty_do_resize()
From: Hendrik Brueckner <redacted>
The patch provides the hvc_resize() function to update the terminal
window dimensions (struct winsize) for a specified hvc console.
The function stores the new window size and schedules a function
that finally updates the tty winsize and signals the change to
user space (SIGWINCH).
Because the winsize update must acquire a mutex and might sleep,
the function is scheduled instead of being called from hvc_poll()
or khvcd.
This patch uses the tty_do_resize() routine from the tty layer.
A pending resize work is canceled in hvc_close() and hvc_hangup().
Signed-off-by: Hendrik Brueckner <redacted>
---
drivers/char/hvc_console.c | 58 +++++++++++++++++++++++++++++++++++++++++++++
drivers/char/hvc_console.h | 6 ++++
2 files changed, 64 insertions(+)
@@ -84,6 +87,9 @@ extern int __devexit hvc_remove(struct hinthvc_poll(structhvc_struct*hp);voidhvc_kick(void);+/* Resize hvc tty terminal window */+externvoidhvc_resize(structhvc_struct*hp,structwinsizews);+/* default notifier for irq based notification */externintnotifier_add_irq(structhvc_struct*hp,intdata);externvoidnotifier_del_irq(structhvc_struct*hp,intdata);
--
Hendrik Brueckner
D/3303 Linux on System z Development
Tel: +49 7031 16-1073
Fax: +49 7031 16-3456
eMail: brueckner@linux.vnet.ibm.com
IBM Deutschland Research & Development GmbH, Schoenaicher Str. 220, 71032 Boeblingen
IBM Deutschland Research & Development GmbH
Vorsitzender des Aufsichtsrats: Martin Jetter
Geschaeftsfuehrung: Erich Baier
Sitz der Gesellschaft: Boeblingen
Registergericht: Amtsgericht Stuttgart, HRB 243294
Since tty_do_resize() cannot be called holding the hp spinlock; the code uses
now tty_kref_get/put to keep track of the tty object. I am not sure if the
use of the kref's is correct here, so please let me know if there is a better
solution.
That looks right to me, hp->tty can go NULL but the tty object itself
will still have a reference even if the asynchronous events kick off late
From: Hendrik Brueckner <hidden> Date: 2008-10-16 11:10:06
Hello,
for the sake of completion, here are few more details why I have suggest to
add the TTY_DRIVER_RESET_TERMIOS flag:
On Tue, Oct 14, 2008 at 10:40:25AM +0100, Alan Cox wrote:
On Tue, 14 Oct 2008 11:12:49 +0200
Hendrik Brueckner [off-list ref] wrote:
quoted
After a tty hangup() or close() operation, processes might not reset the
termio settings to a sane state.
That is the job of the getty task normally. pty is special as the reissue
of the same pty is done as a new device (with new state).
During some testing, I have experienced that the bash alters few termios
settings before showing the bash prompt:
-
ioctl(0, TCGETS, {B38400 opost isig icanon echo ...}) = 0
ioctl(0, TCSETSW, {B38400 opost isig -icanon -echo ...}) = 0
write(2, "root@t6345050:~# ", 17) = 17
-
If the tty gets a hangup, the bash gets terminated but the settings still
remains after init has respawned the getty process.
For my network-based hvc backend, a tty_hangup() is caused by a disconnect.
I looked into the tty_io.c source and found out that the termios settings
are stored in an array of the tty driver struct and they remains unchanged
if a tty device is released and initialized again.
At tty device initialization, the tty_init_termios() set tty->termios to the
tty->driver->termios[tty->index].
The idea is to ensure that when a tty is initialized it has the
default (initial) termio settings; and that is actually done if
TTY_DRIVER_RESET_TERMIOS is set.
Anyhow the other possibility might be to always set the initial termios
when the tty is initialized (see patch below).
But I am not sure if that case is the general behavior of ttys.
Please let me know if there is a reason not to re-initialize the termios
of a new tty.
Thanks.
Best regards
Hendrik
Signed-off-by: Hendrik Brueckner <redacted>
---
drivers/char/tty_io.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
@@ -1243,10 +1243,9 @@ int tty_init_termios(struct tty_struct *tp=kzalloc(sizeof(structktermios[2]),GFP_KERNEL);if(tp==NULL)return-ENOMEM;-memcpy(tp,&tty->driver->init_termios,-sizeof(structktermios));tty->driver->termios[idx]=tp;}+memcpy(tp,&tty->driver->init_termios,sizeof(structktermios));tty->termios=tp;tty->termios_locked=tp+1;
--
Hendrik Brueckner
D/3303 Linux on System z Development
Tel: +49 7031 16-1073
Fax: +49 7031 16-3456
eMail: brueckner@linux.vnet.ibm.com
IBM Deutschland Research & Development GmbH, Schoenaicher Str. 220, 71032 Boeblingen
IBM Deutschland Research & Development GmbH
Vorsitzender des Aufsichtsrats: Martin Jetter
Geschaeftsfuehrung: Erich Baier
Sitz der Gesellschaft: Boeblingen
Registergericht: Amtsgericht Stuttgart, HRB 243294
From: Rusty Russell <hidden> Date: 2008-10-16 11:41:41
On Tuesday 14 October 2008 20:12:51 Hendrik Brueckner wrote:
From: Hendrik Brueckner <redacted>
The patch provides the hvc_resize() function to update the terminal
window dimensions (struct winsize) for a specified hvc console.
The function stores the new window size and schedules a function
that finally updates the tty winsize and signals the change to
user space (SIGWINCH).
Because the winsize update must acquire a mutex and might sleep,
the function is scheduled instead of being called from hvc_poll()
or khvcd.
I want this functionality for lguest, too. But I don't see anything which
uses this call yet? Are we going to use the config_change notifier from
virtio? (Which IIRC neither S/390 nor lguest have plumbed in).
Cheers,
Rusty.
From: Christian Borntraeger <hidden> Date: 2008-10-16 12:00:22
Am Donnerstag, 16. Oktober 2008 schrieb Rusty Russell:
quoted
The patch provides the hvc_resize() function to update the terminal
window dimensions (struct winsize) for a specified hvc console.
The function stores the new window size and schedules a function
that finally updates the tty winsize and signals the change to
user space (SIGWINCH).
Because the winsize update must acquire a mutex and might sleep,
the function is scheduled instead of being called from hvc_poll()
or khvcd.
I want this functionality for lguest, too. But I don't see anything which
uses this call yet? Are we going to use the config_change notifier from
virtio? (Which IIRC neither S/390 nor lguest have plumbed in).
I have some prototype patches for virtio_console, but did not find the time to
finish them.
Christian
For my network-based hvc backend, a tty_hangup() is caused by a disconnect.
If it is network backed then you probably do want
TTY_DRIVER_TERMIOS_RESET. For a normal serial type port getty is supposed
to sort the terminal settings out. So in your case it sounds like
resetting it is the right thing to do.
From: Benjamin Herrenschmidt <benh@kernel.crashing.org> Date: 2008-10-20 23:25:26
On Tue, 2008-10-14 at 11:12 +0200, Hendrik Brueckner wrote:
Hello,
I work on a network-based hvc console backend for s390 that allows
to get "full-screen" terminal access to z/VM guest machines.
The solution consists of a HVC backend that provides the terminal interface;
and a tool to connect to the terminal via a z/VM specific communication
protocol.
.../...
Hi !
What's the status with that patch serie ? Is this 2.6.28 material ?
Alan, are you ok with those ? Hendrik, have there been any respin other
than v2 of patch 4/5 ?
I can merge it via powerpc but it's getting late in the merge window...
Cheers,
Ben.
From: Hendrik Brueckner <hidden> Date: 2008-10-21 07:44:59
On Tue, Oct 21, 2008 at 10:23:37AM +1100, Benjamin Herrenschmidt wrote:
What's the status with that patch serie ? Is this 2.6.28 material ?
It is 2.6.28 material.
Alan, are you ok with those ? Hendrik, have there been any respin other
than v2 of patch 4/5 ?
The other patches have not been changed.
fyi: patch 1/5 (hangup notifier) applies successfully with an offset
of 2 lines due to commit eef2622a9fcfa964073333ea72c7c9cd20ad45e6
(hvc_console: Fix free_irq in spinlocked section).
I can merge it via powerpc but it's getting late in the merge window...
Thanks... that would be really great!
Regards
Hendrik
--
Hendrik Brueckner
D/3303 Linux on System z Development
Tel: +49 7031 16-1073
Fax: +49 7031 16-3456
eMail: brueckner@linux.vnet.ibm.com
IBM Deutschland Research & Development GmbH, Schoenaicher Str. 220, 71032 Boeblingen
IBM Deutschland Research & Development GmbH
Vorsitzender des Aufsichtsrats: Martin Jetter
Geschaeftsfuehrung: Erich Baier
Sitz der Gesellschaft: Boeblingen
Registergericht: Amtsgericht Stuttgart, HRB 243294