patch for inode preallocation

Bill Hawes (whawes@star.net)
Wed, 15 Jul 1998 11:51:53 -0400


This is a multi-part message in MIME format.
--------------80D823EA3AE86EBC5B33D6E3
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

There's been some concern expressed recently that inode memory
allocations may be contributing to memory fragmentation. The degree of
fragmentation probably depends on how quickly the system builds up to
its inode limit, but fragmentation can be eliminated completely by
simply preallocating the inodes. The attached patch adds code to
inode_init() to preallocate inodes up to the max_inodes limit.

The patch also makes max_inodes scale with the system memory size, as
the previous default of 4096 is too many for a small system (e.g. 8M)
and probably too few for systems with 64M+. The NR_INODE value has been
changed to a macro using num_phypages as an argument, so that 16M maps
to 2048, 32M to 4096, etc.

If anyone has experienced problems believed to be due to inode memory
fragmentation, I'd appreciate giving this patch a try and reporting the
results here on the list. By eliminating inode allocation as a
contributor to fragmentation, this will help nail down the causes of
excessive fragmentation.

Regards,
Bill
--------------80D823EA3AE86EBC5B33D6E3
Content-Type: text/plain; charset=us-ascii; name="inode_prealloc108-patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="inode_prealloc108-patch"

--- linux-2.1.108/include/linux/fs.h.old Fri Jul 10 11:21:30 1998
+++ linux-2.1.108/include/linux/fs.h Wed Jul 15 09:46:47 1998
@@ -46,7 +46,17 @@
/* And dynamically-tunable limits and defaults: */
extern int max_inodes;
extern int max_files, nr_files, nr_free_files;
-#define NR_INODE 4096 /* This should no longer be bigger than NR_FILE */
+/*
+ * Make the default inode limit scale with memory size
+ * up to a limit. (A 32M system gets 4096 inodes.)
+ *
+ * Note: NR_INODE may be larger than NR_FILE, as unused
+ * inodes are still useful for preserving page cache.
+ */
+#define NR_INODE_MAX 16384
+#define NR_INODE(pages) \
+ (((pages) >> 1) <= NR_INODE_MAX ? ((pages) >> 1) : NR_INODE_MAX)
+
#define NR_FILE 4096 /* this can well be larger on a larger system */
#define NR_RESERVED_FILES 10 /* reserved for root */

--- linux-2.1.108/fs/inode.c.old Fri Jul 3 10:32:32 1998
+++ linux-2.1.108/fs/inode.c Wed Jul 15 09:42:51 1998
@@ -20,8 +20,12 @@
* Famous last words.
*/

+/* for sizing the inode limit */
+extern unsigned long num_physpages;
+
#define INODE_PARANOIA 1
/* #define INODE_DEBUG 1 */
+#define INODE_PREALLOC 1 /* make a CONFIG option */

/*
* Inode lookup is no longer as critical as it used to be:
@@ -65,7 +69,8 @@
int dummy[4];
} inodes_stat = {0, 0, 0,};

-int max_inodes = NR_INODE;
+/* Initialized in inode_init() */
+int max_inodes;

/*
* Put the inode on the super block's dirty list.
@@ -737,15 +791,35 @@
*/
void inode_init(void)
{
- int i;
struct list_head *head = inode_hashtable;
+ int i = HASH_SIZE;

- i = HASH_SIZE;
do {
INIT_LIST_HEAD(head);
head++;
i--;
} while (i);
+
+ /*
+ * Initialize the default maximum based on memory size.
+ */
+ max_inodes = NR_INODE(num_physpages);
+
+#ifdef INODE_PREALLOC
+ /*
+ * Preallocate the inodes to avoid memory fragmentation.
+ */
+ spin_lock(&inode_lock);
+ while (inodes_stat.nr_inodes < max_inodes) {
+ struct inode *inode = grow_inodes();
+ if (!inode)
+ goto done;
+ list_add(&inode->i_list, &inode_unused);
+ inodes_stat.nr_free_inodes++;
+ }
+ spin_unlock(&inode_lock);
+done:
+#endif
}

/* This belongs in file_table.c, not here... */

--------------80D823EA3AE86EBC5B33D6E3--

-
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.altern.org/andrebalsa/doc/lkml-faq.html