History

Merge tag 'tty-4.19-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty

Pull tty fixes from Greg KH: "Here are three small HVC tty driver fixes to resolve a reported regression from 4.19-rc1. All of these have been in linux-next for a while with no reported issues" * tag 'tty-4.19-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: tty: hvc: hvc_write() fix break condition tty: hvc: hvc_poll() fix read loop batching tty: hvc: hvc_poll() fix read loop hang

Linus Torvalds committed 8 years ago

Commit c284cf02 parents 45d9ab8 7f2bf781 file · +33 −5Browse files

Unified · Split

drivers/tty/hvc/hvc_console.c+33−5
@@ -522,6 +522,8 @@ static int hvc_write(struct tty_struct *tty, const unsigned char *buf, int count · 521 unmodified lines
522522 return -EIO;
523523
524524 while (count > 0) {
525+ int ret = 0;
526+
525527 spin_lock_irqsave(&hp->lock, flags);
526528
527529 rsize = hp->outbuf_size - hp->n_outbuf;
@@ -537,10 +539,13 @@ static int hvc_write(struct tty_struct *tty, const unsigned char *buf, int count · 9 unmodified lines
537539 }
538540
539541 if (hp->n_outbuf > 0)
540− hvc_push(hp);
542+ ret = hvc_push(hp);
541543
542544 spin_unlock_irqrestore(&hp->lock, flags);
543545
546+ if (!ret)
547+ break;
548+
544549 if (count) {
545550 if (hp->n_outbuf > 0)
546551 hvc_flush(hp);
@@ -623,6 +628,15 @@ static int hvc_chars_in_buffer(struct tty_struct *tty) · 76 unmodified lines
623628 #define MAX_TIMEOUT (2000)
624629 static u32 timeout = MIN_TIMEOUT;
625630
631+/*
632+ * Maximum number of bytes to get from the console driver if hvc_poll is
633+ * called from driver (and can't sleep). Any more than this and we break
634+ * and start polling with khvcd. This value was derived from from an OpenBMC
635+ * console with the OPAL driver that results in about 0.25ms interrupts off
636+ * latency.
637+ */
638+#define HVC_ATOMIC_READ_MAX 128
639+
626640 #define HVC_POLL_READ 0x00000001
627641 #define HVC_POLL_WRITE 0x00000002
628642
@@ -669,8 +683,8 @@ static int __hvc_poll(struct hvc_struct *hp, bool may_sleep) · 40 unmodified lines
669683 if (!hp->irq_requested)
670684 poll_mask |= HVC_POLL_READ;
671685
686+ read_again:
672687 /* Read data if any */
673−
674688 count = tty_buffer_request_room(&hp->port, N_INBUF);
675689
676690 /* If flip is full, just reschedule a later read */
@@ -717,9 +731,23 @@ static int __hvc_poll(struct hvc_struct *hp, bool may_sleep) · 40 unmodified lines
717731 #endif /* CONFIG_MAGIC_SYSRQ */
718732 tty_insert_flip_char(&hp->port, buf[i], 0);
719733 }
720− if (n == count)
721− poll_mask |= HVC_POLL_READ;
722− read_total = n;
734+ read_total += n;
735+
736+ if (may_sleep) {
737+ /* Keep going until the flip is full */
738+ spin_unlock_irqrestore(&hp->lock, flags);
739+ cond_resched();
740+ spin_lock_irqsave(&hp->lock, flags);
741+ goto read_again;
742+ } else if (read_total < HVC_ATOMIC_READ_MAX) {
743+ /* Break and defer if it's a large read in atomic */
744+ goto read_again;
745+ }
746+
747+ /*
748+ * Latency break, schedule another poll immediately.
749+ */
750+ poll_mask |= HVC_POLL_READ;
723751
724752 out:
725753 /* Wakeup write queue if necessary */

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t