Commit c0719c5a authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] con_open() speedup/cleanup

con_open() is called on every open of the tty, even if the tty is already all
set up.  We only need to do that initialisation if the tty is being set up
for the very first time (tty->count == 1).

So do that: check for tty_count == 1 inside console_sem() and if so, bypass
all the unnecessary initialisation.



Note that this patch reintroduces the con_close()-vs-init_dev() race+oops. 
This is because that oops is accidentally prevented because when it happens,
con_open() reinstalls tty->driver_data even when tty->count > 1.

But that's bogus, and when the race happens we end up running
vcs_make_devfs() and vcs_remove_devfs() against the same console at the same
time, producing indeterminate results.

So the race needs to be fixed again, for real.
parent 49b8290a
...@@ -2454,32 +2454,30 @@ static void con_flush_chars(struct tty_struct *tty) ...@@ -2454,32 +2454,30 @@ static void con_flush_chars(struct tty_struct *tty)
/* /*
* Allocate the console screen memory. * Allocate the console screen memory.
*/ */
static int con_open(struct tty_struct *tty, struct file * filp) static int con_open(struct tty_struct *tty, struct file *filp)
{ {
unsigned int currcons; unsigned int currcons = tty->index;
int i; int ret = 0;
currcons = tty->index;
acquire_console_sem(); acquire_console_sem();
i = vc_allocate(currcons); if (tty->count == 1) {
if (i) { ret = vc_allocate(currcons);
release_console_sem(); if (ret == 0) {
return i; vt_cons[currcons]->vc_num = currcons;
tty->driver_data = vt_cons[currcons];
vc_cons[currcons].d->vc_tty = tty;
if (!tty->winsize.ws_row && !tty->winsize.ws_col) {
tty->winsize.ws_row = video_num_lines;
tty->winsize.ws_col = video_num_columns;
}
release_console_sem();
vcs_make_devfs(tty);
return ret;
}
} }
vt_cons[currcons]->vc_num = currcons;
tty->driver_data = vt_cons[currcons];
vc_cons[currcons].d->vc_tty = tty;
release_console_sem(); release_console_sem();
return ret;
if (!tty->winsize.ws_row && !tty->winsize.ws_col) {
tty->winsize.ws_row = video_num_lines;
tty->winsize.ws_col = video_num_columns;
}
if (tty->count == 1)
vcs_make_devfs(tty);
return 0;
} }
static void con_close(struct tty_struct *tty, struct file *filp) static void con_close(struct tty_struct *tty, struct file *filp)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment