Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 47492
b: refs/heads/master
c: 8b6312f
h: refs/heads/master
v: v3
  • Loading branch information
Eric W. Biederman authored and Linus Torvalds committed Feb 11, 2007
1 parent b3bfbda commit d171fa2
Show file tree
Hide file tree
Showing 7 changed files with 46 additions and 19 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 0a7b35cb18c52d651f6ed9cd59edc979200ab880
refs/heads/master: 8b6312f4dcc1efe7975731b6c47dd134282bd9ac
12 changes: 3 additions & 9 deletions trunk/drivers/char/keyboard.c
Original file line number Diff line number Diff line change
Expand Up @@ -595,15 +595,9 @@ static void fn_spawn_con(struct vc_data *vc)

static void fn_SAK(struct vc_data *vc)
{
struct tty_struct *tty = vc->vc_tty;

/*
* SAK should also work in all raw modes and reset
* them properly.
*/
if (tty)
do_SAK(tty);
reset_vc(vc);
struct work_struct *SAK_work = &vc_cons[fg_console].SAK_work;
PREPARE_WORK(SAK_work, vc_SAK);
schedule_work(SAK_work);
}

static void fn_null(struct vc_data *vc)
Expand Down
6 changes: 3 additions & 3 deletions trunk/drivers/char/sysrq.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,9 @@ static struct sysrq_key_op sysrq_loglevel_op = {
#ifdef CONFIG_VT
static void sysrq_handle_SAK(int key, struct tty_struct *tty)
{
if (tty)
do_SAK(tty);
reset_vc(vc_cons[fg_console].d);
struct work_struct *SAK_work = &vc_cons[fg_console].SAK_work;
PREPARE_WORK(SAK_work, vc_SAK);
schedule_work(SAK_work);
}
static struct sysrq_key_op sysrq_SAK_op = {
.handler = sysrq_handle_SAK,
Expand Down
13 changes: 9 additions & 4 deletions trunk/drivers/char/tty_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -3324,10 +3324,8 @@ int tty_ioctl(struct inode * inode, struct file * file,
* Nasty bug: do_SAK is being called in interrupt context. This can
* deadlock. We punt it up to process context. AKPM - 16Mar2001
*/
static void __do_SAK(struct work_struct *work)
void __do_SAK(struct tty_struct *tty)
{
struct tty_struct *tty =
container_of(work, struct tty_struct, SAK_work);
#ifdef TTY_SOFT_SAK
tty_hangup(tty);
#else
Expand Down Expand Up @@ -3394,6 +3392,13 @@ static void __do_SAK(struct work_struct *work)
#endif
}

static void do_SAK_work(struct work_struct *work)
{
struct tty_struct *tty =
container_of(work, struct tty_struct, SAK_work);
__do_SAK(tty);
}

/*
* The tq handling here is a little racy - tty->SAK_work may already be queued.
* Fortunately we don't need to worry, because if ->SAK_work is already queued,
Expand All @@ -3404,7 +3409,7 @@ void do_SAK(struct tty_struct *tty)
{
if (!tty)
return;
PREPARE_WORK(&tty->SAK_work, __do_SAK);
PREPARE_WORK(&tty->SAK_work, do_SAK_work);
schedule_work(&tty->SAK_work);
}

Expand Down
28 changes: 26 additions & 2 deletions trunk/drivers/char/vt_ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -672,7 +672,8 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
vc->vt_mode = tmp;
/* the frsig is ignored, so we set it to 0 */
vc->vt_mode.frsig = 0;
put_pid(xchg(&vc->vt_pid, get_pid(task_pid(current))));
put_pid(vc->vt_pid);
vc->vt_pid = get_pid(task_pid(current));
/* no switch is required -- saw@shade.msu.ru */
vc->vt_newvt = -1;
release_console_sem();
Expand Down Expand Up @@ -1063,12 +1064,35 @@ void reset_vc(struct vc_data *vc)
vc->vt_mode.relsig = 0;
vc->vt_mode.acqsig = 0;
vc->vt_mode.frsig = 0;
put_pid(xchg(&vc->vt_pid, NULL));
put_pid(vc->vt_pid);
vc->vt_pid = NULL;
vc->vt_newvt = -1;
if (!in_interrupt()) /* Via keyboard.c:SAK() - akpm */
reset_palette(vc);
}

void vc_SAK(struct work_struct *work)
{
struct vc *vc_con =
container_of(work, struct vc, SAK_work);
struct vc_data *vc;
struct tty_struct *tty;

acquire_console_sem();
vc = vc_con->d;
if (vc) {
tty = vc->vc_tty;
/*
* SAK should also work in all raw modes and reset
* them properly.
*/
if (tty)
__do_SAK(tty);
reset_vc(vc);
}
release_console_sem();
}

/*
* Performs the back end of a vt switch
*/
Expand Down
3 changes: 3 additions & 0 deletions trunk/include/linux/console_struct.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

#include <linux/wait.h>
#include <linux/vt.h>
#include <linux/workqueue.h>

struct vt_struct;

Expand Down Expand Up @@ -103,13 +104,15 @@ struct vc_data {

struct vc {
struct vc_data *d;
struct work_struct SAK_work;

/* might add scrmem, vt_struct, kbd at some time,
to have everything in one place - the disadvantage
would be that vc_cons etc can no longer be static */
};

extern struct vc vc_cons [MAX_NR_CONSOLES];
extern void vc_SAK(struct work_struct *work);

#define CUR_DEF 0
#define CUR_NONE 1
Expand Down
1 change: 1 addition & 0 deletions trunk/include/linux/tty.h
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,7 @@ extern void tty_vhangup(struct tty_struct * tty);
extern void tty_unhangup(struct file *filp);
extern int tty_hung_up_p(struct file * filp);
extern void do_SAK(struct tty_struct *tty);
extern void __do_SAK(struct tty_struct *tty);
extern void disassociate_ctty(int priv);
extern void tty_flip_buffer_push(struct tty_struct *tty);
extern speed_t tty_get_baud_rate(struct tty_struct *tty);
Expand Down

0 comments on commit d171fa2

Please sign in to comment.