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

Commit b20a3503 authored by Christoph Lameter's avatar Christoph Lameter Committed by Linus Torvalds
Browse files

[PATCH] page migration reorg



Centralize the page migration functions in anticipation of additional
tinkering.  Creates a new file mm/migrate.c

1. Extract buffer_migrate_page() from fs/buffer.c

2. Extract central migration code from vmscan.c

3. Extract some components from mempolicy.c

4. Export pageout() and remove_from_swap() from vmscan.c

5. Make it possible to configure NUMA systems without page migration
   and non-NUMA systems with page migration.

I had to so some #ifdeffing in mempolicy.c that may need a cleanup.

Signed-off-by: default avatarChristoph Lameter <clameter@sgi.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 442295c9
Loading
Loading
Loading
Loading
+0 −62
Original line number Diff line number Diff line
@@ -3050,68 +3050,6 @@ asmlinkage long sys_bdflush(int func, long data)
	return 0;
}

/*
 * Migration function for pages with buffers. This function can only be used
 * if the underlying filesystem guarantees that no other references to "page"
 * exist.
 */
#ifdef CONFIG_MIGRATION
int buffer_migrate_page(struct page *newpage, struct page *page)
{
	struct address_space *mapping = page->mapping;
	struct buffer_head *bh, *head;
	int rc;

	if (!mapping)
		return -EAGAIN;

	if (!page_has_buffers(page))
		return migrate_page(newpage, page);

	head = page_buffers(page);

	rc = migrate_page_remove_references(newpage, page, 3);
	if (rc)
		return rc;

	bh = head;
	do {
		get_bh(bh);
		lock_buffer(bh);
		bh = bh->b_this_page;

	} while (bh != head);

	ClearPagePrivate(page);
	set_page_private(newpage, page_private(page));
	set_page_private(page, 0);
	put_page(page);
	get_page(newpage);

	bh = head;
	do {
		set_bh_page(bh, newpage, bh_offset(bh));
		bh = bh->b_this_page;

	} while (bh != head);

	SetPagePrivate(newpage);

	migrate_page_copy(newpage, page);

	bh = head;
	do {
		unlock_buffer(bh);
 		put_bh(bh);
		bh = bh->b_this_page;

	} while (bh != head);

	return 0;
}
EXPORT_SYMBOL(buffer_migrate_page);
#endif

/*
 * Buffer-head allocation
 */
+1 −0
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@
#include <linux/blkdev.h>
#include <linux/hash.h>
#include <linux/kthread.h>
#include <linux/migrate.h>
#include "xfs_linux.h"

STATIC kmem_zone_t *xfs_buf_zone;
+36 −0
Original line number Diff line number Diff line
#ifndef _LINUX_MIGRATE_H
#define _LINUX_MIGRATE_H

#include <linux/config.h>
#include <linux/mm.h>

#ifdef CONFIG_MIGRATION
extern int isolate_lru_page(struct page *p, struct list_head *pagelist);
extern int putback_lru_pages(struct list_head *l);
extern int migrate_page(struct page *, struct page *);
extern void migrate_page_copy(struct page *, struct page *);
extern int migrate_page_remove_references(struct page *, struct page *, int);
extern int migrate_pages(struct list_head *l, struct list_head *t,
		struct list_head *moved, struct list_head *failed);
int migrate_pages_to(struct list_head *pagelist,
			struct vm_area_struct *vma, int dest);
extern int fail_migrate_page(struct page *, struct page *);

extern int migrate_prep(void);

#else

static inline int isolate_lru_page(struct page *p, struct list_head *list)
					{ return -ENOSYS; }
static inline int putback_lru_pages(struct list_head *l) { return 0; }
static inline int migrate_pages(struct list_head *l, struct list_head *t,
	struct list_head *moved, struct list_head *failed) { return -ENOSYS; }

static inline int migrate_prep(void) { return -ENOSYS; }

/* Possible settings for the migrate_page() method in address_operations */
#define migrate_page NULL
#define fail_migrate_page NULL

#endif /* CONFIG_MIGRATION */
#endif /* _LINUX_MIGRATE_H */
+15 −19
Original line number Diff line number Diff line
@@ -175,6 +175,21 @@ extern void swap_setup(void);
extern unsigned long try_to_free_pages(struct zone **, gfp_t);
extern unsigned long shrink_all_memory(unsigned long nr_pages);
extern int vm_swappiness;
extern int remove_mapping(struct address_space *mapping, struct page *page);

/* possible outcome of pageout() */
typedef enum {
	/* failed to write page out, page is locked */
	PAGE_KEEP,
	/* move page to the active list, page is locked */
	PAGE_ACTIVATE,
	/* page has been sent to the disk successfully, page is unlocked */
	PAGE_SUCCESS,
	/* page is clean and locked */
	PAGE_CLEAN,
} pageout_t;

extern pageout_t pageout(struct page *page, struct address_space *mapping);

#ifdef CONFIG_NUMA
extern int zone_reclaim_mode;
@@ -188,25 +203,6 @@ static inline int zone_reclaim(struct zone *z, gfp_t mask, unsigned int order)
}
#endif

#ifdef CONFIG_MIGRATION
extern int isolate_lru_page(struct page *p);
extern unsigned long putback_lru_pages(struct list_head *l);
extern int migrate_page(struct page *, struct page *);
extern void migrate_page_copy(struct page *, struct page *);
extern int migrate_page_remove_references(struct page *, struct page *, int);
extern unsigned long migrate_pages(struct list_head *l, struct list_head *t,
		struct list_head *moved, struct list_head *failed);
extern int fail_migrate_page(struct page *, struct page *);
#else
static inline int isolate_lru_page(struct page *p) { return -ENOSYS; }
static inline int putback_lru_pages(struct list_head *l) { return 0; }
static inline int migrate_pages(struct list_head *l, struct list_head *t,
	struct list_head *moved, struct list_head *failed) { return -ENOSYS; }
/* Possible settings for the migrate_page() method in address_operations */
#define migrate_page NULL
#define fail_migrate_page NULL
#endif

#ifdef CONFIG_MMU
/* linux/mm/shmem.c */
extern int shmem_unuse(swp_entry_t entry, struct page *page);
+6 −0
Original line number Diff line number Diff line
@@ -137,5 +137,11 @@ config SPLIT_PTLOCK_CPUS
# support for page migration
#
config MIGRATION
	bool "Page migration"
	def_bool y if NUMA || SPARSEMEM || DISCONTIGMEM
	depends on SWAP
	help
	  Allows the migration of the physical location of pages of processes
	  while the virtual addresses are not changed. This is useful for
	  example on NUMA systems to put pages nearer to the processors accessing
	  the page.
Loading