aboutsummaryrefslogtreecommitdiffstats
path: root/module
diff options
context:
space:
mode:
authorMatthew Macy <[email protected]>2020-09-03 20:04:09 -0700
committerGitHub <[email protected]>2020-09-03 20:04:09 -0700
commitac6e5fb202a95277cd7886eb7b6acc3ec53d8def (patch)
treeb016a947bae0eee38318eca6c19d619045a7de65 /module
parentf30703f6fc831bdeb5e7a11b5f1c01d6d9cb7799 (diff)
Replace cv_{timed}wait_sig with cv_{timed}wait_idle where appropriate
There are a number of places where cv_?_sig is used simply for accounting purposes but the surrounding code has no ability to cope with actually receiving a signal. On FreeBSD it is possible to send signals to individual kernel threads so this could enable undesirable behavior. This patch adds routines on Linux that will do the same idle accounting as _sig without making the task interruptible. On FreeBSD cv_*_idle are all aliases for cv_* Reviewed-by: Alexander Motin <[email protected]> Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: Matt Macy <[email protected]> Closes #10843
Diffstat (limited to 'module')
-rw-r--r--module/os/linux/spl/spl-condvar.c44
-rw-r--r--module/zfs/arc.c2
-rw-r--r--module/zfs/dbuf.c2
-rw-r--r--module/zfs/mmp.c2
-rw-r--r--module/zfs/txg.c12
-rw-r--r--module/zfs/vdev_trim.c2
-rw-r--r--module/zfs/zthr.c9
7 files changed, 54 insertions, 19 deletions
diff --git a/module/os/linux/spl/spl-condvar.c b/module/os/linux/spl/spl-condvar.c
index 9d045e3e8..49f486645 100644
--- a/module/os/linux/spl/spl-condvar.c
+++ b/module/os/linux/spl/spl-condvar.c
@@ -198,6 +198,18 @@ __cv_wait_sig(kcondvar_t *cvp, kmutex_t *mp)
}
EXPORT_SYMBOL(__cv_wait_sig);
+void
+__cv_wait_idle(kcondvar_t *cvp, kmutex_t *mp)
+{
+ sigset_t blocked, saved;
+
+ sigfillset(&blocked);
+ (void) sigprocmask(SIG_BLOCK, &blocked, &saved);
+ cv_wait_common(cvp, mp, TASK_INTERRUPTIBLE, 0);
+ (void) sigprocmask(SIG_SETMASK, &saved, NULL);
+}
+EXPORT_SYMBOL(__cv_wait_idle);
+
#if defined(HAVE_IO_SCHEDULE_TIMEOUT)
#define spl_io_schedule_timeout(t) io_schedule_timeout(t)
#else
@@ -330,6 +342,21 @@ __cv_timedwait_sig(kcondvar_t *cvp, kmutex_t *mp, clock_t exp_time)
}
EXPORT_SYMBOL(__cv_timedwait_sig);
+int
+__cv_timedwait_idle(kcondvar_t *cvp, kmutex_t *mp, clock_t exp_time)
+{
+ sigset_t blocked, saved;
+ int rc;
+
+ sigfillset(&blocked);
+ (void) sigprocmask(SIG_BLOCK, &blocked, &saved);
+ rc = __cv_timedwait_common(cvp, mp, exp_time,
+ TASK_INTERRUPTIBLE, 0);
+ (void) sigprocmask(SIG_SETMASK, &saved, NULL);
+
+ return (rc);
+}
+EXPORT_SYMBOL(__cv_timedwait_idle);
/*
* 'expire_time' argument is an absolute clock time in nanoseconds.
* Return value is time left (expire_time - now) or -1 if timeout occurred.
@@ -427,6 +454,23 @@ cv_timedwait_sig_hires(kcondvar_t *cvp, kmutex_t *mp, hrtime_t tim,
}
EXPORT_SYMBOL(cv_timedwait_sig_hires);
+int
+cv_timedwait_idle_hires(kcondvar_t *cvp, kmutex_t *mp, hrtime_t tim,
+ hrtime_t res, int flag)
+{
+ sigset_t blocked, saved;
+ int rc;
+
+ sigfillset(&blocked);
+ (void) sigprocmask(SIG_BLOCK, &blocked, &saved);
+ rc = cv_timedwait_hires_common(cvp, mp, tim, res, flag,
+ TASK_INTERRUPTIBLE);
+ (void) sigprocmask(SIG_SETMASK, &saved, NULL);
+
+ return (rc);
+}
+EXPORT_SYMBOL(cv_timedwait_idle_hires);
+
void
__cv_signal(kcondvar_t *cvp)
{
diff --git a/module/zfs/arc.c b/module/zfs/arc.c
index 904c325f3..0c33a4535 100644
--- a/module/zfs/arc.c
+++ b/module/zfs/arc.c
@@ -9174,7 +9174,7 @@ l2arc_feed_thread(void *unused)
cookie = spl_fstrans_mark();
while (l2arc_thread_exit == 0) {
CALLB_CPR_SAFE_BEGIN(&cpr);
- (void) cv_timedwait_sig(&l2arc_feed_thr_cv,
+ (void) cv_timedwait_idle(&l2arc_feed_thr_cv,
&l2arc_feed_thr_lock, next);
CALLB_CPR_SAFE_END(&cpr, &l2arc_feed_thr_lock);
next = ddi_get_lbolt() + hz;
diff --git a/module/zfs/dbuf.c b/module/zfs/dbuf.c
index 2de1f4e4c..7d817320a 100644
--- a/module/zfs/dbuf.c
+++ b/module/zfs/dbuf.c
@@ -718,7 +718,7 @@ dbuf_evict_thread(void *unused)
while (!dbuf_evict_thread_exit) {
while (!dbuf_cache_above_lowater() && !dbuf_evict_thread_exit) {
CALLB_CPR_SAFE_BEGIN(&cpr);
- (void) cv_timedwait_sig_hires(&dbuf_evict_cv,
+ (void) cv_timedwait_idle_hires(&dbuf_evict_cv,
&dbuf_evict_lock, SEC2NSEC(1), MSEC2NSEC(1), 0);
CALLB_CPR_SAFE_END(&cpr, &dbuf_evict_lock);
}
diff --git a/module/zfs/mmp.c b/module/zfs/mmp.c
index 4170d7e03..1b97de468 100644
--- a/module/zfs/mmp.c
+++ b/module/zfs/mmp.c
@@ -671,7 +671,7 @@ mmp_thread(void *arg)
}
CALLB_CPR_SAFE_BEGIN(&cpr);
- (void) cv_timedwait_sig_hires(&mmp->mmp_thread_cv,
+ (void) cv_timedwait_idle_hires(&mmp->mmp_thread_cv,
&mmp->mmp_thread_lock, next_time, USEC2NSEC(100),
CALLOUT_FLAG_ABSOLUTE);
CALLB_CPR_SAFE_END(&cpr, &mmp->mmp_thread_lock);
diff --git a/module/zfs/txg.c b/module/zfs/txg.c
index a5f2b0417..65375b579 100644
--- a/module/zfs/txg.c
+++ b/module/zfs/txg.c
@@ -242,16 +242,11 @@ txg_thread_wait(tx_state_t *tx, callb_cpr_t *cpr, kcondvar_t *cv, clock_t time)
{
CALLB_CPR_SAFE_BEGIN(cpr);
- /*
- * cv_wait_sig() is used instead of cv_wait() in order to prevent
- * this process from incorrectly contributing to the system load
- * average when idle.
- */
if (time) {
- (void) cv_timedwait_sig(cv, &tx->tx_sync_lock,
+ (void) cv_timedwait_idle(cv, &tx->tx_sync_lock,
ddi_get_lbolt() + time);
} else {
- cv_wait_sig(cv, &tx->tx_sync_lock);
+ cv_wait_idle(cv, &tx->tx_sync_lock);
}
CALLB_CPR_SAFE_END(cpr, &tx->tx_sync_lock);
@@ -760,7 +755,8 @@ txg_wait_open(dsl_pool_t *dp, uint64_t txg, boolean_t should_quiesce)
if (should_quiesce == B_TRUE) {
cv_wait_io(&tx->tx_quiesce_done_cv, &tx->tx_sync_lock);
} else {
- cv_wait_sig(&tx->tx_quiesce_done_cv, &tx->tx_sync_lock);
+ cv_wait_idle(&tx->tx_quiesce_done_cv,
+ &tx->tx_sync_lock);
}
}
mutex_exit(&tx->tx_sync_lock);
diff --git a/module/zfs/vdev_trim.c b/module/zfs/vdev_trim.c
index 3f8c34806..7383e1493 100644
--- a/module/zfs/vdev_trim.c
+++ b/module/zfs/vdev_trim.c
@@ -481,7 +481,7 @@ vdev_trim_range(trim_args_t *ta, uint64_t start, uint64_t size)
if (ta->trim_type == TRIM_TYPE_MANUAL) {
while (vd->vdev_trim_rate != 0 && !vdev_trim_should_stop(vd) &&
vdev_trim_calculate_rate(ta) > vd->vdev_trim_rate) {
- cv_timedwait_sig(&vd->vdev_trim_io_cv,
+ cv_timedwait_idle(&vd->vdev_trim_io_cv,
&vd->vdev_trim_io_lock, ddi_get_lbolt() +
MSEC_TO_TICK(10));
}
diff --git a/module/zfs/zthr.c b/module/zfs/zthr.c
index fdc4b8633..e230cd2cb 100644
--- a/module/zfs/zthr.c
+++ b/module/zfs/zthr.c
@@ -237,15 +237,10 @@ zthr_procedure(void *arg)
t->zthr_func(t->zthr_arg, t);
mutex_enter(&t->zthr_state_lock);
} else {
- /*
- * cv_wait_sig() is used instead of cv_wait() in
- * order to prevent this process from incorrectly
- * contributing to the system load average when idle.
- */
if (t->zthr_sleep_timeout == 0) {
- cv_wait_sig(&t->zthr_cv, &t->zthr_state_lock);
+ cv_wait_idle(&t->zthr_cv, &t->zthr_state_lock);
} else {
- (void) cv_timedwait_sig_hires(&t->zthr_cv,
+ (void) cv_timedwait_idle_hires(&t->zthr_cv,
&t->zthr_state_lock, t->zthr_sleep_timeout,
MSEC2NSEC(1), 0);
}