diff options
author | Brian Behlendorf <[email protected]> | 2014-10-01 18:34:41 -0400 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2014-10-17 15:11:51 -0700 |
commit | 8bbbe46f8680389888d6111f8d81429dcc5defac (patch) | |
tree | 5c4aaeafb2ef237e884021082fac39bb373f2dcf /module | |
parent | e1310afae3bdb17628b40c35561f2daedfaf4062 (diff) |
Remove global memory variables
Platforms such as Illumos and FreeBSD have historically provided
global variables which summerize the memory state of a system.
Linux on the otherhand doesn't expose any of this information
to kernel modules and uses entirely different mechanisms for
memory management.
In order to simplify the original ZFS port to Linux these global
variables were emulated by the SPL for the benefit of ZFS. As ZoL
has matured over the years it has moved steadily away from these
interfaces and now no longer depends on them at all.
Therefore, this patch completely removes the global variables
availrmem, minfree, desfree, lotsfree, needfree, swapfs_minfree,
and swapfs_reserve. This greatly simplifies the memory management
code and eliminates a common area of confusion.
Signed-off-by: Brian Behlendorf <[email protected]>
Diffstat (limited to 'module')
-rw-r--r-- | module/spl/spl-kmem.c | 220 | ||||
-rw-r--r-- | module/spl/spl-proc.c | 119 | ||||
-rw-r--r-- | module/splat/splat-kmem.c | 5 |
3 files changed, 2 insertions, 342 deletions
diff --git a/module/spl/spl-kmem.c b/module/spl/spl-kmem.c index 7626a2951..aeb1d2a06 100644 --- a/module/spl/spl-kmem.c +++ b/module/spl/spl-kmem.c @@ -101,44 +101,6 @@ module_param(spl_kmem_cache_kmem_limit, uint, 0644); MODULE_PARM_DESC(spl_kmem_cache_kmem_limit, "Objects less than N bytes use the kmalloc"); -/* - * The minimum amount of memory measured in pages to be free at all - * times on the system. This is similar to Linux's zone->pages_min - * multiplied by the number of zones and is sized based on that. - */ -pgcnt_t minfree = 0; -EXPORT_SYMBOL(minfree); - -/* - * The desired amount of memory measured in pages to be free at all - * times on the system. This is similar to Linux's zone->pages_low - * multiplied by the number of zones and is sized based on that. - * Assuming all zones are being used roughly equally, when we drop - * below this threshold asynchronous page reclamation is triggered. - */ -pgcnt_t desfree = 0; -EXPORT_SYMBOL(desfree); - -/* - * When above this amount of memory measures in pages the system is - * determined to have enough free memory. This is similar to Linux's - * zone->pages_high multiplied by the number of zones and is sized based - * on that. Assuming all zones are being used roughly equally, when - * asynchronous page reclamation reaches this threshold it stops. - */ -pgcnt_t lotsfree = 0; -EXPORT_SYMBOL(lotsfree); - -/* Unused always 0 in this implementation */ -pgcnt_t needfree = 0; -EXPORT_SYMBOL(needfree); - -pgcnt_t swapfs_minfree = 0; -EXPORT_SYMBOL(swapfs_minfree); - -pgcnt_t swapfs_reserve = 0; -EXPORT_SYMBOL(swapfs_reserve); - vmem_t *heap_arena = NULL; EXPORT_SYMBOL(heap_arena); @@ -148,101 +110,6 @@ EXPORT_SYMBOL(zio_alloc_arena); vmem_t *zio_arena = NULL; EXPORT_SYMBOL(zio_arena); -#ifdef HAVE_PGDAT_HELPERS -# ifndef HAVE_FIRST_ONLINE_PGDAT -first_online_pgdat_t first_online_pgdat_fn = SYMBOL_POISON; -EXPORT_SYMBOL(first_online_pgdat_fn); -# endif /* HAVE_FIRST_ONLINE_PGDAT */ - -# ifndef HAVE_NEXT_ONLINE_PGDAT -next_online_pgdat_t next_online_pgdat_fn = SYMBOL_POISON; -EXPORT_SYMBOL(next_online_pgdat_fn); -# endif /* HAVE_NEXT_ONLINE_PGDAT */ - -# ifndef HAVE_NEXT_ZONE -next_zone_t next_zone_fn = SYMBOL_POISON; -EXPORT_SYMBOL(next_zone_fn); -# endif /* HAVE_NEXT_ZONE */ - -#else /* HAVE_PGDAT_HELPERS */ - -# ifndef HAVE_PGDAT_LIST -struct pglist_data *pgdat_list_addr = SYMBOL_POISON; -EXPORT_SYMBOL(pgdat_list_addr); -# endif /* HAVE_PGDAT_LIST */ - -#endif /* HAVE_PGDAT_HELPERS */ - -#ifdef NEED_GET_ZONE_COUNTS -# ifndef HAVE_GET_ZONE_COUNTS -get_zone_counts_t get_zone_counts_fn = SYMBOL_POISON; -EXPORT_SYMBOL(get_zone_counts_fn); -# endif /* HAVE_GET_ZONE_COUNTS */ - -unsigned long -spl_global_page_state(spl_zone_stat_item_t item) -{ - unsigned long active; - unsigned long inactive; - unsigned long free; - - get_zone_counts(&active, &inactive, &free); - switch (item) { - case SPL_NR_FREE_PAGES: return free; - case SPL_NR_INACTIVE: return inactive; - case SPL_NR_ACTIVE: return active; - default: ASSERT(0); /* Unsupported */ - } - - return 0; -} -#else -# ifdef HAVE_GLOBAL_PAGE_STATE -unsigned long -spl_global_page_state(spl_zone_stat_item_t item) -{ - unsigned long pages = 0; - - switch (item) { - case SPL_NR_FREE_PAGES: -# ifdef HAVE_ZONE_STAT_ITEM_NR_FREE_PAGES - pages += global_page_state(NR_FREE_PAGES); -# endif - break; - case SPL_NR_INACTIVE: -# ifdef HAVE_ZONE_STAT_ITEM_NR_INACTIVE - pages += global_page_state(NR_INACTIVE); -# endif -# ifdef HAVE_ZONE_STAT_ITEM_NR_INACTIVE_ANON - pages += global_page_state(NR_INACTIVE_ANON); -# endif -# ifdef HAVE_ZONE_STAT_ITEM_NR_INACTIVE_FILE - pages += global_page_state(NR_INACTIVE_FILE); -# endif - break; - case SPL_NR_ACTIVE: -# ifdef HAVE_ZONE_STAT_ITEM_NR_ACTIVE - pages += global_page_state(NR_ACTIVE); -# endif -# ifdef HAVE_ZONE_STAT_ITEM_NR_ACTIVE_ANON - pages += global_page_state(NR_ACTIVE_ANON); -# endif -# ifdef HAVE_ZONE_STAT_ITEM_NR_ACTIVE_FILE - pages += global_page_state(NR_ACTIVE_FILE); -# endif - break; - default: - ASSERT(0); /* Unsupported */ - } - - return pages; -} -# else -# error "Both global_page_state() and get_zone_counts() unavailable" -# endif /* HAVE_GLOBAL_PAGE_STATE */ -#endif /* NEED_GET_ZONE_COUNTS */ -EXPORT_SYMBOL(spl_global_page_state); - #ifndef HAVE_SHRINK_DCACHE_MEMORY shrink_dcache_memory_t shrink_dcache_memory_fn = SYMBOL_POISON; EXPORT_SYMBOL(shrink_dcache_memory_fn); @@ -253,15 +120,6 @@ shrink_icache_memory_t shrink_icache_memory_fn = SYMBOL_POISON; EXPORT_SYMBOL(shrink_icache_memory_fn); #endif /* HAVE_SHRINK_ICACHE_MEMORY */ -pgcnt_t -spl_kmem_availrmem(void) -{ - /* The amount of easily available memory */ - return (spl_global_page_state(SPL_NR_FREE_PAGES) + - spl_global_page_state(SPL_NR_INACTIVE)); -} -EXPORT_SYMBOL(spl_kmem_availrmem); - size_t vmem_size(vmem_t *vmp, int typemask) { @@ -2458,90 +2316,12 @@ spl_kmem_fini_tracking(struct list_head *list, spinlock_t *lock) #define spl_kmem_fini_tracking(list, lock) #endif /* DEBUG_KMEM && DEBUG_KMEM_TRACKING */ -static void -spl_kmem_init_globals(void) -{ - struct zone *zone; - - /* For now all zones are includes, it may be wise to restrict - * this to normal and highmem zones if we see problems. */ - for_each_zone(zone) { - - if (!populated_zone(zone)) - continue; - - minfree += min_wmark_pages(zone); - desfree += low_wmark_pages(zone); - lotsfree += high_wmark_pages(zone); - } - - /* Solaris default values */ - swapfs_minfree = MAX(2*1024*1024 >> PAGE_SHIFT, physmem >> 3); - swapfs_reserve = MIN(4*1024*1024 >> PAGE_SHIFT, physmem >> 4); -} - /* * Called at module init when it is safe to use spl_kallsyms_lookup_name() */ int spl_kmem_init_kallsyms_lookup(void) { -#ifdef HAVE_PGDAT_HELPERS -# ifndef HAVE_FIRST_ONLINE_PGDAT - first_online_pgdat_fn = (first_online_pgdat_t) - spl_kallsyms_lookup_name("first_online_pgdat"); - if (!first_online_pgdat_fn) { - printk(KERN_ERR "Error: Unknown symbol first_online_pgdat\n"); - return -EFAULT; - } -# endif /* HAVE_FIRST_ONLINE_PGDAT */ - -# ifndef HAVE_NEXT_ONLINE_PGDAT - next_online_pgdat_fn = (next_online_pgdat_t) - spl_kallsyms_lookup_name("next_online_pgdat"); - if (!next_online_pgdat_fn) { - printk(KERN_ERR "Error: Unknown symbol next_online_pgdat\n"); - return -EFAULT; - } -# endif /* HAVE_NEXT_ONLINE_PGDAT */ - -# ifndef HAVE_NEXT_ZONE - next_zone_fn = (next_zone_t) - spl_kallsyms_lookup_name("next_zone"); - if (!next_zone_fn) { - printk(KERN_ERR "Error: Unknown symbol next_zone\n"); - return -EFAULT; - } -# endif /* HAVE_NEXT_ZONE */ - -#else /* HAVE_PGDAT_HELPERS */ - -# ifndef HAVE_PGDAT_LIST - pgdat_list_addr = *(struct pglist_data **) - spl_kallsyms_lookup_name("pgdat_list"); - if (!pgdat_list_addr) { - printk(KERN_ERR "Error: Unknown symbol pgdat_list\n"); - return -EFAULT; - } -# endif /* HAVE_PGDAT_LIST */ -#endif /* HAVE_PGDAT_HELPERS */ - -#if defined(NEED_GET_ZONE_COUNTS) && !defined(HAVE_GET_ZONE_COUNTS) - get_zone_counts_fn = (get_zone_counts_t) - spl_kallsyms_lookup_name("get_zone_counts"); - if (!get_zone_counts_fn) { - printk(KERN_ERR "Error: Unknown symbol get_zone_counts\n"); - return -EFAULT; - } -#endif /* NEED_GET_ZONE_COUNTS && !HAVE_GET_ZONE_COUNTS */ - - /* - * It is now safe to initialize the global tunings which rely on - * the use of the for_each_zone() macro. This macro in turns - * depends on the *_pgdat symbols which are now available. - */ - spl_kmem_init_globals(); - #ifndef HAVE_SHRINK_DCACHE_MEMORY /* When shrink_dcache_memory_fn == NULL support is disabled */ shrink_dcache_memory_fn = (shrink_dcache_memory_t) diff --git a/module/spl/spl-proc.c b/module/spl/spl-proc.c index 3daa3deea..9c42c96ea 100644 --- a/module/spl/spl-proc.c +++ b/module/spl/spl-proc.c @@ -454,55 +454,6 @@ SPL_PROC_HANDLER(proc_dokallsyms_lookup_name) } #endif /* HAVE_KALLSYMS_LOOKUP_NAME */ -SPL_PROC_HANDLER(proc_doavailrmem) -{ - int len, rc = 0; - char str[32]; - SENTRY; - - 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; - } - } - - SRETURN(rc); -} - -SPL_PROC_HANDLER(proc_dofreemem) -{ - int len, rc = 0; - char str[32]; - SENTRY; - - 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; - } - } - - SRETURN(rc); -} - #ifdef DEBUG_KMEM static void slab_seq_show_headers(struct seq_file *f) @@ -719,71 +670,6 @@ static struct ctl_table spl_debug_table[] = { }; #endif /* DEBUG_LOG */ -static struct ctl_table spl_vm_table[] = { - { - .procname = "minfree", - .data = &minfree, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = &proc_dointvec, - }, - { - .procname = "desfree", - .data = &desfree, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = &proc_dointvec, - }, - { - .procname = "lotsfree", - .data = &lotsfree, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = &proc_dointvec, - }, - { - .procname = "needfree", - .data = &needfree, - .maxlen = sizeof(int), - .mode = 0444, - .proc_handler = &proc_dointvec, - }, - { - .procname = "swapfs_minfree", - .data = &swapfs_minfree, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = &proc_dointvec, - }, - { - .procname = "swapfs_reserve", - .data = &swapfs_reserve, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = &proc_dointvec, - }, - { - .procname = "availrmem", - .mode = 0444, - .proc_handler = &proc_doavailrmem, - }, - { - .procname = "freemem", - .data = (void *)2, - .maxlen = sizeof(int), - .mode = 0444, - .proc_handler = &proc_dofreemem, - }, - { - .procname = "physmem", - .data = &physmem, - .maxlen = sizeof(int), - .mode = 0444, - .proc_handler = &proc_dointvec, - }, - {0}, -}; - #ifdef DEBUG_KMEM static struct ctl_table spl_kmem_table[] = { { @@ -922,11 +808,6 @@ static struct ctl_table spl_table[] = { .child = spl_debug_table, }, #endif - { - .procname = "vm", - .mode = 0555, - .child = spl_vm_table, - }, #ifdef DEBUG_KMEM { .procname = "kmem", diff --git a/module/splat/splat-kmem.c b/module/splat/splat-kmem.c index ebc6a042f..76643db18 100644 --- a/module/splat/splat-kmem.c +++ b/module/splat/splat-kmem.c @@ -1052,9 +1052,8 @@ splat_kmem_test10(struct file *file, void *arg) for (alloc = 1; alloc <= 1024; alloc *= 2) { - /* Skip tests which exceed available memory. We - * leverage availrmem here for some extra testing */ - if (size * alloc * SPLAT_KMEM_THREADS > availrmem / 2) + /* Skip tests which exceed 1/2 of physical memory. */ + if (size * alloc * SPLAT_KMEM_THREADS > physmem / 2) continue; rc = splat_kmem_cache_thread_test(file, arg, |