From 22474ed69f7449d8b405e3799d330c9c1bf36d8f Mon Sep 17 00:00:00 2001 From: Fabian Keil Date: Tue, 16 Jun 2015 15:07:06 +0200 Subject: [PATCH 132/257] deadlkres(): (Try to) optionally unlock deadlocked processes to work around USB deadlocks This is work in progress and hasn't been properly tested yet. Obtained from: ElectroBSD --- sys/kern/kern_clock.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/sys/kern/kern_clock.c b/sys/kern/kern_clock.c index 7734e81518af..7ab290ca4863 100644 --- a/sys/kern/kern_clock.c +++ b/sys/kern/kern_clock.c @@ -178,6 +178,7 @@ static const char *blessed[] = { }; static int slptime_threshold = 1800; static int blktime_threshold = 900; +static int unlock_deadlocked_processes = 0; static int sleepfreq = 3; static void @@ -236,9 +237,15 @@ deadlkres(void) * turnstile. */ PROC_UNLOCK(p); - sx_sunlock(&allproc_lock); + if (unlock_deadlocked_processes == 0) { + sx_sunlock(&allproc_lock); panic("%s: possible deadlock detected for %p, blocked for %d ticks\n", - __func__, td, tticks); + __func__, td, tticks); + } else { + printf("%s: possible deadlock detected for %p, blocked for %d ticks. " + "Unlocking process to see what happens. Good luck.\n", __func__, td, tticks); + TD_CLR_LOCK(td); + } } } else if (TD_IS_SLEEPING(td) && TD_ON_SLEEPQ(td)) { @@ -282,9 +289,15 @@ deadlkres(void) continue; } PROC_UNLOCK(p); - sx_sunlock(&allproc_lock); + if (unlock_deadlocked_processes == 0) { + sx_sunlock(&allproc_lock); panic("%s: possible deadlock detected for %p, blocked for %d ticks\n", - __func__, td, tticks); + __func__, td, tticks); + } else { + printf("%s: possible deadlock detected for %p, blocked for %d ticks. " + "Unlocking process to see what happens. Good luck.\n", __func__, td, tticks); + TD_CLR_LOCK(td); + } } } else thread_unlock(td); @@ -316,6 +329,11 @@ SYSCTL_INT(_debug_deadlkres, OID_AUTO, blktime_threshold, CTLFLAG_RW, "Number of seconds within is valid to block on a turnstile"); SYSCTL_INT(_debug_deadlkres, OID_AUTO, sleepfreq, CTLFLAG_RW, &sleepfreq, 0, "Number of seconds between any deadlock resolver thread run"); +SYSCTL_INT(_debug_deadlkres, OID_AUTO, + unlock_deadlocked_processes_and_see_what_happens, + CTLFLAG_RW, &unlock_deadlocked_processes, 0, + "'Resolve' deadlocks by merely unlocking the locked process. " + "May cause permanent data corruption."); #endif /* DEADLKRES */ void -- 2.11.0