From 5b63b3eb6f42f3d9f6a19b22c3f10f72927eeacc Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Fri, 10 Dec 2010 12:00:00 -0800 Subject: [PATCH] Use cv_timedwait_interruptible in arc The issue is that cv_timedwait() sleeps uninterruptibly to block signals and avoid waking up early. Under Linux this counts against the load average keeping it artificially high. This change allows the arc to sleep interruptibly which mean it may be woken up early due to a signal. Normally this means some extra care must be taken to handle a potential signal. But for the arcs usage of cv_timedwait() there is no harm in waking up before the timeout expires so no extra handling is required. --- include/sys/zfs_context.h | 1 + module/zfs/arc.c | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/include/sys/zfs_context.h b/include/sys/zfs_context.h index c449903512..44e3dd1d39 100644 --- a/include/sys/zfs_context.h +++ b/include/sys/zfs_context.h @@ -310,6 +310,7 @@ extern void cv_wait(kcondvar_t *cv, kmutex_t *mp); extern clock_t cv_timedwait(kcondvar_t *cv, kmutex_t *mp, clock_t abstime); extern void cv_signal(kcondvar_t *cv); extern void cv_broadcast(kcondvar_t *cv); +#define cv_timedwait_interruptible(cv, mp, at) cv_timedwait(cv, mp, at); /* * kstat creation, installation and deletion diff --git a/module/zfs/arc.c b/module/zfs/arc.c index 32d99bf392..808c8e8dfc 100644 --- a/module/zfs/arc.c +++ b/module/zfs/arc.c @@ -2149,7 +2149,7 @@ arc_reclaim_thread(void) /* block until needed, or one second, whichever is shorter */ CALLB_CPR_SAFE_BEGIN(&cpr); - (void) cv_timedwait(&arc_reclaim_thr_cv, + (void) cv_timedwait_interruptible(&arc_reclaim_thr_cv, &arc_reclaim_thr_lock, (ddi_get_lbolt() + hz)); CALLB_CPR_SAFE_END(&cpr, &arc_reclaim_thr_lock); } @@ -4435,8 +4435,8 @@ l2arc_feed_thread(void) while (l2arc_thread_exit == 0) { CALLB_CPR_SAFE_BEGIN(&cpr); - (void) cv_timedwait(&l2arc_feed_thr_cv, &l2arc_feed_thr_lock, - next); + (void) cv_timedwait_interruptible(&l2arc_feed_thr_cv, + &l2arc_feed_thr_lock, next); CALLB_CPR_SAFE_END(&cpr, &l2arc_feed_thr_lock); next = ddi_get_lbolt() + hz;