summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKyle McMartin <kyle@mcmartin.ca>2010-11-26 10:15:29 -0500
committerKyle McMartin <kyle@mcmartin.ca>2010-11-26 10:15:29 -0500
commit2f05b4a2c9603413e1b3832b758d132a24929ec1 (patch)
tree35f57ed267b4034d42069ec437d07a9a8f4c0e18
parentc3e06ee55aad889b162aa78277b521445347cc75 (diff)
downloadkernel-2f05b4a2c9603413e1b3832b758d132a24929ec1.tar.gz
kernel-2f05b4a2c9603413e1b3832b758d132a24929ec1.tar.xz
kernel-2f05b4a2c9603413e1b3832b758d132a24929ec1.zip
Linux 2.6.37-rc3-git2
-rw-r--r--config-generic3
-rw-r--r--kernel.spec9
-rw-r--r--tty-dont-allow-reopen-when-ldisc-is-changing.patch84
3 files changed, 95 insertions, 1 deletions
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 <kyle@redhat.com> 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 <kyle@redhat.com> 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 <jslaby@suse.cz>
+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:
+ [<ffffffff8103b189>] warn_slowpath_common+0x80/0x98
+ [<ffffffff8103b1b6>] warn_slowpath_null+0x15/0x17
+ [<ffffffff8128a3ab>] tty_open+0x2a2/0x49a
+ [<ffffffff810fd53f>] 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 <jslaby@suse.cz>
+Reported-by: <Valdis.Kletnieks@vt.edu>
+Cc: Kyle McMartin <kyle@mcmartin.ca>
+Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
+---
+ 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
+
+
+