Subject: Re: Sysctl types for vm.bufmem* are wrong
To: None <tech-kern@NetBSD.org>
From: Martin Husemann <martin@duskware.de>
List: tech-kern
Date: 10/18/2007 13:11:51
--FL5UXtIhxfXey3p5
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Ok, I personally do not like to use int64_t here amd implicitly relying
on the fact that it is just the same as quad_t in sysctl (nor will I go
on a sweep to fix quad->int64 for sysctl right now) - but if people prefer
this, ok.
The previous patch was not complete, here is a full (working) version.
Noone asked for compatibility yet, so I won't bother.
Martin
--FL5UXtIhxfXey3p5
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=patch
Index: vfs_bio.c
===================================================================
RCS file: /cvsroot/src/sys/kern/vfs_bio.c,v
retrieving revision 1.179
diff -u -p -r1.179 vfs_bio.c
--- vfs_bio.c 8 Oct 2007 18:04:05 -0000 1.179
+++ vfs_bio.c 18 Oct 2007 11:05:53 -0000
@@ -231,10 +231,10 @@ static struct pool_allocator bufmempool_
};
/* Buffer memory management variables */
-u_long bufmem_valimit;
-u_long bufmem_hiwater;
-u_long bufmem_lowater;
-u_long bufmem;
+uint64_t bufmem_valimit;
+uint64_t bufmem_hiwater;
+uint64_t bufmem_lowater;
+uint64_t bufmem;
/*
* MD code can call this to set a hard limit on the amount
@@ -1598,8 +1598,20 @@ cleanup:
return (error);
}
+static void
+sysctl_bufvm_common(void)
+{
+ int64_t t;
+
+ /* Drain until below new high water mark */
+ while ((t = (int64_t)bufmem - (int64_t)bufmem_hiwater) >= 0) {
+ if (buf_drain(t / (2 * 1024)) <= 0)
+ break;
+ }
+}
+
static int
-sysctl_bufvm_update(SYSCTLFN_ARGS)
+sysctl_bufcache_update(SYSCTLFN_ARGS)
{
int t, error;
struct sysctlnode node;
@@ -1611,14 +1623,32 @@ sysctl_bufvm_update(SYSCTLFN_ARGS)
if (error || newp == NULL)
return (error);
+ if (t < 0 || t > 100)
+ return EINVAL;
+ bufcache = t;
+ buf_setwm();
+
+ sysctl_bufvm_common();
+ return 0;
+}
+
+static int
+sysctl_bufvm_update(SYSCTLFN_ARGS)
+{
+ int64_t t;
+ int error;
+ struct sysctlnode node;
+
+ node = *rnode;
+ node.sysctl_data = &t;
+ t = *(int64_t *)rnode->sysctl_data;
+ error = sysctl_lookup(SYSCTLFN_CALL(&node));
+ if (error || newp == NULL)
+ return (error);
+
if (t < 0)
return EINVAL;
- if (rnode->sysctl_data == &bufcache) {
- if (t > 100)
- return (EINVAL);
- bufcache = t;
- buf_setwm();
- } else if (rnode->sysctl_data == &bufmem_lowater) {
+ if (rnode->sysctl_data == &bufmem_lowater) {
if (bufmem_hiwater - t < 16)
return (EINVAL);
bufmem_lowater = t;
@@ -1629,11 +1659,7 @@ sysctl_bufvm_update(SYSCTLFN_ARGS)
} else
return (EINVAL);
- /* Drain until below new high water mark */
- while ((t = bufmem - bufmem_hiwater) >= 0) {
- if (buf_drain(t / (2 * 1024)) <= 0)
- break;
- }
+ sysctl_bufvm_common();
return 0;
}
@@ -1668,25 +1694,25 @@ SYSCTL_SETUP(sysctl_vm_buf_setup, "sysct
CTLTYPE_INT, "bufcache",
SYSCTL_DESCR("Percentage of physical memory to use for "
"buffer cache"),
- sysctl_bufvm_update, 0, &bufcache, 0,
+ sysctl_bufcache_update, 0, &bufcache, 0,
CTL_VM, CTL_CREATE, CTL_EOL);
sysctl_createv(clog, 0, NULL, NULL,
CTLFLAG_PERMANENT|CTLFLAG_READONLY,
- CTLTYPE_INT, "bufmem",
+ CTLTYPE_QUAD, "bufmem",
SYSCTL_DESCR("Amount of kernel memory used by buffer "
"cache"),
NULL, 0, &bufmem, 0,
CTL_VM, CTL_CREATE, CTL_EOL);
sysctl_createv(clog, 0, NULL, NULL,
CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
- CTLTYPE_INT, "bufmem_lowater",
+ CTLTYPE_QUAD, "bufmem_lowater",
SYSCTL_DESCR("Minimum amount of kernel memory to "
"reserve for buffer cache"),
sysctl_bufvm_update, 0, &bufmem_lowater, 0,
CTL_VM, CTL_CREATE, CTL_EOL);
sysctl_createv(clog, 0, NULL, NULL,
CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
- CTLTYPE_INT, "bufmem_hiwater",
+ CTLTYPE_QUAD, "bufmem_hiwater",
SYSCTL_DESCR("Maximum amount of kernel memory to use "
"for buffer cache"),
sysctl_bufvm_update, 0, &bufmem_hiwater, 0,
--FL5UXtIhxfXey3p5--