summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpjd <pjd@FreeBSD.org>2007-09-10 19:58:14 +0000
committerpjd <pjd@FreeBSD.org>2007-09-10 19:58:14 +0000
commita9891a0fce1a7655a14a07701ad58c3d106c9d00 (patch)
tree04cf461f001606c1a89933203c3d1c444a812bef
parentafe3e152994d9d61c59cae30f9d392539d9ad64a (diff)
downloadFreeBSD-src-a9891a0fce1a7655a14a07701ad58c3d106c9d00.zip
FreeBSD-src-a9891a0fce1a7655a14a07701ad58c3d106c9d00.tar.gz
Reduce the limit of vnodes on i386 when ZFS is loaded to 3/4 of the original
value, so we don't run out of KVA. The default vnodes limit fits better for UFS, but ZFS allocated more file system specific memory for a vnode than UFS. Don't touch vnodes limit if we detect it was tuned by system administrator and restore original value when ZFS is unloaded. This isn't final fix, but before we implement something better, this will help to stabilize ZFS under heavy load on i386. Approved by: re (bmah)
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c41
-rw-r--r--sys/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c41
2 files changed, 82 insertions, 0 deletions
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
index 259b77c..e08785a 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
@@ -949,6 +949,39 @@ zfs_freevfs(vfs_t *vfsp)
atomic_add_32(&zfs_active_fs_count, -1);
}
+#ifdef __i386__
+static int desiredvnodes_backup;
+#endif
+
+static void
+zfs_vnodes_adjust(void)
+{
+#ifdef __i386__
+ int val;
+
+ desiredvnodes_backup = desiredvnodes;
+
+ /*
+ * We calculate newdesiredvnodes the same way it is done in
+ * vntblinit(). If it is equal to desiredvnodes, it means that
+ * it wasn't tuned by the administrator and we can tune it down.
+ */
+ val = min(maxproc + cnt.v_page_count / 4, 2 * vm_kmem_size /
+ (5 * (sizeof(struct vm_object) + sizeof(struct vnode))));
+ if (desiredvnodes == val)
+ desiredvnodes = (3 * desiredvnodes) / 4;
+#endif
+}
+
+static void
+zfs_vnodes_adjust_back(void)
+{
+
+#ifdef __i386__
+ desiredvnodes = desiredvnodes_backup;
+#endif
+}
+
void
zfs_init(void)
{
@@ -964,6 +997,13 @@ zfs_init(void)
* Initialize znode cache, vnode ops, etc...
*/
zfs_znode_init();
+
+ /*
+ * Reduce number of vnodes. Originally number of vnodes is calculated
+ * with UFS inode in mind. We reduce it here, because it's too big for
+ * ZFS/i386.
+ */
+ zfs_vnodes_adjust();
}
void
@@ -971,6 +1011,7 @@ zfs_fini(void)
{
zfsctl_fini();
zfs_znode_fini();
+ zfs_vnodes_adjust_back();
}
int
diff --git a/sys/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c b/sys/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
index 259b77c..e08785a 100644
--- a/sys/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
+++ b/sys/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
@@ -949,6 +949,39 @@ zfs_freevfs(vfs_t *vfsp)
atomic_add_32(&zfs_active_fs_count, -1);
}
+#ifdef __i386__
+static int desiredvnodes_backup;
+#endif
+
+static void
+zfs_vnodes_adjust(void)
+{
+#ifdef __i386__
+ int val;
+
+ desiredvnodes_backup = desiredvnodes;
+
+ /*
+ * We calculate newdesiredvnodes the same way it is done in
+ * vntblinit(). If it is equal to desiredvnodes, it means that
+ * it wasn't tuned by the administrator and we can tune it down.
+ */
+ val = min(maxproc + cnt.v_page_count / 4, 2 * vm_kmem_size /
+ (5 * (sizeof(struct vm_object) + sizeof(struct vnode))));
+ if (desiredvnodes == val)
+ desiredvnodes = (3 * desiredvnodes) / 4;
+#endif
+}
+
+static void
+zfs_vnodes_adjust_back(void)
+{
+
+#ifdef __i386__
+ desiredvnodes = desiredvnodes_backup;
+#endif
+}
+
void
zfs_init(void)
{
@@ -964,6 +997,13 @@ zfs_init(void)
* Initialize znode cache, vnode ops, etc...
*/
zfs_znode_init();
+
+ /*
+ * Reduce number of vnodes. Originally number of vnodes is calculated
+ * with UFS inode in mind. We reduce it here, because it's too big for
+ * ZFS/i386.
+ */
+ zfs_vnodes_adjust();
}
void
@@ -971,6 +1011,7 @@ zfs_fini(void)
{
zfsctl_fini();
zfs_znode_fini();
+ zfs_vnodes_adjust_back();
}
int
OpenPOWER on IntegriCloud