Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 28 Sep 2014 21:12:23 +0000 (UTC)
From:      Neel Natu <neel@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r272270 - head/sys/kern
Message-ID:  <201409282112.s8SLCNuA067731@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: neel
Date: Sun Sep 28 21:12:23 2014
New Revision: 272270
URL: http://svnweb.freebsd.org/changeset/base/272270

Log:
  tty_rel_free() can be called more than once for the same tty so make sure
  that the tty is dequeued from 'tty_list' only the first time.
  
  The panic below was seen when a revoke(2) was issued on an nmdm device.
  In this case there was also a thread that was blocked on a read(2) on the
  device. The revoke(2) woke up the blocked thread which would typically
  return an error to userspace. In this case the reader also held the last
  reference on the file descriptor so fdrop() ended up calling tty_rel_free()
  via ttydev_close().
  
  tty_rel_free() then tried to dequeue 'tp' again which led to the panic.
  
  panic: Bad link elm 0xfffff80042602400 prev->next != elm
  cpuid = 1
  KDB: stack backtrace:
  db_trace_self_wrapper() at db_trace_self_wrapper+0x2b/frame 0xfffffe00f9c90460
  kdb_backtrace() at kdb_backtrace+0x39/frame 0xfffffe00f9c90510
  vpanic() at vpanic+0x189/frame 0xfffffe00f9c90590
  panic() at panic+0x43/frame 0xfffffe00f9c905f0
  tty_rel_free() at tty_rel_free+0x29b/frame 0xfffffe00f9c90640
  ttydev_close() at ttydev_close+0x1f9/frame 0xfffffe00f9c90690
  devfs_close() at devfs_close+0x298/frame 0xfffffe00f9c90720
  VOP_CLOSE_APV() at VOP_CLOSE_APV+0x13c/frame 0xfffffe00f9c90770
  vn_close() at vn_close+0x194/frame 0xfffffe00f9c90810
  vn_closefile() at vn_closefile+0x48/frame 0xfffffe00f9c90890
  devfs_close_f() at devfs_close_f+0x2c/frame 0xfffffe00f9c908c0
  _fdrop() at _fdrop+0x29/frame 0xfffffe00f9c908e0
  sys_read() at sys_read+0x63/frame 0xfffffe00f9c90980
  amd64_syscall() at amd64_syscall+0x2b3/frame 0xfffffe00f9c90ab0
  Xfast_syscall() at Xfast_syscall+0xfb/frame 0xfffffe00f9c90ab0
  --- syscall (3, FreeBSD ELF64, sys_read), rip = 0x800b78d8a, rsp = 0x7fffffbfdaf8, rbp = 0x7fffffbfdb30 ---
  
  CR:		https://reviews.freebsd.org/D851
  Reviewed by:	glebius, ed
  Reported by:	Leon Dang
  Sponsored by:	Nahanni Systems
  MFC after:	1 week

Modified:
  head/sys/kern/tty.c

Modified: head/sys/kern/tty.c
==============================================================================
--- head/sys/kern/tty.c	Sun Sep 28 20:06:02 2014	(r272269)
+++ head/sys/kern/tty.c	Sun Sep 28 21:12:23 2014	(r272270)
@@ -1055,13 +1055,13 @@ tty_rel_free(struct tty *tp)
 	tp->t_dev = NULL;
 	tty_unlock(tp);
 
-	sx_xlock(&tty_list_sx);
-	TAILQ_REMOVE(&tty_list, tp, t_list);
-	tty_list_count--;
-	sx_xunlock(&tty_list_sx);
-
-	if (dev != NULL)
+	if (dev != NULL) {
+		sx_xlock(&tty_list_sx);
+		TAILQ_REMOVE(&tty_list, tp, t_list);
+		tty_list_count--;
+		sx_xunlock(&tty_list_sx);
 		destroy_dev_sched_cb(dev, tty_dealloc, tp);
+	}
 }
 
 void



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201409282112.s8SLCNuA067731>