[patch] getnamebuf second try (not in the slab)

Andrea Arcangeli (andrea@e-mind.com)
Mon, 18 Jan 1999 16:36:56 +0100 (CET)


I didn't liked too much to use the slab cache to cache the getname buf.
Also because usually there's only one process that use the getname buf at
one time. So I changed a bit the way I cache it. This make sense to me and
works fine. I had no time to bench it though...

If somebody would try some:

time find / &>/dev/null

with and w/o the patch, please then let me know the results.

Patch against pre-8.gz in testing/:

Index: linux/fs/namei.c
diff -u linux/fs/namei.c:1.1.1.2 linux/fs/namei.c:1.1.2.3
--- linux/fs/namei.c:1.1.1.2 Mon Jan 18 14:38:53 1999
+++ linux/fs/namei.c Mon Jan 18 16:27:39 1999
@@ -16,6 +16,7 @@
#include <linux/proc_fs.h>
#include <linux/smp_lock.h>
#include <linux/quotaops.h>
+#include <linux/init.h>

#include <asm/uaccess.h>
#include <asm/unaligned.h>
@@ -101,6 +102,28 @@
*
* POSIX.1 2.4: an empty pathname is invalid (ENOENT).
*/
+
+/*
+ * getname buffer caching, Copyright (C) 1999 Andrea Arcangeli
+ */
+static char * getnamebuf;
+static unsigned long getnamebuf_inuse = 0;
+
+static char * __getname(void)
+{
+ if (!test_and_set_bit(1, &getnamebuf_inuse))
+ return getnamebuf;
+ else
+ return (char *) __get_free_page(GFP_KERNEL);
+}
+void putname(char * name)
+{
+ if (name == getnamebuf)
+ clear_bit(1, &getnamebuf_inuse);
+ else
+ free_page((unsigned long) name);
+}
+
static inline int do_getname(const char *filename, char *page)
{
int retval;
@@ -1316,4 +1339,14 @@
}
unlock_kernel();
return error;
+}
+
+unsigned long __init namei_init(unsigned long start, unsigned long end)
+{
+ start = PAGE_ALIGN(start);
+ getnamebuf = (char *) start;
+ start += PAGE_SIZE;
+ if (start > end)
+ panic("namei_init: no enough memory");
+ return start;
}
Index: linux/include/linux/fs.h
diff -u linux/include/linux/fs.h:1.1.1.1 linux/include/linux/fs.h:1.1.2.2
--- linux/include/linux/fs.h:1.1.1.1 Mon Jan 18 02:27:02 1999
+++ linux/include/linux/fs.h Mon Jan 18 16:27:40 1999
@@ -168,6 +168,7 @@
extern void inode_init(void);
extern void file_table_init(void);
extern void dcache_init(void);
+extern unsigned long namei_init(unsigned long start, unsigned long end);

typedef char buffer_block[BLOCK_SIZE];

@@ -696,9 +687,8 @@
extern int close_fp(struct file *, fl_owner_t id);
extern struct file *filp_open(const char *, int, int);

-extern char * getname(const char * filename);
-#define __getname() ((char *) __get_free_page(GFP_KERNEL))
-#define putname(name) free_page((unsigned long)(name))
+extern char * FASTCALL(getname(const char * filename));
+extern void FASTCALL(putname(char * name));

extern void kill_fasync(struct fasync_struct *fa, int sig);
extern int register_blkdev(unsigned int, const char *, struct file_operations *);
Index: linux/init/main.c
diff -u linux/init/main.c:1.1.1.1 linux/init/main.c:1.1.2.2
--- linux/init/main.c:1.1.1.1 Mon Jan 18 02:26:59 1999
+++ linux/init/main.c Mon Jan 18 16:27:41 1999
@@ -1138,6 +1138,7 @@
memset(prof_buffer, 0, prof_len * sizeof(unsigned int));
}

+ memory_start = namei_init(memory_start, memory_end);
memory_start = kmem_cache_init(memory_start, memory_end);
sti();
calibrate_delay();

Andrea Arcangeli

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/