mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-04-22 06:13:59 +00:00
tty: hvc: hvc_poll() break hv read loop
Avoid looping with the spinlock held while there is read data being returned from the hv driver. Instead note if the entire size returned by tty_buffer_request_room was read, and request another read poll. This limits the critical section lengths, and provides more even service to other consoles in case there is a pathological condition. Signed-off-by: Nicholas Piggin <npiggin@gmail.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
This commit is contained in:
parent
a9bf5c8a27
commit
ec97eaad13
1 changed files with 51 additions and 49 deletions
|
@ -592,7 +592,7 @@ static u32 timeout = MIN_TIMEOUT;
|
||||||
int hvc_poll(struct hvc_struct *hp)
|
int hvc_poll(struct hvc_struct *hp)
|
||||||
{
|
{
|
||||||
struct tty_struct *tty;
|
struct tty_struct *tty;
|
||||||
int i, n, poll_mask = 0;
|
int i, n, count, poll_mask = 0;
|
||||||
char buf[N_INBUF] __ALIGNED__;
|
char buf[N_INBUF] __ALIGNED__;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
int read_total = 0;
|
int read_total = 0;
|
||||||
|
@ -618,7 +618,7 @@ int hvc_poll(struct hvc_struct *hp)
|
||||||
|
|
||||||
/* Now check if we can get data (are we throttled ?) */
|
/* Now check if we can get data (are we throttled ?) */
|
||||||
if (tty_throttled(tty))
|
if (tty_throttled(tty))
|
||||||
goto throttled;
|
goto out;
|
||||||
|
|
||||||
/* If we aren't notifier driven and aren't throttled, we always
|
/* If we aren't notifier driven and aren't throttled, we always
|
||||||
* request a reschedule
|
* request a reschedule
|
||||||
|
@ -627,13 +627,13 @@ int hvc_poll(struct hvc_struct *hp)
|
||||||
poll_mask |= HVC_POLL_READ;
|
poll_mask |= HVC_POLL_READ;
|
||||||
|
|
||||||
/* Read data if any */
|
/* Read data if any */
|
||||||
for (;;) {
|
|
||||||
int count = tty_buffer_request_room(&hp->port, N_INBUF);
|
count = tty_buffer_request_room(&hp->port, N_INBUF);
|
||||||
|
|
||||||
/* If flip is full, just reschedule a later read */
|
/* If flip is full, just reschedule a later read */
|
||||||
if (count == 0) {
|
if (count == 0) {
|
||||||
poll_mask |= HVC_POLL_READ;
|
poll_mask |= HVC_POLL_READ;
|
||||||
break;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
n = hp->ops->get_chars(hp->vtermno, buf, count);
|
n = hp->ops->get_chars(hp->vtermno, buf, count);
|
||||||
|
@ -651,8 +651,9 @@ int hvc_poll(struct hvc_struct *hp)
|
||||||
*/
|
*/
|
||||||
poll_mask |= HVC_POLL_READ;
|
poll_mask |= HVC_POLL_READ;
|
||||||
}
|
}
|
||||||
break;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < n; ++i) {
|
for (i = 0; i < n; ++i) {
|
||||||
#ifdef CONFIG_MAGIC_SYSRQ
|
#ifdef CONFIG_MAGIC_SYSRQ
|
||||||
if (hp->index == hvc_console.index) {
|
if (hp->index == hvc_console.index) {
|
||||||
|
@ -673,10 +674,11 @@ int hvc_poll(struct hvc_struct *hp)
|
||||||
#endif /* CONFIG_MAGIC_SYSRQ */
|
#endif /* CONFIG_MAGIC_SYSRQ */
|
||||||
tty_insert_flip_char(&hp->port, buf[i], 0);
|
tty_insert_flip_char(&hp->port, buf[i], 0);
|
||||||
}
|
}
|
||||||
|
if (n == count)
|
||||||
|
poll_mask |= HVC_POLL_READ;
|
||||||
|
read_total = n;
|
||||||
|
|
||||||
read_total += n;
|
out:
|
||||||
}
|
|
||||||
throttled:
|
|
||||||
/* Wakeup write queue if necessary */
|
/* Wakeup write queue if necessary */
|
||||||
if (hp->do_wakeup) {
|
if (hp->do_wakeup) {
|
||||||
hp->do_wakeup = 0;
|
hp->do_wakeup = 0;
|
||||||
|
|
Loading…
Add table
Reference in a new issue