From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754888Ab3CKVP2 (ORCPT ); Mon, 11 Mar 2013 17:15:28 -0400 Received: from mailout01.c08.mtsvc.net ([205.186.168.189]:33341 "EHLO mailout01.c08.mtsvc.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753530Ab3CKVPO (ORCPT ); Mon, 11 Mar 2013 17:15:14 -0400 From: Peter Hurley To: Greg Kroah-Hartman , Jiri Slaby Cc: Sasha Levin , Dave Jones , Sebastian Andrzej Siewior , Shawn Guo , linux-kernel@vger.kernel.org, linux-serial@vger.kernel.org, Peter Hurley Subject: [PATCH v5 12/44] n_tty: Fully initialize ldisc before restarting buffer work Date: Mon, 11 Mar 2013 16:44:32 -0400 Message-Id: <1363034704-28036-13-git-send-email-peter@hurleysoftware.com> X-Mailer: git-send-email 1.8.1.2 In-Reply-To: <1363034704-28036-1-git-send-email-peter@hurleysoftware.com> References: <1361390599-15195-1-git-send-email-peter@hurleysoftware.com> <1363034704-28036-1-git-send-email-peter@hurleysoftware.com> X-Authenticated-User: 125194 peter@hurleysoftware.com Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Buffer work may already be pending when the n_tty ldisc is re-opened, eg., when setting the ldisc (via TIOCSETD ioctl) and when hanging up the tty. Since n_tty_set_room() may restart buffer work, first ensure the ldisc is completely initialized. Factor n_tty_set_room() out of reset_buffer_flags() (only 2 callers) and reorganize n_tty_open() to set termios last; buffer work will be restarted there if necessary, after the char_map is properly initialized. Fixes this WARNING: [ 549.561769] ------------[ cut here ]------------ [ 549.598755] WARNING: at drivers/tty/n_tty.c:160 n_tty_set_room+0xff/0x130() [ 549.604058] scheduling buffer work for halted ldisc [ 549.607741] Pid: 9417, comm: trinity-child28 Tainted: G D W 3.7.0-next-20121217-sasha-00023-g8689ef9 #219 [ 549.652580] Call Trace: [ 549.662754] [] ? n_tty_set_room+0xff/0x130 [ 549.665458] [] warn_slowpath_common+0x87/0xb0 [ 549.668257] [] warn_slowpath_fmt+0x41/0x50 [ 549.671007] [] n_tty_set_room+0xff/0x130 [ 549.673268] [] reset_buffer_flags+0x137/0x150 [ 549.675607] [] n_tty_open+0x131/0x1c0 [ 549.677699] [] tty_ldisc_open.isra.5+0x54/0x70 [ 549.680147] [] tty_ldisc_hangup+0x11f/0x1e0 [ 549.682409] [] __tty_hangup+0x137/0x440 [ 549.684634] [] tty_vhangup+0x9/0x10 [ 549.686443] [] pty_close+0x14c/0x160 [ 549.688446] [] tty_release+0xd5/0x490 [ 549.690460] [] __fput+0x122/0x250 [ 549.692577] [] ____fput+0x9/0x10 [ 549.694534] [] task_work_run+0xb2/0xf0 [ 549.696349] [] do_exit+0x36d/0x580 [ 549.698286] [] ? syscall_trace_enter+0x24/0x2e0 [ 549.702729] [] do_group_exit+0x8a/0xc0 [ 549.706775] [] sys_exit_group+0x12/0x20 [ 549.711088] [] tracesys+0xe1/0xe6 [ 549.728001] ---[ end trace 73eb41728f11f87e ]--- Reported-by: Sasha Levin Signed-off-by: Peter Hurley --- drivers/tty/n_tty.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index a786f4e..66ce178 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -219,9 +219,8 @@ static void check_unthrottle(struct tty_struct *tty) * Locking: tty_read_lock for read fields. */ -static void reset_buffer_flags(struct tty_struct *tty) +static void reset_buffer_flags(struct n_tty_data *ldata) { - struct n_tty_data *ldata = tty->disc_data; unsigned long flags; raw_spin_lock_irqsave(&ldata->read_lock, flags); @@ -234,7 +233,6 @@ static void reset_buffer_flags(struct tty_struct *tty) ldata->canon_head = ldata->canon_data = ldata->erasing = 0; bitmap_zero(ldata->read_flags, N_TTY_BUF_SIZE); - n_tty_set_room(tty); } static void n_tty_packet_mode_flush(struct tty_struct *tty) @@ -262,7 +260,8 @@ static void n_tty_packet_mode_flush(struct tty_struct *tty) static void n_tty_flush_buffer(struct tty_struct *tty) { - reset_buffer_flags(tty); + reset_buffer_flags(tty->disc_data); + n_tty_set_room(tty); if (tty->link) n_tty_packet_mode_flush(tty); @@ -1654,14 +1653,14 @@ static int n_tty_open(struct tty_struct *tty) goto err_free_bufs; tty->disc_data = ldata; - /* indicate buffer work may resume */ - clear_bit(TTY_LDISC_HALTED, &tty->flags); - reset_buffer_flags(tty); - tty_unthrottle(tty); + reset_buffer_flags(tty->disc_data); ldata->column = 0; - n_tty_set_termios(tty, NULL); tty->minimum_to_wake = 1; tty->closing = 0; + /* indicate buffer work may resume */ + clear_bit(TTY_LDISC_HALTED, &tty->flags); + n_tty_set_termios(tty, NULL); + tty_unthrottle(tty); return 0; err_free_bufs: -- 1.8.1.2