SPL_AC_ATOMIC_SPINLOCK
SPL_AC_SHRINKER_CALLBACK
SPL_AC_CTL_NAME
- SPL_AC_VMALLOC_INFO
SPL_AC_PDE_DATA
SPL_AC_MUTEX_OWNER
SPL_AC_MUTEX_OWNER_TASK_STRUCT
SPL_AC_KALLSYMS_LOOKUP_NAME
- SPL_AC_GET_VMALLOC_INFO
SPL_AC_PGDAT_HELPERS
SPL_AC_FIRST_ONLINE_PGDAT
SPL_AC_NEXT_ONLINE_PGDAT
])
])
-dnl #
-dnl # Proposed API change,
-dnl # This symbol is not available in stock kernels. You may build a
-dnl # custom kernel with the *-spl-export-symbols.patch which will export
-dnl # these symbols for use. If your already rolling a custom kernel for
-dnl # your environment this is recommended.
-dnl #
-AC_DEFUN([SPL_AC_GET_VMALLOC_INFO],
- [AC_MSG_CHECKING([whether get_vmalloc_info() is available])
- SPL_CHECK_SYMBOL_EXPORT([get_vmalloc_info], [], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_GET_VMALLOC_INFO, 1,
- [get_vmalloc_info() is available])
- ], [
- AC_MSG_RESULT(no)
- ])
-])
-
-dnl #
-dnl # 3.10 API change,
-dnl # struct vmalloc_info is now declared in linux/vmalloc.h
-dnl #
-AC_DEFUN([SPL_AC_VMALLOC_INFO], [
- AC_MSG_CHECKING([whether struct vmalloc_info is declared])
- SPL_LINUX_TRY_COMPILE([
- #include <linux/vmalloc.h>
- struct vmalloc_info { void *a; };
- ],[
- return 0;
- ],[
- AC_MSG_RESULT(no)
- ],[
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_VMALLOC_INFO, 1, [yes])
- ])
-])
-
dnl #
dnl # 3.10 API change,
dnl # PDE is replaced by PDE_DATA
extern pgcnt_t spl_kmem_availrmem(void);
extern size_t vmem_size(vmem_t *vmp, int typemask);
-/*
- * The following symbols are available for use within the kernel
- * itself, and they used to be available in older kernels. But it
- * looks like they have been removed perhaps due to lack of use.
- * For our purposes we need them to access the global memory state
- * of the system, which is even available to user space process
- * in /proc/meminfo. It's odd to me that there is no kernel API
- * to get the same information, minimally the proc handler for
- * the above mentioned /proc/meminfo file would make use of it.
- */
-
-/* Source linux/fs/proc/mmu.c */
-#ifndef HAVE_GET_VMALLOC_INFO
-#ifdef CONFIG_MMU
+#define VMEM_ALLOC 0x01
+#define VMEM_FREE 0x02
-#ifndef HAVE_VMALLOC_INFO
-struct vmalloc_info {
- unsigned long used;
- unsigned long largest_chunk;
-};
+#ifndef VMALLOC_TOTAL
+#define VMALLOC_TOTAL (VMALLOC_END - VMALLOC_START)
#endif
-typedef void (*get_vmalloc_info_t)(struct vmalloc_info *);
-extern get_vmalloc_info_t get_vmalloc_info_fn;
-
-# define VMEM_ALLOC 0x01
-# define VMEM_FREE 0x02
-# define VMALLOC_TOTAL (VMALLOC_END - VMALLOC_START)
-# define get_vmalloc_info(vmi) get_vmalloc_info_fn(vmi)
-#else
-# error "CONFIG_MMU must be defined"
-#endif /* CONFIG_MMU */
-#endif /* HAVE_GET_VMALLOC_INFO */
-
#ifdef HAVE_PGDAT_HELPERS
/* Source linux/mm/mmzone.c */
# ifndef HAVE_FIRST_ONLINE_PGDAT
vmem_t *zio_arena = NULL;
EXPORT_SYMBOL(zio_arena);
-#ifndef HAVE_GET_VMALLOC_INFO
-get_vmalloc_info_t get_vmalloc_info_fn = SYMBOL_POISON;
-EXPORT_SYMBOL(get_vmalloc_info_fn);
-#endif /* HAVE_GET_VMALLOC_INFO */
-
#ifdef HAVE_PGDAT_HELPERS
# ifndef HAVE_FIRST_ONLINE_PGDAT
first_online_pgdat_t first_online_pgdat_fn = SYMBOL_POISON;
size_t
vmem_size(vmem_t *vmp, int typemask)
{
- struct vmalloc_info vmi;
- size_t size = 0;
-
- ASSERT(vmp == NULL);
- ASSERT(typemask & (VMEM_ALLOC | VMEM_FREE));
-
- get_vmalloc_info(&vmi);
- if (typemask & VMEM_ALLOC)
- size += (size_t)vmi.used;
+ ASSERT3P(vmp, ==, NULL);
+ ASSERT3S(typemask & VMEM_ALLOC, ==, VMEM_ALLOC);
+ ASSERT3S(typemask & VMEM_FREE, ==, VMEM_FREE);
- if (typemask & VMEM_FREE)
- size += (size_t)(VMALLOC_TOTAL - vmi.used);
-
- return size;
+ return (VMALLOC_TOTAL);
}
EXPORT_SYMBOL(vmem_size);
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) {
- printk(KERN_ERR "Error: Unknown symbol get_vmalloc_info\n");
- return -EFAULT;
- }
-#endif /* HAVE_GET_VMALLOC_INFO */
-
#ifdef HAVE_PGDAT_HELPERS
# ifndef HAVE_FIRST_ONLINE_PGDAT
first_online_pgdat_fn = (first_online_pgdat_t)
#define SPLAT_KMEM_TEST11_DESC "Slab memory overcommit test"
#endif
-#define SPLAT_KMEM_TEST12_ID 0x010c
-#define SPLAT_KMEM_TEST12_NAME "vmem_size"
-#define SPLAT_KMEM_TEST12_DESC "Memory zone test"
-
#define SPLAT_KMEM_TEST13_ID 0x010d
#define SPLAT_KMEM_TEST13_NAME "slab_reclaim"
#define SPLAT_KMEM_TEST13_DESC "Slab direct memory reclaim test"
}
#endif
-/*
- * Check vmem_size() behavior by acquiring the alloc/free/total vmem
- * space, then allocate a known buffer size from vmem space. We can
- * then check that vmem_size() values were updated properly with in
- * a fairly small tolerence. The tolerance is important because we
- * are not the only vmem consumer on the system. Other unrelated
- * allocations might occur during the small test window. The vmem
- * allocation itself may also add in a little extra private space to
- * the buffer. Finally, verify total space always remains unchanged.
- */
-static int
-splat_kmem_test12(struct file *file, void *arg)
-{
- 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=%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);
- if (!ptr) {
- splat_vprint(file, SPLAT_KMEM_TEST12_NAME,
- "Failed to alloc %d bytes\n", size);
- return -ENOMEM;
- }
-
- 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=%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: %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: %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: "
- "%lu != %lu\n", (unsigned long)total2,
- (unsigned long)total1);
- return -ERANGE;
- }
-
- splat_vprint(file, SPLAT_KMEM_TEST12_NAME,
- "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: ~%ld%% (%ld/%d)\n",
- (long)abs((free1 - (long)size) - free2) * 100 / (long)size,
- (long)abs((free1 - (long)size) - free2), size);
-
- return 0;
-}
-
typedef struct dummy_page {
struct list_head dp_list;
char dp_pad[PAGE_SIZE - sizeof(struct list_head)];
SPLAT_TEST_INIT(sub, SPLAT_KMEM_TEST11_NAME, SPLAT_KMEM_TEST11_DESC,
SPLAT_KMEM_TEST11_ID, splat_kmem_test11);
#endif
- SPLAT_TEST_INIT(sub, SPLAT_KMEM_TEST12_NAME, SPLAT_KMEM_TEST12_DESC,
- SPLAT_KMEM_TEST12_ID, splat_kmem_test12);
SPLAT_TEST_INIT(sub, SPLAT_KMEM_TEST13_NAME, SPLAT_KMEM_TEST13_DESC,
SPLAT_KMEM_TEST13_ID, splat_kmem_test13);
{
ASSERT(sub);
SPLAT_TEST_FINI(sub, SPLAT_KMEM_TEST13_ID);
- SPLAT_TEST_FINI(sub, SPLAT_KMEM_TEST12_ID);
#if 0
SPLAT_TEST_FINI(sub, SPLAT_KMEM_TEST11_ID);
#endif