diff options
-rw-r--r-- | config/spl-build.m4 | 18 | ||||
-rwxr-xr-x | configure | 39 | ||||
-rw-r--r-- | configure.ac | 1 | ||||
-rw-r--r-- | include/sys/vmsystm.h | 20 | ||||
-rw-r--r-- | module/spl/spl-kmem.c | 86 | ||||
-rw-r--r-- | module/spl/spl-proc.c | 86 | ||||
-rw-r--r-- | spl_config.h.in | 3 |
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])], + []) +]) @@ -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 |