[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