From 29e76aef0abe949af1be4820e64fac4fac8448ca Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 14 Sep 2011 16:21:31 -0700 Subject: [PATCH] --- yaml --- r: 263818 b: refs/heads/master c: 7cf3cf21aac7d75d27e8e7cd039bd33d19fb300d h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/arch/um/drivers/line.c | 38 +++++++++++++++++++++++------------- 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/[refs] b/[refs] index b83ad78e9fbf..346f59c5321e 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 45cd5e2d4e632f55af1d6131f33b554c98f8b929 +refs/heads/master: 7cf3cf21aac7d75d27e8e7cd039bd33d19fb300d diff --git a/trunk/arch/um/drivers/line.c b/trunk/arch/um/drivers/line.c index 91bf18941ca4..364c8a15c4c3 100644 --- a/trunk/arch/um/drivers/line.c +++ b/trunk/arch/um/drivers/line.c @@ -721,43 +721,53 @@ struct winch { int pid; struct tty_struct *tty; unsigned long stack; + struct work_struct work; }; -static void free_winch(struct winch *winch, int free_irq_ok) +static void __free_winch(struct work_struct *work) { - int fd = winch->fd; - winch->fd = -1; - if (free_irq_ok) - free_irq(WINCH_IRQ, winch); - - list_del(&winch->list); + struct winch *winch = container_of(work, struct winch, work); + free_irq(WINCH_IRQ, winch); if (winch->pid != -1) os_kill_process(winch->pid, 1); - if (fd != -1) - os_close_file(fd); if (winch->stack != 0) free_stack(winch->stack, 0); kfree(winch); } +static void free_winch(struct winch *winch) +{ + int fd = winch->fd; + winch->fd = -1; + if (fd != -1) + os_close_file(fd); + list_del(&winch->list); + __free_winch(&winch->work); +} + static irqreturn_t winch_interrupt(int irq, void *data) { struct winch *winch = data; struct tty_struct *tty; struct line *line; + int fd = winch->fd; int err; char c; - if (winch->fd != -1) { - err = generic_read(winch->fd, &c, NULL); + if (fd != -1) { + err = generic_read(fd, &c, NULL); if (err < 0) { if (err != -EAGAIN) { + winch->fd = -1; + list_del(&winch->list); + os_close_file(fd); printk(KERN_ERR "winch_interrupt : " "read failed, errno = %d\n", -err); printk(KERN_ERR "fd %d is losing SIGWINCH " "support\n", winch->tty_fd); - free_winch(winch, 0); + INIT_WORK(&winch->work, __free_winch); + schedule_work(&winch->work); return IRQ_HANDLED; } goto out; @@ -829,7 +839,7 @@ static void unregister_winch(struct tty_struct *tty) list_for_each_safe(ele, next, &winch_handlers) { winch = list_entry(ele, struct winch, list); if (winch->tty == tty) { - free_winch(winch, 1); + free_winch(winch); break; } } @@ -845,7 +855,7 @@ static void winch_cleanup(void) list_for_each_safe(ele, next, &winch_handlers) { winch = list_entry(ele, struct winch, list); - free_winch(winch, 1); + free_winch(winch); } spin_unlock(&winch_handler_lock);