[Codefragments-commits] manish commits r4 - in trunk: . mempressure
svn-commits at oss.oracle.com
svn-commits at oss.oracle.com
Thu Apr 15 19:14:12 CDT 2004
Author: manish
Date: 2004-04-15 18:14:10 -0500 (Thu, 15 Apr 2004)
New Revision: 4
Added:
trunk/mempressure/
trunk/mempressure/Makefile
trunk/mempressure/mempressure.c
Log:
mempressure module
Added: trunk/mempressure/Makefile
===================================================================
--- trunk/mempressure/Makefile 2004-04-13 21:48:57 UTC (rev 3)
+++ trunk/mempressure/Makefile 2004-04-15 23:14:10 UTC (rev 4)
@@ -0,0 +1,39 @@
+CC = gcc
+
+KSRC = /usr/src/linux-2.4
+GCCINC = $(shell echo "-I `$(CC) -print-search-dirs | sed -n 's/^install: \(.*\)/\1/p'`include")
+
+RH_MAGIC_DEFINES =
+
+ifeq ($(KVER),hugemem)
+ RH_MAGIC_DEFINES += -D__BOOT_KERNEL_HUGEMEM=1
+ RH_MAGIC_DEFINES += -D__BOOT_KERNEL_ENTERPRISE=0
+ RH_MAGIC_DEFINES += -D__BOOT_KERNEL_SMP=0
+ RH_MAGIC_DEFINES += -D__BOOT_KERNEL_UP=0
+endif
+ifeq ($(KVER),smp)
+ RH_MAGIC_DEFINES += -D__BOOT_KERNEL_HUGEMEM=0
+ RH_MAGIC_DEFINES += -D__BOOT_KERNEL_ENTERPRISE=0
+ RH_MAGIC_DEFINES += -D__BOOT_KERNEL_SMP=1
+ RH_MAGIC_DEFINES += -D__BOOT_KERNEL_UP=0
+endif
+ifeq ($(KVER),ent)
+ RH_MAGIC_DEFINES += -D__BOOT_KERNEL_HUGEMEM=0
+ RH_MAGIC_DEFINES += -D__BOOT_KERNEL_ENTERPRISE=1
+ RH_MAGIC_DEFINES += -D__BOOT_KERNEL_SMP=0
+ RH_MAGIC_DEFINES += -D__BOOT_KERNEL_UP=0
+endif
+ifeq ($(KVER),up)
+ RH_MAGIC_DEFINES += -D__BOOT_KERNEL_HUGEMEM=0
+ RH_MAGIC_DEFINES += -D__BOOT_KERNEL_ENTERPRISE=0
+ RH_MAGIC_DEFINES += -D__BOOT_KERNEL_SMP=0
+ RH_MAGIC_DEFINES += -D__BOOT_KERNEL_UP=1
+endif
+
+CFLAGS = -nostdinc -fno-strict-aliasing -fomit-frame-pointer -include $(KSRC)/include/linux/modversions.h -DMODVERSIONS -Wall -O2 -I$(KSRC)/include $(GCCINC) -DMODULE -DLINUX -D__KERNEL__ $(RH_MAGIC_DEFINES)
+
+mempressure.o: mempressure.c
+ $(CC) $(CFLAGS) -o $@ -c $<
+
+clean:
+ rm *.o
Added: trunk/mempressure/mempressure.c
===================================================================
--- trunk/mempressure/mempressure.c 2004-04-13 21:48:57 UTC (rev 3)
+++ trunk/mempressure/mempressure.c 2004-04-15 23:14:10 UTC (rev 4)
@@ -0,0 +1,292 @@
+/*
+ * mempressure.c
+ *
+ * Simple module to kmalloc/vmalloc arbitrarily sized chunks of memory, to
+ * aid in simulating low memory condiitons.
+ *
+ * Copyright (C) 2004 Oracle. All rights reserved.
+ *
+ * Author: Manish Singh <manish.singh at oracle.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have recieved a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/vmalloc.h>
+#include <linux/sysctl.h>
+
+/* This entire thing is quick and dirty and could be rewritten in a much
+ * nicer fashion.
+ */
+
+#ifdef CONFIG_SYSCTL
+
+#define MP_PRINT(level, fmt, args...) printk(level "mempressure: " fmt "\n", ## args)
+
+#define MP_INFO(fmt, args...) MP_PRINT(KERN_ERR, fmt, ## args)
+#define MP_ERR(fmt, args...) MP_PRINT(KERN_ERR, fmt, ## args)
+#define MP_DEBUG(fmt, args...) MP_PRINT(KERN_DEBUG, fmt, ## args)
+
+struct alloc_entry {
+ void *mem;
+ int id;
+ int size;
+ int vmalloc;
+ struct list_head list;
+};
+
+static LIST_HEAD(allocs);
+static int alloc_max_id = 0;
+static spinlock_t alloc_lock = SPIN_LOCK_UNLOCKED;
+
+enum {
+ DEBUG_MEMPRESSURE_ADD_KMALLOC = 1,
+ DEBUG_MEMPRESSURE_ADD_VMALLOC = 2,
+ DEBUG_MEMPRESSURE_DEL_ALLOC = 3,
+ DEBUG_MEMPRESSURE_SHOW_ALLOCS = 4,
+
+ DEBUG_MEMPRESSURE = 1000
+};
+
+static int add_alloc(ctl_table *table, int write, struct file *filp,
+ void *buffer, size_t *lenp, int do_vmalloc);
+static int del_alloc(ctl_table *table, int write, struct file *filp,
+ void *buffer, size_t *lenp);
+static int show_allocs(ctl_table *table, int write, struct file *filp,
+ void *buffer, size_t *lenp);
+static int add_kmalloc(ctl_table *table, int write, struct file *filp,
+ void *buffer, size_t *lenp);
+static int add_vmalloc(ctl_table *table, int write, struct file *filp,
+ void *buffer, size_t *lenp);
+
+static int add_kmalloc_val, add_vmalloc_val;
+static int del_alloc_id, show_allocs_dummy;
+
+static struct ctl_table_header *mempressure_sysctl_header;
+
+static ctl_table mempressure_table[] = {
+ {DEBUG_MEMPRESSURE_ADD_KMALLOC, "add_kmalloc",
+ &add_kmalloc_val, sizeof(int), 0644, NULL,
+ &add_kmalloc},
+ {DEBUG_MEMPRESSURE_ADD_VMALLOC, "add_vmalloc",
+ &add_vmalloc_val, sizeof(int), 0644, NULL,
+ &add_vmalloc},
+ {DEBUG_MEMPRESSURE_DEL_ALLOC, "del_alloc",
+ &del_alloc_id, sizeof(int), 0644, NULL,
+ &del_alloc},
+ {DEBUG_MEMPRESSURE_SHOW_ALLOCS, "show_allocs",
+ &show_allocs_dummy, sizeof(int), 0644, NULL,
+ &show_allocs},
+ {0}
+};
+
+static ctl_table mempressure_dir_table[] = {
+ {DEBUG_MEMPRESSURE, "mempressure", NULL, 0, 0555, mempressure_table,
+ 0, 0, 0, 0, 0},
+ {0}
+};
+
+static ctl_table mempressure_root_table[] = {
+ {CTL_DEBUG, "debug", NULL, 0, 0555, mempressure_dir_table,
+ 0, 0, 0, 0, 0},
+ {0}
+};
+
+#define COMMON_PROLOGUE do { \
+ spin_lock(&alloc_lock); \
+ ret = proc_dointvec(table, write, filp, buffer, lenp); \
+ if (!write || ret != 0) { \
+ spin_unlock(&alloc_lock); \
+ return ret; \
+ } \
+} while (0)
+
+#define COMMON_EPILOGUE \
+ spin_unlock(&alloc_lock); \
+ return ret
+
+#define FREE_ENTRY(entry) do { \
+ if (entry->vmalloc) \
+ vfree(entry->mem); \
+ else \
+ kfree(entry->mem); \
+ kfree(entry); \
+} while (0)
+
+static int add_alloc(ctl_table *table, int write, struct file *filp,
+ void *buffer, size_t *lenp, int do_vmalloc)
+{
+ int ret, size;
+ char *type;
+ struct alloc_entry *entry;
+
+ COMMON_PROLOGUE;
+
+ if (do_vmalloc) {
+ size = add_vmalloc_val;
+ type = "vmalloc";
+ } else {
+ size = add_kmalloc_val;
+ type = "kmalloc";
+ }
+
+ if (size <= 0) {
+ spin_unlock(&alloc_lock);
+ return ret;
+ }
+
+ entry = kmalloc(sizeof(*entry), GFP_KERNEL);
+
+ if (entry == NULL) {
+ MP_ERR("could not kmalloc housekeeping entry");
+
+ spin_unlock(&alloc_lock);
+ return -ENOMEM;
+ }
+
+ if (do_vmalloc)
+ entry->mem = vmalloc(size * 1024);
+ else
+ entry->mem = kmalloc(size * 1024, GFP_KERNEL);
+
+ if (entry->mem == NULL) {
+ kfree(entry);
+
+ MP_DEBUG("could not %s %dKB", type, size);
+
+ spin_unlock(&alloc_lock);
+ return -ENOMEM;
+ }
+
+ entry->id = alloc_max_id;
+ alloc_max_id++;
+
+ entry->size = size;
+ entry->vmalloc = do_vmalloc;
+
+ list_add_tail(&entry->list, &allocs);
+
+ MP_DEBUG("allocated %s %dKB", type, size);
+
+ COMMON_EPILOGUE;
+}
+
+static int del_alloc(ctl_table *table, int write, struct file *filp,
+ void *buffer, size_t *lenp)
+{
+ int ret;
+ struct list_head *lh, *next;
+ struct alloc_entry *entry;
+
+ COMMON_PROLOGUE;
+
+ list_for_each_safe (lh, next, &allocs) {
+ entry = list_entry(lh, struct alloc_entry, list);
+
+ if (entry->id == del_alloc_id) {
+ list_del(lh);
+ MP_DEBUG("deleting entry %d", entry->id);
+ FREE_ENTRY(entry);
+ }
+ }
+
+ COMMON_EPILOGUE;
+}
+
+static int show_allocs(ctl_table *table, int write, struct file *filp,
+ void *buffer, size_t *lenp)
+{
+ int ret;
+ struct list_head *lh;
+ struct alloc_entry *entry;
+
+ COMMON_PROLOGUE;
+
+ MP_DEBUG("showing entries");
+ MP_DEBUG(" id size (KB) vmalloc");
+
+ list_for_each(lh, &allocs) {
+ entry = list_entry(lh, struct alloc_entry, list);
+ MP_DEBUG("%10d %10d %s", entry->id, entry->size,
+ entry->vmalloc ? "yes" : " no");
+ }
+
+ MP_DEBUG("finished showing entries");
+
+ COMMON_EPILOGUE;
+}
+
+static int add_kmalloc(ctl_table *table, int write, struct file *filp,
+ void *buffer, size_t *lenp)
+{
+ return add_alloc(table, write, filp, buffer, lenp, 0);
+}
+
+static int add_vmalloc(ctl_table *table, int write, struct file *filp,
+ void *buffer, size_t *lenp)
+{
+ return add_alloc(table, write, filp, buffer, lenp, 1);
+}
+
+static int __init mempressure_init (void)
+{
+ MP_INFO("module loading");
+
+ mempressure_sysctl_header =
+ register_sysctl_table(mempressure_root_table, 0);
+
+ if (mempressure_sysctl_header == NULL) {
+ printk("mempressure: can't register to sysctl\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+static void __exit mempressure_exit (void)
+{
+ struct list_head *lh, *next;
+ struct alloc_entry *entry;
+
+ MP_INFO("module exiting");
+
+ spin_lock(&alloc_lock);
+
+ list_for_each_safe (lh, next, &allocs) {
+ entry = list_entry(lh, struct alloc_entry, list);
+
+ /*MP_DEBUG("cleaning entry: %d %d %d",
+ entry->id, entry->size, entry->vmalloc);*/
+
+ FREE_ENTRY(entry);
+ }
+
+ spin_unlock(&alloc_lock);
+
+ unregister_sysctl_table(mempressure_sysctl_header);
+}
+
+module_init(mempressure_init);
+module_exit(mempressure_exit);
+MODULE_LICENSE ("GPL");
+
+#else
+#error "Need a sysctl enabled kernel!"
+#endif
More information about the Codefragments-commits
mailing list