summaryrefslogtreecommitdiffstats
path: root/sys/kern/subr_sleepqueue.c
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2013-02-06 17:06:51 +0000
committerjhb <jhb@FreeBSD.org>2013-02-06 17:06:51 +0000
commit0fee3f66b8449575ed4673125b12bfd592191d2d (patch)
treeb7c1d4516fbc8d227d8e9d82226ffe2268726c9c /sys/kern/subr_sleepqueue.c
parent85b0c7ccf995a662173c813d3e6cea1b62bee356 (diff)
downloadFreeBSD-src-0fee3f66b8449575ed4673125b12bfd592191d2d.zip
FreeBSD-src-0fee3f66b8449575ed4673125b12bfd592191d2d.tar.gz
Rework the handling of stop signals in the NFS client. The changes in
195702, 195703, and 195821 prevented a thread from suspending while holding locks inside of NFS by forcing the thread to fail sleeps with EINTR or ERESTART but defer the thread suspension to the user boundary. However, this had the effect that stopping a process during an NFS request could abort the request and trigger EINTR errors that were visible to userland processes (previously the thread would have suspended and completed the request once it was resumed). This change instead effectively masks stop signals while in the NFS client. It uses the existing TDF_SBDRY flag to effect this since SIGSTOP cannot be masked directly. Also, instead of setting PBDRY on individual sleeps, the NFS client now sets the TDF_SBDRY flag around each NFS request and stop signals are masked for all sleeps during that region (the previous change missed sleeps in lockmgr locks). The end result is that stop signals sent to threads performing an NFS request are completely ignored until after the NFS request has finished processing and the thread prepares to return to userland. This restores the behavior of stop signals being transparent to userland processes while still preventing threads from suspending while holding NFS locks. Reviewed by: kib MFC after: 1 month
Diffstat (limited to 'sys/kern/subr_sleepqueue.c')
-rw-r--r--sys/kern/subr_sleepqueue.c6
1 files changed, 2 insertions, 4 deletions
diff --git a/sys/kern/subr_sleepqueue.c b/sys/kern/subr_sleepqueue.c
index 2d5ea51..b6bd8fc 100644
--- a/sys/kern/subr_sleepqueue.c
+++ b/sys/kern/subr_sleepqueue.c
@@ -352,8 +352,6 @@ sleepq_add(void *wchan, struct lock_object *lock, const char *wmesg, int flags,
if (flags & SLEEPQ_INTERRUPTIBLE) {
td->td_flags |= TDF_SINTR;
td->td_flags &= ~TDF_SLEEPABORT;
- if (flags & SLEEPQ_STOP_ON_BDRY)
- td->td_flags |= TDF_SBDRY;
}
thread_unlock(td);
}
@@ -600,7 +598,7 @@ sleepq_check_signals(void)
/* We are no longer in an interruptible sleep. */
if (td->td_flags & TDF_SINTR)
- td->td_flags &= ~(TDF_SINTR | TDF_SBDRY);
+ td->td_flags &= ~TDF_SINTR;
if (td->td_flags & TDF_SLEEPABORT) {
td->td_flags &= ~TDF_SLEEPABORT;
@@ -747,7 +745,7 @@ sleepq_resume_thread(struct sleepqueue *sq, struct thread *td, int pri)
td->td_wmesg = NULL;
td->td_wchan = NULL;
- td->td_flags &= ~(TDF_SINTR | TDF_SBDRY);
+ td->td_flags &= ~TDF_SINTR;
CTR3(KTR_PROC, "sleepq_wakeup: thread %p (pid %ld, %s)",
(void *)td, (long)td->td_proc->p_pid, td->td_name);
OpenPOWER on IntegriCloud