summaryrefslogtreecommitdiffstats
path: root/module/spl/spl-kmem.c
diff options
context:
space:
mode:
Diffstat (limited to 'module/spl/spl-kmem.c')
-rw-r--r--module/spl/spl-kmem.c147
1 files changed, 75 insertions, 72 deletions
diff --git a/module/spl/spl-kmem.c b/module/spl/spl-kmem.c
index 18613e799..b8b006610 100644
--- a/module/spl/spl-kmem.c
+++ b/module/spl/spl-kmem.c
@@ -79,85 +79,29 @@ EXPORT_SYMBOL(zio_alloc_arena);
vmem_t *zio_arena = NULL;
EXPORT_SYMBOL(zio_arena);
+#ifndef HAVE_GET_VMALLOC_INFO
+get_vmalloc_info_t get_vmalloc_info_fn = NULL;
+EXPORT_SYMBOL(get_vmalloc_info_fn);
+#endif /* HAVE_GET_VMALLOC_INFO */
+
#ifndef HAVE_FIRST_ONLINE_PGDAT
-struct pglist_data *
-first_online_pgdat(void)
-{
- return NODE_DATA(first_online_node);
-}
-EXPORT_SYMBOL(first_online_pgdat);
+first_online_pgdat_t first_online_pgdat_fn = NULL;
+EXPORT_SYMBOL(first_online_pgdat_fn);
#endif /* HAVE_FIRST_ONLINE_PGDAT */
#ifndef HAVE_NEXT_ONLINE_PGDAT
-struct pglist_data *
-next_online_pgdat(struct pglist_data *pgdat)
-{
- int nid = next_online_node(pgdat->node_id);
-
- if (nid == MAX_NUMNODES)
- return NULL;
-
- return NODE_DATA(nid);
-}
-EXPORT_SYMBOL(next_online_pgdat);
+next_online_pgdat_t next_online_pgdat_fn = NULL;
+EXPORT_SYMBOL(next_online_pgdat_fn);
#endif /* HAVE_NEXT_ONLINE_PGDAT */
#ifndef HAVE_NEXT_ZONE
-struct zone *
-next_zone(struct zone *zone)
-{
- pg_data_t *pgdat = zone->zone_pgdat;
-
- if (zone < pgdat->node_zones + MAX_NR_ZONES - 1)
- zone++;
- else {
- pgdat = next_online_pgdat(pgdat);
- if (pgdat)
- zone = pgdat->node_zones;
- else
- zone = NULL;
- }
- return zone;
-}
-EXPORT_SYMBOL(next_zone);
+next_zone_t next_zone_fn = NULL;
+EXPORT_SYMBOL(next_zone_fn);
#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);
+get_zone_counts_t get_zone_counts_fn = NULL;
+EXPORT_SYMBOL(get_zone_counts_fn);
#endif /* HAVE_GET_ZONE_COUNTS */
pgcnt_t
@@ -177,11 +121,20 @@ EXPORT_SYMBOL(spl_kmem_availrmem);
size_t
vmem_size(vmem_t *vmp, int typemask)
{
- /* Arena's unsupported */
+ struct vmalloc_info vmi;
+ size_t size = 0;
+
ASSERT(vmp == NULL);
ASSERT(typemask & (VMEM_ALLOC | VMEM_FREE));
- return 0;
+ get_vmalloc_info(&vmi);
+ if (typemask & VMEM_ALLOC)
+ size += (size_t)vmi.used;
+
+ if (typemask & VMEM_FREE)
+ size += (size_t)(VMALLOC_TOTAL - vmi.used);
+
+ return size;
}
EXPORT_SYMBOL(vmem_size);
@@ -1812,6 +1765,57 @@ spl_kmem_init_globals(void)
swapfs_reserve = MIN(4*1024*1024 / PAGE_SIZE, physmem / 16);
}
+/*
+ * Called at module init when it is safe to use spl_kallsyms_lookup_name()
+ */
+int
+spl_kmem_init_kallsyms_lookup(void)
+{
+#ifndef HAVE_GET_VMALLOC_INFO
+ get_vmalloc_info_fn = (get_vmalloc_info_t)
+ spl_kallsyms_lookup_name("get_vmalloc_info");
+ if (!get_vmalloc_info_fn)
+ return -EFAULT;
+#endif /* HAVE_GET_VMALLOC_INFO */
+
+#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)
+ 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)
+ 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)
+ return -EFAULT;
+#endif /* HAVE_NEXT_ZONE */
+
+#ifndef HAVE_GET_ZONE_COUNTS
+ get_zone_counts_fn = (get_zone_counts_t)
+ spl_kallsyms_lookup_name("get_zone_counts");
+ if (!get_zone_counts_fn)
+ return -EFAULT;
+#endif /* 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();
+
+ return 0;
+}
+
int
spl_kmem_init(void)
{
@@ -1820,7 +1824,6 @@ spl_kmem_init(void)
init_rwsem(&spl_kmem_cache_sem);
INIT_LIST_HEAD(&spl_kmem_cache_list);
- spl_kmem_init_globals();
#ifdef HAVE_SET_SHRINKER
spl_kmem_cache_shrinker = set_shrinker(KMC_DEFAULT_SEEKS,