Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 29 May 2015 16:26:08 +0000 (UTC)
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r283745 - head/sys/kern
Message-ID:  <201505291626.t4TGQ8mt050399@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kib
Date: Fri May 29 16:26:08 2015
New Revision: 283745
URL: https://svnweb.freebsd.org/changeset/base/283745

Log:
  When delivering a signal with default disposition to the thread,
  tdsigwakeup() increases the priority of the low-priority threads, to
  give them a chance to be terminated timely.  Also, kernel allows user
  to signal kernel processes.  The combined effect is that signalling
  idle process bump a priority of the selected delivery thread, which
  starts eating CPU.
  
  Check for the delivery thread be an idle thread and do not raise its
  priority then.
  
  The signal delivery to the kernel threads must be opt-in feature.
  Kernel thread should explicitely declare the ability to handle signals
  directed to it.  E.g., nfsd threads check for signal as an indication
  of exit request.
  
  Most threads do not handle signals at all, and queuing the signal to
  them causes odd side-effects.  Most innocent consequence is the memory
  leak due to queued ksiginfo, which is never deleted from the sigqueue.
  Code to prevent even queuing signals to the kernel threads is trivial,
  but it requires careful examination of each call to kproc/kthread
  creation to decide should the signalling be allowed.  The commit is a
  stop-gap measure which fixes the immediate case for now.
  
  PR:	200493
  Reported and tested by:	trasz
  Discussed with:	trasz, emaste
  Sponsored by:	The FreeBSD Foundation
  MFC after:	1 week

Modified:
  head/sys/kern/kern_sig.c

Modified: head/sys/kern/kern_sig.c
==============================================================================
--- head/sys/kern/kern_sig.c	Fri May 29 14:35:16 2015	(r283744)
+++ head/sys/kern/kern_sig.c	Fri May 29 16:26:08 2015	(r283745)
@@ -2368,9 +2368,12 @@ tdsigwakeup(struct thread *td, int sig, 
 	thread_lock(td);
 	/*
 	 * Bring the priority of a thread up if we want it to get
-	 * killed in this lifetime.
+	 * killed in this lifetime.  Be careful to avoid bumping the
+	 * priority of the idle thread, since we still allow to signal
+	 * kernel processes.
 	 */
-	if (action == SIG_DFL && (prop & SA_KILL) && td->td_priority > PUSER)
+	if (action == SIG_DFL && (prop & SA_KILL) != 0 &&
+	    td->td_priority > PUSER && !TD_IS_IDLETHREAD(td))
 		sched_prio(td, PUSER);
 	if (TD_ON_SLEEPQ(td)) {
 		/*
@@ -2408,7 +2411,7 @@ tdsigwakeup(struct thread *td, int sig, 
 		/*
 		 * Give low priority threads a better chance to run.
 		 */
-		if (td->td_priority > PUSER)
+		if (td->td_priority > PUSER && !TD_IS_IDLETHREAD(td))
 			sched_prio(td, PUSER);
 
 		wakeup_swapper = sleepq_abort(td, intrval);



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