hvc: provide a flush operation, implement for opal console, and use in hvc console
Nicholas Piggin
reviewerRFC PATCH 1/1 hvc: provide a flush operation, implement for opal console, and use in hvc console
This patch is not quite polished and needs to be split out, but the idea is to move busy waits in hvc console drivers out from under locks and into the main hvc driver where it can sleep.
The flush op allows for a 0 timeout which reverts to spin wait behaviour to cater for polling cases. A default operation is used for drivers that don't supply one, and they should get some benefit too just from sleeping outside locks.
This applies on top of the recent series of opal console patches.
Before this patch it is possible to see large interrupts off delays caused by hvc_push->opal_put_chars_nonatomic->opal_flush_console despite the previous series moved the flush from under the opal driver's output lock, because hvc_push is called with the hvc lock.
This is an irqsoff trace collected after running dmesg from the OpenBMC console:
dmesg-8334 12d... 0us : _raw_spin_lock_irqsave dmesg-8334 12d... 0us : hvc_push <-hvc_write dmesg-8334 12d... 1us : opal_put_chars_nonatomic <-hvc_push dmesg-8334 12d... 1us : __opal_put_chars <-hvc_push dmesg-8334 12d... 2us : opal_flush_console <-__opal_put_chars dmesg-8334 12d... 4us!: udelay <-opal_flush_console dmesg-8334 12d... 787us : soft_nmi_interrupt <-soft_nmi_common dmesg-8334 12d... 787us : printk_nmi_enter <-soft_nmi_interrupt dmesg-8334 12d.Z. 788us : rcu_nmi_enter <-soft_nmi_interrupt dmesg-8334 12d.Z. 788us : rcu_nmi_exit <-soft_nmi_interrupt dmesg-8334 12d... 788us#: printk_nmi_exit <-soft_nmi_interrupt dmesg-8334 12d... 10005us*: udelay <-opal_flush_console dmesg-8334 12d... 20007us*: udelay <-opal_flush_console dmesg-8334 12d... 30020us*: udelay <-opal_flush_console dmesg-8334 12d... 40022us*: udelay <-opal_flush_console dmesg-8334 12d... 50023us*: udelay <-opal_flush_console dmesg-8334 12d... 60024us : opal_error_code <-opal_flush_console dmesg-8334 12d... 60025us : _raw_spin_unlock_irqrestore <-hvc_write dmesg-8334 12d... 60025us : _raw_spin_unlock_irqrestore dmesg-8334 12d... 60025us : trace_hardirqs_on <-_raw_spin_unlock_irqrestore dmesg-8334 12d... 60027us : <stack trace>
After this patch, the same operation does not show latency above the noise of an idle system (~400us).
Impossible to tell the responsiveness difference with my ping 200-400ms to the BMC. It's not noticably worse.
--- arch/powerpc/include/asm/opal.h | 1 + arch/powerpc/platforms/powernv/opal.c | 74 ++++++++++-------- drivers/tty/hvc/hvc_console.c | 106 ++++++++++++++++++++------ drivers/tty/hvc/hvc_console.h | 1 + drivers/tty/hvc/hvc_opal.c | 2 + 5 files changed, 129 insertions(+), 55 deletions(-)
arch/powerpc/include/asm/opal.h +1 -0
@@ -304,6 +304,7 @@ extern void opal_configure_cores(void);extern int opal_get_chars (uint32_t vtermno,char *buf,int count);extern int opal_put_chars (uint32_t vtermno,const char *buf,int total_len);extern int opal_put_chars_nonatomic (uint32_t vtermno,const char *buf,int total_len); +extern int opal_flush_chars (uint32_t vtermno,long timeout);extern int opal_flush_console (uint32_t vtermno);extern void hvc_opal_init_early (void );
arch/powerpc/platforms/powernv/opal.c +42 -32
109 lines not on this page · raw message
drivers/tty/hvc/hvc_console.c +83 -23
146 lines not on this page · raw message
drivers/tty/hvc/hvc_console.h +1 -0
@@ -54,6 +54,7 @@ struct hvc_struct {struct hv_ops {int (*get_chars)(uint32_t vtermno,char *buf,int count);int (*put_chars)(uint32_t vtermno,const char *buf,int count); +int (*flush)(uint32_t vtermno,long timeout);/* Callbacks for notification. Called in open, close and hangup */ int (*notifier_add)(struct hvc_struct *hp,int irq);
drivers/tty/hvc/hvc_opal.c +2 -0
@@ -52,6 +52,7 @@ static u32 hvc_opal_boot_termno;static const struct hv_ops hvc_opal_raw_ops = { .get_chars = opal_get_chars, .put_chars = opal_put_chars_nonatomic, + .flush = opal_flush_chars, .notifier_add = notifier_add_irq, .notifier_del = notifier_del_irq, .notifier_hangup = notifier_hangup_irq,
@@ -141,6 +142,7 @@ static int hvc_opal_hvsi_tiocmset(struct hvc_struct *hp, unsigned int set,static const struct hv_ops hvc_opal_hvsi_ops = { .get_chars = hvc_opal_hvsi_get_chars, .put_chars = hvc_opal_hvsi_put_chars, + .flush = opal_flush_chars, .notifier_add = hvc_opal_hvsi_open, .notifier_del = hvc_opal_hvsi_close, .notifier_hangup = hvc_opal_hvsi_hangup,
Signature · 1 line
2.17.0