From 2f05b4a2c9603413e1b3832b758d132a24929ec1 Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Fri, 26 Nov 2010 10:15:29 -0500 Subject: [PATCH] Linux 2.6.37-rc3-git2 --- config-generic | 3 +- kernel.spec | 9 ++ ...-allow-reopen-when-ldisc-is-changing.patch | 84 +++++++++++++++++++ 3 files changed, 95 insertions(+), 1 deletion(-) create mode 100644 tty-dont-allow-reopen-when-ldisc-is-changing.patch diff --git a/config-generic b/config-generic index 5b6b2912d..db67c5026 100644 --- a/config-generic +++ b/config-generic @@ -3810,7 +3810,8 @@ CONFIG_CGROUP_DEVICE=y CONFIG_CGROUP_FREEZER=y CONFIG_CGROUP_SCHED=y CONFIG_CGROUP_MEM_RES_CTLR=y -CONFIG_CGROUP_MEM_RES_CTLR_SWAP=y +CONFIG_CGROUP_MEM_RES_CTLR_SWAP=y # XXX disabled by default, pass 'swapaccount' +# CONFIG_CGROUP_MEM_RES_CTLR_SWAP_ENABLED is not set CONFIG_BLK_CGROUP=y # CONFIG_DEBUG_BLK_CGROUP is not set diff --git a/kernel.spec b/kernel.spec index c1cded595..9df0131bc 100644 --- a/kernel.spec +++ b/kernel.spec @@ -699,6 +699,8 @@ Patch12205: runtime_pm_fixups.patch Patch12303: dmar-disable-when-ricoh-multifunction.patch +Patch12400: tty-dont-allow-reopen-when-ldisc-is-changing.patch + %endif BuildRoot: %{_tmppath}/kernel-%{KVERREL}-root @@ -1287,6 +1289,9 @@ ApplyPatch runtime_pm_fixups.patch # rhbz#605888 ApplyPatch dmar-disable-when-ricoh-multifunction.patch +# rhbz#630464 +ApplyPatch tty-dont-allow-reopen-when-ldisc-is-changing.patch + # END OF PATCH APPLICATIONS %endif @@ -1901,6 +1906,10 @@ fi %changelog * Fri Nov 26 2010 Kyle McMartin 2.6.37-0.rc3.git2.1 - Linux 2.6.37-rc3-git2 +- CGROUP_MEM_RES_CTLR_SWAP_ENABLED is not set, so the cgroup memory + resource controller swap accounting is disabled by default. You can + enable it with 'swapaccount' if desired. +- TTY: don't allow reopen when ldisc is changing (rhbz#630464) * Wed Nov 24 2010 Kyle McMartin 2.6.37-0.rc3.git1.1 - Linux 2.6.37-rc3-git1 diff --git a/tty-dont-allow-reopen-when-ldisc-is-changing.patch b/tty-dont-allow-reopen-when-ldisc-is-changing.patch new file mode 100644 index 000000000..02d6746fc --- /dev/null +++ b/tty-dont-allow-reopen-when-ldisc-is-changing.patch @@ -0,0 +1,84 @@ +From jirislaby@gmail.com Thu Nov 25 12:16:42 2010 +From: Jiri Slaby +Subject: [PATCH 1/1] TTY: don't allow reopen when ldisc is changing +Date: Thu, 25 Nov 2010 18:16:23 +0100 + +There are many WARNINGs like the following reported nowadays: +WARNING: at drivers/tty/tty_io.c:1331 tty_open+0x2a2/0x49a() +Hardware name: Latitude E6500 +Modules linked in: +Pid: 1207, comm: plymouthd Not tainted 2.6.37-rc3-mmotm1123 #3 +Call Trace: + [] warn_slowpath_common+0x80/0x98 + [] warn_slowpath_null+0x15/0x17 + [] tty_open+0x2a2/0x49a + [] chrdev_open+0x11d/0x146 +... + +This means tty_reopen is called without TTY_LDISC set. For further +considerations, note tty_lock is held in tty_open. TTY_LDISC is cleared in: +1) __tty_hangup from tty_ldisc_hangup to tty_ldisc_enable. During this +section tty_lock is held. + +2) tty_release via tty_ldisc_release till the end of tty existence. If +tty->count <= 1, tty_lock is taken, TTY_CLOSING bit set and then +tty_ldisc_release called. tty_reopen checks TTY_CLOSING before checking +TTY_LDISC. + +3) tty_set_ldisc from tty_ldisc_halt to tty_ldisc_enable. We: + * take tty_lock, set TTY_LDISC_CHANGING, put tty_lock + * call tty_ldisc_halt (clear TTY_LDISC), tty_lock is _not_ held + * do some other work + * take tty_lock, call tty_ldisc_enable (set TTY_LDISC), put + tty_lock + +So the only option I see is 3). The solution is to check +TTY_LDISC_CHANGING along with TTY_CLOSING in tty_reopen. + +Nicely reproducible with two processes: +while (1) { + fd = open("/dev/ttyS1", O_RDWR); + if (fd < 0) { + warn("open"); + continue; + } + close(fd); +} +-------- +while (1) { + fd = open("/dev/ttyS1", O_RDWR); + ld1 = 0; ld2 = 2; + while (1) { + ioctl(fd, TIOCSETD, &ld1); + ioctl(fd, TIOCSETD, &ld2); + } + close(fd); +} + +Signed-off-by: Jiri Slaby +Reported-by: +Cc: Kyle McMartin +Cc: Alan Cox +--- + drivers/tty/tty_io.c | 3 ++- + 1 files changed, 2 insertions(+), 1 deletions(-) + +diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c +index c05c5af..878f6d6 100644 +--- a/drivers/tty/tty_io.c ++++ b/drivers/tty/tty_io.c +@@ -1310,7 +1310,8 @@ static int tty_reopen(struct tty_struct *tty) + { + struct tty_driver *driver = tty->driver; + +- if (test_bit(TTY_CLOSING, &tty->flags)) ++ if (test_bit(TTY_CLOSING, &tty->flags) || ++ test_bit(TTY_LDISC_CHANGING, &tty->flags)) + return -EIO; + + if (driver->type == TTY_DRIVER_TYPE_PTY && +-- +1.7.3.1 + + +