summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--config/spl-build.m418
-rwxr-xr-xconfigure39
-rw-r--r--configure.ac1
-rw-r--r--include/sys/vmsystm.h20
-rw-r--r--module/spl/spl-kmem.c86
-rw-r--r--module/spl/spl-proc.c86
-rw-r--r--spl_config.h.in3
7 files changed, 214 insertions, 39 deletions
diff --git a/config/spl-build.m4 b/config/spl-build.m4
index b7aa024e4..5ee615bf8 100644
--- a/config/spl-build.m4
+++ b/config/spl-build.m4
@@ -707,7 +707,7 @@ AC_DEFUN([SPL_AC_3ARGS_ON_EACH_CPU], [
])
dnl #
-dnl # Distro specific first_online_pgdat symbol export.
+dnl # Distro specific first_online_pgdat() symbol export.
dnl #
AC_DEFUN([SPL_AC_FIRST_ONLINE_PGDAT], [
SPL_CHECK_SYMBOL_EXPORT(
@@ -719,7 +719,7 @@ AC_DEFUN([SPL_AC_FIRST_ONLINE_PGDAT], [
])
dnl #
-dnl # Distro specific next_online_pgdat symbol export.
+dnl # Distro specific next_online_pgdat() symbol export.
dnl #
AC_DEFUN([SPL_AC_NEXT_ONLINE_PGDAT], [
SPL_CHECK_SYMBOL_EXPORT(
@@ -731,7 +731,7 @@ AC_DEFUN([SPL_AC_NEXT_ONLINE_PGDAT], [
])
dnl #
-dnl # Distro specific next_zone symbol export.
+dnl # Distro specific next_zone() symbol export.
dnl #
AC_DEFUN([SPL_AC_NEXT_ZONE], [
SPL_CHECK_SYMBOL_EXPORT(
@@ -741,3 +741,15 @@ AC_DEFUN([SPL_AC_NEXT_ZONE], [
[next_zone() is available])],
[])
])
+
+dnl #
+dnl # Distro specific get_zone_counts() symbol export.
+dnl #
+AC_DEFUN([SPL_AC_GET_ZONE_COUNTS], [
+ SPL_CHECK_SYMBOL_EXPORT(
+ [get_zone_counts],
+ [],
+ [AC_DEFINE(HAVE_GET_ZONE_COUNTS, 1,
+ [get_zone_counts() is available])],
+ [])
+])
diff --git a/configure b/configure
index 7e59d67fd..21e222de4 100755
--- a/configure
+++ b/configure
@@ -20598,6 +20598,45 @@ _ACEOF
+ echo "$as_me:$LINENO: checking whether symbol get_zone_counts is exported" >&5
+echo $ECHO_N "checking whether symbol get_zone_counts is exported... $ECHO_C" >&6
+ grep -q -E '[[:space:]]get_zone_counts[[:space:]]' $LINUX/Module.symvers 2>/dev/null
+ rc=$?
+ if test $rc -ne 0; then
+ export=0
+ for file in ; do
+ grep -q -E "EXPORT_SYMBOL.*(get_zone_counts)" "$LINUX/$file" 2>/dev/null
+ rc=$?
+ if test $rc -eq 0; then
+ export=1
+ break;
+ fi
+ done
+ if test $export -eq 0; then
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+
+ else
+ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_GET_ZONE_COUNTS 1
+_ACEOF
+
+ fi
+ else
+ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_GET_ZONE_COUNTS 1
+_ACEOF
+
+ fi
+
+
+
TOPDIR=`/bin/pwd`
# Add "V=1" to KERNELMAKE_PARAMS to enable verbose module build
diff --git a/configure.ac b/configure.ac
index bd4f69976..259c4e892 100644
--- a/configure.ac
+++ b/configure.ac
@@ -72,6 +72,7 @@ SPL_AC_3ARGS_ON_EACH_CPU
SPL_AC_FIRST_ONLINE_PGDAT
SPL_AC_NEXT_ONLINE_PGDAT
SPL_AC_NEXT_ZONE
+SPL_AC_GET_ZONE_COUNTS
TOPDIR=`/bin/pwd`
diff --git a/include/sys/vmsystm.h b/include/sys/vmsystm.h
index a6e9e7d7e..75ae8a991 100644
--- a/include/sys/vmsystm.h
+++ b/include/sys/vmsystm.h
@@ -45,15 +45,14 @@
#define physmem num_physpages
#define freemem nr_free_pages()
+#define availrmem spl_kmem_availrmem()
extern pgcnt_t minfree; /* Sum of zone->pages_min */
extern pgcnt_t desfree; /* Sum of zone->pages_low */
extern pgcnt_t lotsfree; /* Sum of zone->pages_high */
-extern pgcnt_t needfree; /* Always 0 */
-extern pgcnt_t swapfs_minfree;
-extern pgcnt_t swapfs_desfree;
-extern pgcnt_t swapfs_reserve;
-extern pgcnt_t availrmem;
+extern pgcnt_t needfree; /* Always 0 unused in new Solaris */
+extern pgcnt_t swapfs_minfree; /* Solaris default value */
+extern pgcnt_t swapfs_reserve; /* Solaris default value */
extern vmem_t *heap_arena; /* primary kernel heap arena */
extern vmem_t *zio_alloc_arena; /* arena for zio caches */
@@ -62,15 +61,8 @@ extern vmem_t *zio_arena; /* arena for allocating zio memory */
#define VMEM_ALLOC 0x01
#define VMEM_FREE 0x02
-static __inline__ size_t
-vmem_size(vmem_t *vmp, int typemask)
-{
- /* Arena's unsupported */
- ASSERT(vmp == NULL);
- ASSERT(typemask & (VMEM_ALLOC | VMEM_FREE));
-
- return 0;
-}
+extern pgcnt_t spl_kmem_availrmem(void);
+extern size_t vmem_size(vmem_t *vmp, int typemask);
#define xcopyin(from, to, size) copy_from_user(to, from, size)
#define xcopyout(from, to, size) copy_to_user(to, from, size)
diff --git a/module/spl/spl-kmem.c b/module/spl/spl-kmem.c
index c39636e06..b5cd9fb12 100644
--- a/module/spl/spl-kmem.c
+++ b/module/spl/spl-kmem.c
@@ -64,18 +64,12 @@ EXPORT_SYMBOL(lotsfree);
pgcnt_t needfree = 0;
EXPORT_SYMBOL(needfree);
-pgcnt_t swapfs_desfree = 0;
-EXPORT_SYMBOL(swapfs_desfree);
-
pgcnt_t swapfs_minfree = 0;
EXPORT_SYMBOL(swapfs_minfree);
pgcnt_t swapfs_reserve = 0;
EXPORT_SYMBOL(swapfs_reserve);
-pgcnt_t availrmem = 0;
-EXPORT_SYMBOL(availrmem);
-
vmem_t *heap_arena = NULL;
EXPORT_SYMBOL(heap_arena);
@@ -86,14 +80,17 @@ vmem_t *zio_arena = NULL;
EXPORT_SYMBOL(zio_arena);
#ifndef HAVE_FIRST_ONLINE_PGDAT
-struct pglist_data *first_online_pgdat(void)
+struct pglist_data *
+first_online_pgdat(void)
{
return NODE_DATA(first_online_node);
}
+EXPORT_SYMBOL(first_online_pgdat);
#endif /* HAVE_FIRST_ONLINE_PGDAT */
#ifndef HAVE_NEXT_ONLINE_PGDAT
-struct pglist_data *next_online_pgdat(struct pglist_data *pgdat)
+struct pglist_data *
+next_online_pgdat(struct pglist_data *pgdat)
{
int nid = next_online_node(pgdat->node_id);
@@ -102,10 +99,12 @@ struct pglist_data *next_online_pgdat(struct pglist_data *pgdat)
return NODE_DATA(nid);
}
+EXPORT_SYMBOL(next_online_pgdat);
#endif /* HAVE_NEXT_ONLINE_PGDAT */
#ifndef HAVE_NEXT_ZONE
-struct zone *next_zone(struct zone *zone)
+struct zone *
+next_zone(struct zone *zone)
{
pg_data_t *pgdat = zone->zone_pgdat;
@@ -120,8 +119,73 @@ struct zone *next_zone(struct zone *zone)
}
return zone;
}
+EXPORT_SYMBOL(next_zone);
#endif /* HAVE_NEXT_ZONE */
+#ifndef HAVE_GET_ZONE_COUNTS
+void
+__get_zone_counts(unsigned long *active, unsigned long *inactive,
+ unsigned long *free, struct pglist_data *pgdat)
+{
+ struct zone *zones = pgdat->node_zones;
+ int i;
+
+ *active = 0;
+ *inactive = 0;
+ *free = 0;
+ for (i = 0; i < MAX_NR_ZONES; i++) {
+ *active += zones[i].nr_active;
+ *inactive += zones[i].nr_inactive;
+ *free += zones[i].free_pages;
+ }
+}
+
+void
+get_zone_counts(unsigned long *active, unsigned long *inactive,
+ unsigned long *free)
+{
+ struct pglist_data *pgdat;
+
+ *active = 0;
+ *inactive = 0;
+ *free = 0;
+ for_each_online_pgdat(pgdat) {
+ unsigned long l, m, n;
+ __get_zone_counts(&l, &m, &n, pgdat);
+ *active += l;
+ *inactive += m;
+ *free += n;
+ }
+}
+EXPORT_SYMBOL(get_zone_counts);
+#endif /* HAVE_GET_ZONE_COUNTS */
+
+pgcnt_t
+spl_kmem_availrmem(void)
+{
+ unsigned long active;
+ unsigned long inactive;
+ unsigned long free;
+
+ get_zone_counts(&active, &inactive, &free);
+
+ /* The amount of easily available memory */
+ return free + inactive;
+}
+EXPORT_SYMBOL(spl_kmem_availrmem);
+
+size_t
+vmem_size(vmem_t *vmp, int typemask)
+{
+ /* Arena's unsupported */
+ ASSERT(vmp == NULL);
+ ASSERT(typemask & (VMEM_ALLOC | VMEM_FREE));
+
+ return 0;
+}
+EXPORT_SYMBOL(vmem_size);
+
+
/*
* Memory allocation interfaces and debugging for basic kmem_*
* and vmem_* style memory allocation. When DEBUG_KMEM is enable
@@ -1707,6 +1771,10 @@ spl_kmem_init_globals(void)
desfree += zone->pages_low;
lotsfree += zone->pages_high;
}
+
+ /* Solaris default values */
+ swapfs_minfree = MAX(2*1024*1024 / PAGE_SIZE, physmem / 8);
+ swapfs_reserve = MIN(4*1024*1024 / PAGE_SIZE, physmem / 16);
}
int
diff --git a/module/spl/spl-proc.c b/module/spl/spl-proc.c
index 024118a9f..1ae1c129a 100644
--- a/module/spl/spl-proc.c
+++ b/module/spl/spl-proc.c
@@ -91,9 +91,10 @@ struct proc_dir_entry *proc_spl_kstat = NULL;
#define CTL_VM_LOTSFREE CTL_UNNUMBERED /* Lots of free memory */
#define CTL_VM_NEEDFREE CTL_UNNUMBERED /* Need free memory */
#define CTL_VM_SWAPFS_MINFREE CTL_UNNUMBERED /* Minimum swapfs memory */
-#define CTL_VM_SWAPFS_DESFREE CTL_UNNUMBERED /* Desired swapfs memory */
#define CTL_VM_SWAPFS_RESERVE CTL_UNNUMBERED /* Reserved swapfs memory */
-#define CTL_VM_AVAILRMEM CTL_UNNUMBERED /* Available reserved memory */
+#define CTL_VM_AVAILRMEM CTL_UNNUMBERED /* Easily available memory */
+#define CTL_VM_FREEMEM CTL_UNNUMBERED /* Free memory */
+#define CTL_VM_PHYSMEM CTL_UNNUMBERED /* Total physical memory */
#ifdef DEBUG_KMEM
#define CTL_KMEM_KMEMUSED CTL_UNNUMBERED /* Alloc'd kmem bytes */
@@ -145,9 +146,10 @@ enum {
CTL_VM_LOTSFREE, /* Lots of free memory threshold */
CTL_VM_NEEDFREE, /* Need free memory deficit */
CTL_VM_SWAPFS_MINFREE, /* Minimum swapfs memory */
- CTL_VM_SWAPFS_DESFREE, /* Desired swapfs memory */
CTL_VM_SWAPFS_RESERVE, /* Reserved swapfs memory */
- CTL_VM_AVAILRMEM, /* Available reserved memory */
+ CTL_VM_AVAILRMEM, /* Easily available memory */
+ CTL_VM_FREEMEM, /* Free memory */
+ CTL_VM_PHYSMEM, /* Total physical memory */
#ifdef DEBUG_KMEM
CTL_KMEM_KMEMUSED, /* Alloc'd kmem bytes */
@@ -486,6 +488,58 @@ proc_dohostid(struct ctl_table *table, int write, struct file *filp,
RETURN(rc);
}
+static int
+proc_doavailrmem(struct ctl_table *table, int write, struct file *filp,
+ void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+ int len, rc = 0;
+ char str[32];
+ ENTRY;
+
+ if (write) {
+ *ppos += *lenp;
+ } else {
+ len = snprintf(str, sizeof(str), "%lu", (unsigned long)availrmem);
+ if (*ppos >= len)
+ rc = 0;
+ else
+ rc = proc_copyout_string(buffer, *lenp, str + *ppos, "\n");
+
+ if (rc >= 0) {
+ *lenp = rc;
+ *ppos += rc;
+ }
+ }
+
+ RETURN(rc);
+}
+
+static int
+proc_dofreemem(struct ctl_table *table, int write, struct file *filp,
+ void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+ int len, rc = 0;
+ char str[32];
+ ENTRY;
+
+ if (write) {
+ *ppos += *lenp;
+ } else {
+ len = snprintf(str, sizeof(str), "%lu", (unsigned long)freemem);
+ if (*ppos >= len)
+ rc = 0;
+ else
+ rc = proc_copyout_string(buffer, *lenp, str + *ppos, "\n");
+
+ if (rc >= 0) {
+ *lenp = rc;
+ *ppos += rc;
+ }
+ }
+
+ RETURN(rc);
+}
+
#ifdef DEBUG_MUTEX
static void
mutex_seq_show_headers(struct seq_file *f)
@@ -833,14 +887,6 @@ static struct ctl_table spl_vm_table[] = {
.proc_handler = &proc_dointvec,
},
{
- .ctl_name = CTL_VM_SWAPFS_DESFREE,
- .procname = "swapfs_desfree",
- .data = &swapfs_desfree,
- .maxlen = sizeof(int),
- .mode = 0644,
- .proc_handler = &proc_dointvec,
- },
- {
.ctl_name = CTL_VM_SWAPFS_RESERVE,
.procname = "swapfs_reserve",
.data = &swapfs_reserve,
@@ -851,7 +897,21 @@ static struct ctl_table spl_vm_table[] = {
{
.ctl_name = CTL_VM_AVAILRMEM,
.procname = "availrmem",
- .data = &availrmem,
+ .mode = 0444,
+ .proc_handler = &proc_doavailrmem,
+ },
+ {
+ .ctl_name = CTL_VM_FREEMEM,
+ .procname = "freemem",
+ .data = (void *)2,
+ .maxlen = sizeof(int),
+ .mode = 0444,
+ .proc_handler = &proc_dofreemem,
+ },
+ {
+ .ctl_name = CTL_VM_PHYSMEM,
+ .procname = "physmem",
+ .data = &physmem,
.maxlen = sizeof(int),
.mode = 0444,
.proc_handler = &proc_dointvec,
diff --git a/spl_config.h.in b/spl_config.h.in
index 2bfb5c487..1b7c8abab 100644
--- a/spl_config.h.in
+++ b/spl_config.h.in
@@ -51,6 +51,9 @@
/* fls64() is available */
#undef HAVE_FLS64
+/* get_zone_counts() is available */
+#undef HAVE_GET_ZONE_COUNTS
+
/* init_utsname() is available */
#undef HAVE_INIT_UTSNAME