From owner-svn-src-head@freebsd.org Fri Jun 17 17:34:30 2016 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 5A32FA78D4E; Fri, 17 Jun 2016 17:34:30 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 1D54720F5; Fri, 17 Jun 2016 17:34:30 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u5HHYTIe005858; Fri, 17 Jun 2016 17:34:29 GMT (envelope-from kib@FreeBSD.org) Received: (from kib@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u5HHYTCb005855; Fri, 17 Jun 2016 17:34:29 GMT (envelope-from kib@FreeBSD.org) Message-Id: <201606171734.u5HHYTCb005855@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: kib set sender to kib@FreeBSD.org using -f From: Konstantin Belousov Date: Fri, 17 Jun 2016 17:34:29 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r301997 - in head/sys/cddl: compat/opensolaris/sys contrib/opensolaris/uts/common/fs/zfs X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 17 Jun 2016 17:34:30 -0000 Author: kib Date: Fri Jun 17 17:34:28 2016 New Revision: 301997 URL: https://svnweb.freebsd.org/changeset/base/301997 Log: Use vnlru_free(9) to implement dnlc_reduce_cache(). This apparently puts ARC back under the limits after the vnode pressure rework in r291244, in particular due to the kmem exhaustion. Based on patch by: mckusick Reviewed by: avg, mckusick Tested by: allanjude, madpilot Sponsored by: The FreeBSD Foundation Approved by: re (gjb) Modified: head/sys/cddl/compat/opensolaris/sys/dnlc.h head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c Modified: head/sys/cddl/compat/opensolaris/sys/dnlc.h ============================================================================== --- head/sys/cddl/compat/opensolaris/sys/dnlc.h Fri Jun 17 17:33:25 2016 (r301996) +++ head/sys/cddl/compat/opensolaris/sys/dnlc.h Fri Jun 17 17:34:28 2016 (r301997) @@ -35,6 +35,6 @@ #define dnlc_update(dvp, name, vp) do { } while (0) #define dnlc_remove(dvp, name) do { } while (0) #define dnlc_purge_vfsp(vfsp, count) (0) -#define dnlc_reduce_cache(percent) do { } while (0) +void dnlc_reduce_cache(void *arg); #endif /* !_OPENSOLARIS_SYS_DNLC_H_ */ Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c ============================================================================== --- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c Fri Jun 17 17:33:25 2016 (r301996) +++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c Fri Jun 17 17:34:28 2016 (r301997) @@ -159,6 +159,10 @@ static kmutex_t arc_user_evicts_lock; static kcondvar_t arc_user_evicts_cv; static boolean_t arc_user_evicts_thread_exit; +static kmutex_t arc_dnlc_evicts_lock; +static kcondvar_t arc_dnlc_evicts_cv; +static boolean_t arc_dnlc_evicts_thread_exit; + uint_t arc_reduce_dnlc_percent = 3; /* @@ -3749,6 +3753,57 @@ arc_user_evicts_thread(void *dummy __unu thread_exit(); } +static u_int arc_dnlc_evicts_arg; +extern struct vfsops zfs_vfsops; + +static void +arc_dnlc_evicts_thread(void *dummy __unused) +{ + callb_cpr_t cpr; + u_int percent; + + CALLB_CPR_INIT(&cpr, &arc_dnlc_evicts_lock, callb_generic_cpr, FTAG); + + mutex_enter(&arc_dnlc_evicts_lock); + while (!arc_dnlc_evicts_thread_exit) { + CALLB_CPR_SAFE_BEGIN(&cpr); + (void) cv_wait(&arc_dnlc_evicts_cv, &arc_dnlc_evicts_lock); + CALLB_CPR_SAFE_END(&cpr, &arc_dnlc_evicts_lock); + if (arc_dnlc_evicts_arg != 0) { + percent = arc_dnlc_evicts_arg; + mutex_exit(&arc_dnlc_evicts_lock); +#ifdef _KERNEL + vnlru_free(desiredvnodes * percent / 100, &zfs_vfsops); +#endif + mutex_enter(&arc_dnlc_evicts_lock); + /* + * Clear our token only after vnlru_free() + * pass is done, to avoid false queueing of + * the requests. + */ + arc_dnlc_evicts_arg = 0; + } + } + arc_dnlc_evicts_thread_exit = FALSE; + cv_broadcast(&arc_dnlc_evicts_cv); + CALLB_CPR_EXIT(&cpr); + thread_exit(); +} + +void +dnlc_reduce_cache(void *arg) +{ + u_int percent; + + percent = (u_int)arg; + mutex_enter(&arc_dnlc_evicts_lock); + if (arc_dnlc_evicts_arg == 0) { + arc_dnlc_evicts_arg = percent; + cv_broadcast(&arc_dnlc_evicts_cv); + } + mutex_exit(&arc_dnlc_evicts_lock); +} + /* * Adapt arc info given the number of bytes we are trying to add and * the state that we are comming from. This function is only called @@ -5311,6 +5366,9 @@ arc_init(void) mutex_init(&arc_user_evicts_lock, NULL, MUTEX_DEFAULT, NULL); cv_init(&arc_user_evicts_cv, NULL, CV_DEFAULT, NULL); + mutex_init(&arc_dnlc_evicts_lock, NULL, MUTEX_DEFAULT, NULL); + cv_init(&arc_dnlc_evicts_cv, NULL, CV_DEFAULT, NULL); + /* Convert seconds to clock ticks */ arc_min_prefetch_lifespan = 1 * hz; @@ -5463,6 +5521,7 @@ arc_init(void) arc_reclaim_thread_exit = FALSE; arc_user_evicts_thread_exit = FALSE; + arc_dnlc_evicts_thread_exit = FALSE; arc_eviction_list = NULL; bzero(&arc_eviction_hdr, sizeof (arc_buf_hdr_t)); @@ -5486,6 +5545,9 @@ arc_init(void) (void) thread_create(NULL, 0, arc_user_evicts_thread, NULL, 0, &p0, TS_RUN, minclsyspri); + (void) thread_create(NULL, 0, arc_dnlc_evicts_thread, NULL, 0, &p0, + TS_RUN, minclsyspri); + arc_dead = FALSE; arc_warm = B_FALSE; @@ -5568,6 +5630,18 @@ arc_fini(void) } mutex_exit(&arc_user_evicts_lock); + mutex_enter(&arc_dnlc_evicts_lock); + arc_dnlc_evicts_thread_exit = TRUE; + /* + * The user evicts thread will set arc_user_evicts_thread_exit + * to FALSE when it is finished exiting; we're waiting for that. + */ + while (arc_dnlc_evicts_thread_exit) { + cv_signal(&arc_dnlc_evicts_cv); + cv_wait(&arc_dnlc_evicts_cv, &arc_dnlc_evicts_lock); + } + mutex_exit(&arc_dnlc_evicts_lock); + /* Use TRUE to ensure *all* buffers are evicted */ arc_flush(NULL, TRUE); @@ -5585,6 +5659,9 @@ arc_fini(void) mutex_destroy(&arc_user_evicts_lock); cv_destroy(&arc_user_evicts_cv); + mutex_destroy(&arc_dnlc_evicts_lock); + cv_destroy(&arc_dnlc_evicts_cv); + refcount_destroy(&arc_anon->arcs_size); refcount_destroy(&arc_mru->arcs_size); refcount_destroy(&arc_mru_ghost->arcs_size); Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c ============================================================================== --- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c Fri Jun 17 17:33:25 2016 (r301996) +++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c Fri Jun 17 17:34:28 2016 (r301997) @@ -101,7 +101,7 @@ static int zfs_fhtovp(vfs_t *vfsp, fid_t static void zfs_objset_close(zfsvfs_t *zfsvfs); static void zfs_freevfs(vfs_t *vfsp); -static struct vfsops zfs_vfsops = { +struct vfsops zfs_vfsops = { .vfs_mount = zfs_mount, .vfs_unmount = zfs_umount, .vfs_root = zfs_root,