Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e12ba74d authored by Mel Gorman's avatar Mel Gorman Committed by Linus Torvalds
Browse files

Group short-lived and reclaimable kernel allocations



This patch marks a number of allocations that are either short-lived such as
network buffers or are reclaimable such as inode allocations.  When something
like updatedb is called, long-lived and unmovable kernel allocations tend to
be spread throughout the address space which increases fragmentation.

This patch groups these allocations together as much as possible by adding a
new MIGRATE_TYPE.  The MIGRATE_RECLAIMABLE type is for allocations that can be
reclaimed on demand, but not moved.  i.e.  they can be migrated by deleting
them and re-reading the information from elsewhere.

Signed-off-by: default avatarMel Gorman <mel@csn.ul.ie>
Cc: Andy Whitcroft <apw@shadowen.org>
Cc: Christoph Lameter <clameter@sgi.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent c361be55
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -3169,7 +3169,8 @@ static void recalc_bh_state(void)
	
struct buffer_head *alloc_buffer_head(gfp_t gfp_flags)
{
	struct buffer_head *ret = kmem_cache_zalloc(bh_cachep, gfp_flags);
	struct buffer_head *ret = kmem_cache_zalloc(bh_cachep,
				set_migrateflags(gfp_flags, __GFP_RECLAIMABLE));
	if (ret) {
		INIT_LIST_HEAD(&ret->b_assoc_buffers);
		get_cpu_var(bh_accounting).nr++;
+2 −2
Original line number Diff line number Diff line
@@ -1710,7 +1710,7 @@ static int journal_init_journal_head_cache(void)
	journal_head_cache = kmem_cache_create("journal_head",
				sizeof(struct journal_head),
				0,		/* offset */
				0,		/* flags */
				SLAB_TEMPORARY,	/* flags */
				NULL);		/* ctor */
	retval = 0;
	if (journal_head_cache == 0) {
@@ -2006,7 +2006,7 @@ static int __init journal_init_handle_cache(void)
	jbd_handle_cache = kmem_cache_create("journal_handle",
				sizeof(handle_t),
				0,		/* offset */
				0,		/* flags */
				SLAB_TEMPORARY,	/* flags */
				NULL);		/* ctor */
	if (jbd_handle_cache == NULL) {
		printk(KERN_EMERG "JBD: failed to create handle cache\n");
+4 −2
Original line number Diff line number Diff line
@@ -170,13 +170,15 @@ int __init journal_init_revoke_caches(void)
{
	revoke_record_cache = kmem_cache_create("revoke_record",
					   sizeof(struct jbd_revoke_record_s),
					   0, SLAB_HWCACHE_ALIGN, NULL);
					   0,
					   SLAB_HWCACHE_ALIGN|SLAB_TEMPORARY,
					   NULL);
	if (revoke_record_cache == 0)
		return -ENOMEM;

	revoke_table_cache = kmem_cache_create("revoke_table",
					   sizeof(struct jbd_revoke_table_s),
					   0, 0, NULL);
					   0, SLAB_TEMPORARY, NULL);
	if (revoke_table_cache == 0) {
		kmem_cache_destroy(revoke_record_cache);
		revoke_record_cache = NULL;
+7 −6
Original line number Diff line number Diff line
@@ -492,7 +492,7 @@ static ssize_t proc_info_read(struct file * file, char __user * buf,
		count = PROC_BLOCK_SIZE;

	length = -ENOMEM;
	if (!(page = __get_free_page(GFP_KERNEL)))
	if (!(page = __get_free_page(GFP_TEMPORARY)))
		goto out;

	length = PROC_I(inode)->op.proc_read(task, (char*)page);
@@ -532,7 +532,7 @@ static ssize_t mem_read(struct file * file, char __user * buf,
		goto out;

	ret = -ENOMEM;
	page = (char *)__get_free_page(GFP_USER);
	page = (char *)__get_free_page(GFP_TEMPORARY);
	if (!page)
		goto out;

@@ -602,7 +602,7 @@ static ssize_t mem_write(struct file * file, const char __user *buf,
		goto out;

	copied = -ENOMEM;
	page = (char *)__get_free_page(GFP_USER);
	page = (char *)__get_free_page(GFP_TEMPORARY);
	if (!page)
		goto out;

@@ -788,7 +788,7 @@ static ssize_t proc_loginuid_write(struct file * file, const char __user * buf,
		/* No partial writes. */
		return -EINVAL;
	}
	page = (char*)__get_free_page(GFP_USER);
	page = (char*)__get_free_page(GFP_TEMPORARY);
	if (!page)
		return -ENOMEM;
	length = -EFAULT;
@@ -954,7 +954,8 @@ static int do_proc_readlink(struct dentry *dentry, struct vfsmount *mnt,
			    char __user *buffer, int buflen)
{
	struct inode * inode;
	char *tmp = (char*)__get_free_page(GFP_KERNEL), *path;
	char *tmp = (char*)__get_free_page(GFP_TEMPORARY);
	char *path;
	int len;

	if (!tmp)
@@ -1726,7 +1727,7 @@ static ssize_t proc_pid_attr_write(struct file * file, const char __user * buf,
		goto out;

	length = -ENOMEM;
	page = (char*)__get_free_page(GFP_USER);
	page = (char*)__get_free_page(GFP_TEMPORARY);
	if (!page)
		goto out;

+1 −1
Original line number Diff line number Diff line
@@ -74,7 +74,7 @@ proc_file_read(struct file *file, char __user *buf, size_t nbytes,
		nbytes = MAX_NON_LFS - pos;

	dp = PDE(inode);
	if (!(page = (char*) __get_free_page(GFP_KERNEL)))
	if (!(page = (char*) __get_free_page(GFP_TEMPORARY)))
		return -ENOMEM;

	while ((nbytes > 0) && !eof) {
Loading