summaryrefslogtreecommitdiffstats
path: root/module
diff options
context:
space:
mode:
authorBrian Behlendorf <[email protected]>2009-07-28 15:06:42 -0700
committerBrian Behlendorf <[email protected]>2009-07-28 15:06:42 -0700
commit6ae7fef5b94275e50cc1dcd48c4ecf3b70d7f9d9 (patch)
tree6bee188c48e16981416bab356d02bc02817edae0 /module
parent6b09f739398a644384bfbab87792e4681707aef1 (diff)
Update global_page_state() support for 2.6.29 kernels.
Basically everything we need to monitor the global memory state of the system is now cleanly available via global_page_state(). The problem is that this interface is still fairly recent, and there has been one change in the page state enum which we need to handle. These changes basically boil down to the following: - If global_page_state() is available we should use it. Several autoconf checks have been added to detect the correct enum names. - If global_page_state() is not available check to see if get_zone_counts() symbol is available and use that. - If the get_zone_counts() symbol is not exported we have no choice be to dynamically aquire it at load time. This is an absolute last resort for old kernel which we don't want to patch to cleanly export the symbol.
Diffstat (limited to 'module')
-rw-r--r--module/spl/spl-kmem.c79
-rw-r--r--module/splat/splat-kmem.c45
2 files changed, 79 insertions, 45 deletions
diff --git a/module/spl/spl-kmem.c b/module/spl/spl-kmem.c
index 4edd3d7e1..b1124f706 100644
--- a/module/spl/spl-kmem.c
+++ b/module/spl/spl-kmem.c
@@ -109,49 +109,82 @@ EXPORT_SYMBOL(pgdat_list_addr);
#endif /* HAVE_PGDAT_HELPERS */
-#ifndef HAVE_ZONE_STAT_ITEM_FIA
+#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(int item)
+spl_global_page_state(spl_zone_stat_item_t item)
{
unsigned long active;
unsigned long inactive;
unsigned long free;
- if (item == NR_FREE_PAGES) {
- get_zone_counts(&active, &inactive, &free);
- return 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 */
}
- if (item == NR_INACTIVE) {
- get_zone_counts(&active, &inactive, &free);
- return inactive;
- }
-
- if (item == NR_ACTIVE) {
- get_zone_counts(&active, &inactive, &free);
- return active;
+ 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 */
}
-# ifdef HAVE_GLOBAL_PAGE_STATE
- return global_page_state((enum zone_stat_item)item);
+ return pages;
+}
# else
- return 0; /* Unsupported */
+# 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);
-#endif /* HAVE_ZONE_STAT_ITEM_FIA */
pgcnt_t
spl_kmem_availrmem(void)
{
/* The amount of easily available memory */
- return (spl_global_page_state(NR_FREE_PAGES) +
- spl_global_page_state(NR_INACTIVE));
+ return (spl_global_page_state(SPL_NR_FREE_PAGES) +
+ spl_global_page_state(SPL_NR_INACTIVE));
}
EXPORT_SYMBOL(spl_kmem_availrmem);
@@ -1856,16 +1889,14 @@ spl_kmem_init_kallsyms_lookup(void)
# endif /* HAVE_PGDAT_LIST */
#endif /* HAVE_PGDAT_HELPERS */
-#ifndef HAVE_ZONE_STAT_ITEM_FIA
-# ifndef HAVE_GET_ZONE_COUNTS
+#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 /* HAVE_GET_ZONE_COUNTS */
-#endif /* HAVE_ZONE_STAT_ITEM_FIA */
+#endif /* NEED_GET_ZONE_COUNTS && !HAVE_GET_ZONE_COUNTS */
/*
* It is now safe to initialize the global tunings which rely on
diff --git a/module/splat/splat-kmem.c b/module/splat/splat-kmem.c
index b021750ad..1007f7855 100644
--- a/module/splat/splat-kmem.c
+++ b/module/splat/splat-kmem.c
@@ -1045,16 +1045,17 @@ splat_kmem_test11(struct file *file, void *arg)
static int
splat_kmem_test12(struct file *file, void *arg)
{
- ssize_t alloc1, free1, total1;
- ssize_t alloc2, free2, total2;
+ size_t alloc1, free1, total1;
+ size_t alloc2, free2, total2;
int size = 8*1024*1024;
void *ptr;
alloc1 = vmem_size(NULL, VMEM_ALLOC);
free1 = vmem_size(NULL, VMEM_FREE);
total1 = vmem_size(NULL, VMEM_ALLOC | VMEM_FREE);
- splat_vprint(file, SPLAT_KMEM_TEST12_NAME, "Vmem alloc=%d free=%d "
- "total=%d\n", (int)alloc1, (int)free1, (int)total1);
+ splat_vprint(file, SPLAT_KMEM_TEST12_NAME, "Vmem alloc=%lu "
+ "free=%lu total=%lu\n", (unsigned long)alloc1,
+ (unsigned long)free1, (unsigned long)total1);
splat_vprint(file, SPLAT_KMEM_TEST12_NAME, "Alloc %d bytes\n", size);
ptr = vmem_alloc(size, KM_SLEEP);
@@ -1067,42 +1068,44 @@ splat_kmem_test12(struct file *file, void *arg)
alloc2 = vmem_size(NULL, VMEM_ALLOC);
free2 = vmem_size(NULL, VMEM_FREE);
total2 = vmem_size(NULL, VMEM_ALLOC | VMEM_FREE);
- splat_vprint(file, SPLAT_KMEM_TEST12_NAME, "Vmem alloc=%d free=%d "
- "total=%d\n", (int)alloc2, (int)free2, (int)total2);
+ splat_vprint(file, SPLAT_KMEM_TEST12_NAME, "Vmem alloc=%lu "
+ "free=%lu total=%lu\n", (unsigned long)alloc2,
+ (unsigned long)free2, (unsigned long)total2);
splat_vprint(file, SPLAT_KMEM_TEST12_NAME, "Free %d bytes\n", size);
vmem_free(ptr, size);
if (alloc2 < (alloc1 + size - (size / 100)) ||
alloc2 > (alloc1 + size + (size / 100))) {
- splat_vprint(file, SPLAT_KMEM_TEST12_NAME,
- "Failed VMEM_ALLOC size: %d != %d+%d (+/- 1%%)\n",
- (int)alloc2, (int)alloc1, size);
+ splat_vprint(file, SPLAT_KMEM_TEST12_NAME, "Failed "
+ "VMEM_ALLOC size: %lu != %lu+%d (+/- 1%%)\n",
+ (unsigned long)alloc2,(unsigned long)alloc1,size);
return -ERANGE;
}
if (free2 < (free1 - size - (size / 100)) ||
free2 > (free1 - size + (size / 100))) {
- splat_vprint(file, SPLAT_KMEM_TEST12_NAME,
- "Failed VMEM_FREE size: %d != %d-%d (+/- 1%%)\n",
- (int)free2, (int)free1, size);
+ splat_vprint(file, SPLAT_KMEM_TEST12_NAME, "Failed "
+ "VMEM_FREE size: %lu != %lu-%d (+/- 1%%)\n",
+ (unsigned long)free2, (unsigned long)free1, size);
return -ERANGE;
}
if (total1 != total2) {
- splat_vprint(file, SPLAT_KMEM_TEST12_NAME,
- "Failed VMEM_ALLOC | VMEM_FREE not constant: "
- "%d != %d\n", (int)total2, (int)total1);
+ splat_vprint(file, SPLAT_KMEM_TEST12_NAME, "Failed "
+ "VMEM_ALLOC | VMEM_FREE not constant: "
+ "%lu != %lu\n", (unsigned long)total2,
+ (unsigned long)total1);
return -ERANGE;
}
splat_vprint(file, SPLAT_KMEM_TEST12_NAME,
- "VMEM_ALLOC within tolerance: ~%d%% (%d/%d)\n",
- (int)(((alloc1 + size) - alloc2) * 100 / size),
- (int)((alloc1 + size) - alloc2), size);
+ "VMEM_ALLOC within tolerance: ~%ld%% (%ld/%d)\n",
+ (long)abs(alloc1 + (long)size - alloc2) * 100 / (long)size,
+ (long)abs(alloc1 + (long)size - alloc2), size);
splat_vprint(file, SPLAT_KMEM_TEST12_NAME,
- "VMEM_FREE within tolerance: ~%d%% (%d/%d)\n",
- (int)(((free1 - size) - free2) * 100 / size),
- (int)((free1 - size) - free2), size);
+ "VMEM_FREE within tolerance: ~%ld%% (%ld/%d)\n",
+ (long)abs((free1 - (long)size) - free2) * 100 / (long)size,
+ (long)abs((free1 - (long)size) - free2), size);
return 0;
}