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
522 return -EIO;522 return -EIO;
523 523
524 while (count > 0) {524 while (count > 0) {
525 int ret = 0;
526
525 spin_lock_irqsave(&hp->lock, flags);527 spin_lock_irqsave(&hp->lock, flags);
526 528
527 rsize = hp->outbuf_size - hp->n_outbuf;529 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
537 }539 }
538 540
539 if (hp->n_outbuf > 0)541 if (hp->n_outbuf > 0)
540 hvc_push(hp);542 ret = hvc_push(hp);
541 543
542 spin_unlock_irqrestore(&hp->lock, flags);544 spin_unlock_irqrestore(&hp->lock, flags);
543 545
546 if (!ret)
547 break;
548
544 if (count) {549 if (count) {
545 if (hp->n_outbuf > 0)550 if (hp->n_outbuf > 0)
546 hvc_flush(hp);551 hvc_flush(hp);
@@ -623,6 +628,15 @@ static int hvc_chars_in_buffer(struct tty_struct *tty) · 76 unmodified lines
623#define MAX_TIMEOUT (2000)628#define MAX_TIMEOUT (2000)
624static u32 timeout = MIN_TIMEOUT;629static u32 timeout = MIN_TIMEOUT;
625 630
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
626#define HVC_POLL_READ 0x00000001640#define HVC_POLL_READ 0x00000001
627#define HVC_POLL_WRITE 0x00000002641#define HVC_POLL_WRITE 0x00000002
628 642
@@ -669,8 +683,8 @@ static int __hvc_poll(struct hvc_struct *hp, bool may_sleep) · 40 unmodified lines
669 if (!hp->irq_requested)683 if (!hp->irq_requested)
670 poll_mask |= HVC_POLL_READ;684 poll_mask |= HVC_POLL_READ;
671 685
686 read_again:
672 /* Read data if any */687 /* Read data if any */
673
674 count = tty_buffer_request_room(&hp->port, N_INBUF);688 count = tty_buffer_request_room(&hp->port, N_INBUF);
675 689
676 /* If flip is full, just reschedule a later read */690 /* 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
717#endif /* CONFIG_MAGIC_SYSRQ */731#endif /* CONFIG_MAGIC_SYSRQ */
718 tty_insert_flip_char(&hp->port, buf[i], 0);732 tty_insert_flip_char(&hp->port, buf[i], 0);
719 }733 }
720 if (n == count)734 read_total += n;
721 poll_mask |= HVC_POLL_READ;735
722 read_total = n;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;
723 751
724 out:752 out:
725 /* Wakeup write queue if necessary */753 /* 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