* [RFC 5/6] Swapless V1: Rip out swap migration code
From: Christoph Lameter @ 2006-04-04 6:58 UTC (permalink / raw)
To: linux-mm
Cc: Lee Schermerhorn, Christoph Lameter, lhms-devel,
Hirokazu Takahashi, Marcelo Tosatti, KAMEZAWA Hiroyuki
In-Reply-To: <20060404065739.24532.95451.sendpatchset@schroedinger.engr.sgi.com>
Rip the page migration logic out
Remove all code that has to do with swapping during page migration.
This also guts the ability to migrate pages to swap. No one used that
so lets let it go for good.
Page migration should be a bit broken after this patch.
Signed-off-by: Christoph Lameter <clameter@sgi.com>
Index: linux-2.6.17-rc1/mm/migrate.c
===================================================================
--- linux-2.6.17-rc1.orig/mm/migrate.c 2006-04-03 22:07:40.000000000 -0700
+++ linux-2.6.17-rc1/mm/migrate.c 2006-04-03 22:07:56.000000000 -0700
@@ -70,10 +70,6 @@ int isolate_lru_page(struct page *page,
*/
int migrate_prep(void)
{
- /* Must have swap device for migration */
- if (nr_swap_pages <= 0)
- return -ENODEV;
-
/*
* Clear the LRU lists so pages can be isolated.
* Note that pages may be moved off the LRU after we have
@@ -129,53 +125,6 @@ int fail_migrate_page(struct page *newpa
EXPORT_SYMBOL(fail_migrate_page);
/*
- * swapout a single page
- * page is locked upon entry, unlocked on exit
- */
-static int swap_page(struct page *page)
-{
- struct address_space *mapping = page_mapping(page);
-
- if (page_mapped(page) && mapping)
- if (try_to_unmap(page, 1) != SWAP_SUCCESS)
- goto unlock_retry;
-
- if (PageDirty(page)) {
- /* Page is dirty, try to write it out here */
- switch(pageout(page, mapping)) {
- case PAGE_KEEP:
- case PAGE_ACTIVATE:
- goto unlock_retry;
-
- case PAGE_SUCCESS:
- goto retry;
-
- case PAGE_CLEAN:
- ; /* try to free the page below */
- }
- }
-
- if (PagePrivate(page)) {
- if (!try_to_release_page(page, GFP_KERNEL) ||
- (!mapping && page_count(page) == 1))
- goto unlock_retry;
- }
-
- if (remove_mapping(mapping, page)) {
- /* Success */
- unlock_page(page);
- return 0;
- }
-
-unlock_retry:
- unlock_page(page);
-
-retry:
- return -EAGAIN;
-}
-EXPORT_SYMBOL(swap_page);
-
-/*
* Remove references for a page and establish the new page with the correct
* basic settings to be able to stop accesses to the page.
*/
@@ -336,8 +285,7 @@ EXPORT_SYMBOL(migrate_page);
* Two lists are passed to this function. The first list
* contains the pages isolated from the LRU to be migrated.
* The second list contains new pages that the pages isolated
- * can be moved to. If the second list is NULL then all
- * pages are swapped out.
+ * can be moved to.
*
* The function returns after 10 attempts or if no pages
* are movable anymore because to has become empty
@@ -393,30 +341,13 @@ redo:
* Only wait on writeback if we have already done a pass where
* we we may have triggered writeouts for lots of pages.
*/
- if (pass > 0) {
+ if (pass > 0)
wait_on_page_writeback(page);
- } else {
+ else {
if (PageWriteback(page))
goto unlock_page;
}
- /*
- * Anonymous pages must have swap cache references otherwise
- * the information contained in the page maps cannot be
- * preserved.
- */
- if (PageAnon(page) && !PageSwapCache(page)) {
- if (!add_to_swap(page, GFP_KERNEL)) {
- rc = -ENOMEM;
- goto unlock_page;
- }
- }
-
- if (!to) {
- rc = swap_page(page);
- goto next;
- }
-
newpage = lru_to_page(to);
lock_page(newpage);
@@ -470,24 +401,6 @@ redo:
goto unlock_both;
}
- /*
- * On early passes with mapped pages simply
- * retry. There may be a lock held for some
- * buffers that may go away. Later
- * swap them out.
- */
- if (pass > 4) {
- /*
- * Persistently unable to drop buffers..... As a
- * measure of last resort we fall back to
- * swap_page().
- */
- unlock_page(newpage);
- newpage = NULL;
- rc = swap_page(page);
- goto next;
- }
-
unlock_both:
unlock_page(newpage);
Index: linux-2.6.17-rc1/mm/swapfile.c
===================================================================
--- linux-2.6.17-rc1.orig/mm/swapfile.c 2006-04-03 22:07:46.000000000 -0700
+++ linux-2.6.17-rc1/mm/swapfile.c 2006-04-03 22:07:56.000000000 -0700
@@ -618,15 +618,6 @@ static int unuse_mm(struct mm_struct *mm
return 0;
}
-#ifdef CONFIG_MIGRATION
-int remove_vma_swap(struct vm_area_struct *vma, struct page *page)
-{
- swp_entry_t entry = { .val = page_private(page) };
-
- return unuse_vma(vma, entry, page);
-}
-#endif
-
/*
* Scan swap_map from current position to next entry still in use.
* Recycle to start on reaching the end, returning 0 when empty.
Index: linux-2.6.17-rc1/mm/rmap.c
===================================================================
--- linux-2.6.17-rc1.orig/mm/rmap.c 2006-04-03 22:07:55.000000000 -0700
+++ linux-2.6.17-rc1/mm/rmap.c 2006-04-03 22:07:56.000000000 -0700
@@ -205,44 +205,6 @@ out:
return anon_vma;
}
-#ifdef CONFIG_MIGRATION
-/*
- * Remove an anonymous page from swap replacing the swap pte's
- * through real pte's pointing to valid pages and then releasing
- * the page from the swap cache.
- *
- * Must hold page lock on page and mmap_sem of one vma that contains
- * the page.
- */
-void remove_from_swap(struct page *page)
-{
- struct anon_vma *anon_vma;
- struct vm_area_struct *vma;
- unsigned long mapping;
-
- if (!PageSwapCache(page))
- return;
-
- mapping = (unsigned long)page->mapping;
-
- if (!mapping || (mapping & PAGE_MAPPING_ANON) == 0)
- return;
-
- /*
- * We hold the mmap_sem lock. So no need to call page_lock_anon_vma.
- */
- anon_vma = (struct anon_vma *) (mapping - PAGE_MAPPING_ANON);
- spin_lock(&anon_vma->lock);
-
- list_for_each_entry(vma, &anon_vma->head, anon_vma_node)
- remove_vma_swap(vma, page);
-
- spin_unlock(&anon_vma->lock);
- delete_from_swap_cache(page);
-}
-EXPORT_SYMBOL(remove_from_swap);
-#endif
-
/*
* At what user virtual address is page expected in vma?
*/
Index: linux-2.6.17-rc1/include/linux/rmap.h
===================================================================
--- linux-2.6.17-rc1.orig/include/linux/rmap.h 2006-04-03 22:07:55.000000000 -0700
+++ linux-2.6.17-rc1/include/linux/rmap.h 2006-04-03 22:07:56.000000000 -0700
@@ -92,7 +92,6 @@ static inline void page_dup_rmap(struct
*/
int page_referenced(struct page *, int is_locked);
int try_to_unmap(struct page *, int ignore_refs);
-void remove_from_swap(struct page *page);
/*
* Called from mm/filemap_xip.c to unmap empty zero page
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
* [RFC 4/6] Swapless V1: remove migration ptes
From: Christoph Lameter @ 2006-04-04 6:58 UTC (permalink / raw)
To: linux-mm
Cc: Lee Schermerhorn, Christoph Lameter, lhms-devel,
Hirokazu Takahashi, Marcelo Tosatti, KAMEZAWA Hiroyuki
In-Reply-To: <20060404065739.24532.95451.sendpatchset@schroedinger.engr.sgi.com>
Add ability to remove migration ptes.
1. Modify page_check_address to support matching on ptes with
SWP_TYPE_MIGRATION
2. Add functions to scan the anon vma and replace SWAP_TYPE_MIGRATION
ptes with regular ones.
Signed-off-by: Christoph Lameter <clameter@sgi.com>
Index: linux-2.6.17-rc1/mm/rmap.c
===================================================================
--- linux-2.6.17-rc1.orig/mm/rmap.c 2006-04-03 22:50:00.000000000 -0700
+++ linux-2.6.17-rc1/mm/rmap.c 2006-04-03 22:57:08.000000000 -0700
@@ -291,7 +291,7 @@ pte_t *page_check_address(struct page *p
pgd_t *pgd;
pud_t *pud;
pmd_t *pmd;
- pte_t *pte;
+ pte_t *ptep, pte;
spinlock_t *ptl;
pgd = pgd_offset(mm, address);
@@ -306,23 +306,84 @@ pte_t *page_check_address(struct page *p
if (!pmd_present(*pmd))
return NULL;
- pte = pte_offset_map(pmd, address);
+ ptep = pte_offset_map(pmd, address);
+ pte = *ptep;
/* Make a quick check before getting the lock */
- if (!pte_present(*pte)) {
- pte_unmap(pte);
+ if (pte_none(pte) || pte_file(pte)) {
+ pte_unmap(ptep);
return NULL;
}
ptl = pte_lockptr(mm, pmd);
spin_lock(ptl);
- if (pte_present(*pte) && page_to_pfn(page) == pte_pfn(*pte)) {
- *ptlp = ptl;
- return pte;
+ if (pte_present(pte)) {
+ if (page_to_pfn(page) == pte_pfn(pte)) {
+ *ptlp = ptl;
+ return ptep;
+ }
+ } else {
+ /* Could still be a migration entry pointing to the page */
+ swp_entry_t entry = pte_to_swp_entry(pte);
+
+ if (swp_type(entry) == SWP_TYPE_MIGRATION &&
+ swp_offset(entry) == page_to_pfn(page)) {
+ *ptlp = ptl;
+ return ptep;
+ }
}
pte_unmap_unlock(pte, ptl);
return NULL;
}
+#ifdef CONFIG_MIGRATION
+/*
+ * Restore a potential migration pte to a working pte entry for
+ * anonymous pages.
+ */
+static void remove_migration_pte(struct vm_area_struct *vma, unsigned long addr,
+ struct page *old, struct page *new)
+{
+ struct mm_struct *mm = vma->vm_mm;
+ pte_t *ptep;
+ spinlock_t *ptl;
+
+ ptep = page_check_address(old, mm, addr, &ptl);
+ if (!ptep)
+ return;
+
+ get_page(new);
+ set_pte_at(mm, addr, ptep, pte_mkold(mk_pte(new, vma->vm_page_prot)));
+ page_add_anon_rmap(new, vma, addr);
+
+ spin_unlock(ptl);
+}
+
+/*
+ * Get rid of all migration entries and replace them by
+ * references to the indicated page.
+ *
+ * Must hold mmap_sem lock on at least one of the vmas containing
+ * the page so that the anon_vma cannot vanish.
+ */
+void remove_migration_ptes(struct page *page, struct page *newpage)
+{
+ struct anon_vma *anon_vma;
+ struct vm_area_struct *vma;
+
+ if (!PageAnon(newpage))
+ return;
+
+ anon_vma = page_lock_anon_vma(newpage);
+ BUG_ON(!anon_vma);
+
+ list_for_each_entry(vma, &anon_vma->head, anon_vma_node)
+ remove_migration_pte(vma, page_address_in_vma(newpage, vma),
+ page, newpage);
+
+ spin_unlock(&anon_vma->lock);
+}
+#endif
+
/*
* Subfunctions of page_referenced: page_referenced_one called
* repeatedly from either page_referenced_anon or page_referenced_file.
Index: linux-2.6.17-rc1/include/linux/rmap.h
===================================================================
--- linux-2.6.17-rc1.orig/include/linux/rmap.h 2006-04-02 20:22:10.000000000 -0700
+++ linux-2.6.17-rc1/include/linux/rmap.h 2006-04-03 22:57:08.000000000 -0700
@@ -105,6 +105,11 @@ pte_t *page_check_address(struct page *,
*/
unsigned long page_address_in_vma(struct page *, struct vm_area_struct *);
+/*
+ * Used by page migration to restore ptes of anonymous pages
+ */
+void remove_migration_ptes(struct page *page, struct page *newpage);
+
#else /* !CONFIG_MMU */
#define anon_vma_init() do {} while (0)
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
* [RFC 3/6] Swapless V1: try_to_unmap() - Create migration entries
From: Christoph Lameter @ 2006-04-04 6:57 UTC (permalink / raw)
To: linux-mm
Cc: Lee Schermerhorn, Christoph Lameter, lhms-devel,
Hirokazu Takahashi, Marcelo Tosatti, KAMEZAWA Hiroyuki
In-Reply-To: <20060404065739.24532.95451.sendpatchset@schroedinger.engr.sgi.com>
Modify try_to_unmap to produce swap migration entries
If we are trying to unmap an entry and do not have an associated
swapcache entry but are doing migration then create a special
swap pte of type SWP_TYPE_MIGRATION pointing to the pfn.
Signed-off-by: Christoph Lameter <clameter@sgi.com>
Index: linux-2.6.17-rc1/mm/rmap.c
===================================================================
--- linux-2.6.17-rc1.orig/mm/rmap.c 2006-04-03 22:33:56.000000000 -0700
+++ linux-2.6.17-rc1/mm/rmap.c 2006-04-03 22:50:00.000000000 -0700
@@ -620,6 +620,17 @@ static int try_to_unmap_one(struct page
if (PageAnon(page)) {
swp_entry_t entry = { .val = page_private(page) };
+
+ if (!PageSwapCache(page) && migration) {
+ /*
+ * Store the pfn of the page in a special migration
+ * pte. do_swap_page() will wait until the page is unlocked
+ * and then restart the fault handling.
+ */
+ entry = swp_entry(SWP_TYPE_MIGRATION, page_to_pfn(page));
+ set_pte_at(mm, address, pte, swp_entry_to_pte(entry));
+ goto finish;
+ }
/*
* Store the swap location in the pte.
* See handle_pte_fault() ...
@@ -638,6 +649,7 @@ static int try_to_unmap_one(struct page
} else
dec_mm_counter(mm, file_rss);
+finish:
page_remove_rmap(page);
page_cache_release(page);
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
* [RFC 2/6] Swapless V1: Add SWP_TYPE_MIGRATION
From: Christoph Lameter @ 2006-04-04 6:57 UTC (permalink / raw)
To: linux-mm
Cc: Lee Schermerhorn, Christoph Lameter, lhms-devel,
Hirokazu Takahashi, Marcelo Tosatti, KAMEZAWA Hiroyuki
In-Reply-To: <20060404065739.24532.95451.sendpatchset@schroedinger.engr.sgi.com>
Add migration swap type
SWP_TYPE_MIGRATION is a special swap type that encodes the pfn of the
page in the swp_offset.
Note that the swp_offset size is limited. This is 27 bits on 32 bit and
54 bits on IA64. pfn numbers must fit into that size of a field for
this scheme to work. Could that be a problem?
SWP_TYPE_MIGRATION is only set for a pte while the corresponding page
is locked. It is removed while the page is still locked. Therefore the
processing for this special type of swap page can be simple.
The freeing of this type of entry is simply ignored.
lookup_swap_cache() determines the page from the pfn and only takes a
reference on the page.
Signed-off-by: Christoph Lameter <clameter@sgi.com>
Index: linux-2.6.17-rc1/mm/swap_state.c
===================================================================
--- linux-2.6.17-rc1.orig/mm/swap_state.c 2006-04-02 20:22:10.000000000 -0700
+++ linux-2.6.17-rc1/mm/swap_state.c 2006-04-03 23:26:21.000000000 -0700
@@ -10,6 +10,7 @@
#include <linux/mm.h>
#include <linux/kernel_stat.h>
#include <linux/swap.h>
+#include <linux/swapops.h>
#include <linux/init.h>
#include <linux/pagemap.h>
#include <linux/buffer_head.h>
@@ -299,6 +300,16 @@ struct page * lookup_swap_cache(swp_entr
{
struct page *page;
+ /*
+ * If the swap type is SWP_TYPE_MIGRATION then the
+ * swap entry contains the pfn of a page.
+ */
+ if (unlikely(swp_type(entry) == SWP_TYPE_MIGRATION)) {
+ page = pfn_to_page(swp_offset(entry));
+ get_page(page);
+ return page;
+ }
+
page = find_get_page(&swapper_space, entry.val);
if (page)
Index: linux-2.6.17-rc1/mm/swapfile.c
===================================================================
--- linux-2.6.17-rc1.orig/mm/swapfile.c 2006-04-02 20:22:10.000000000 -0700
+++ linux-2.6.17-rc1/mm/swapfile.c 2006-04-03 23:26:21.000000000 -0700
@@ -395,6 +395,9 @@ void free_swap_and_cache(swp_entry_t ent
struct swap_info_struct * p;
struct page *page = NULL;
+ if (swp_type(entry) == SWP_TYPE_MIGRATION)
+ return;
+
p = swap_info_get(entry);
if (p) {
if (swap_entry_free(p, swp_offset(entry)) == 1) {
@@ -1710,6 +1713,9 @@ int swap_duplicate(swp_entry_t entry)
int result = 0;
type = swp_type(entry);
+ if (type == SWP_TYPE_MIGRATION)
+ return 1;
+
if (type >= nr_swapfiles)
goto bad_file;
p = type + swap_info;
Index: linux-2.6.17-rc1/include/linux/swap.h
===================================================================
--- linux-2.6.17-rc1.orig/include/linux/swap.h 2006-04-02 20:22:10.000000000 -0700
+++ linux-2.6.17-rc1/include/linux/swap.h 2006-04-03 23:43:03.000000000 -0700
@@ -29,7 +29,10 @@ static inline int current_is_kswapd(void
* the type/offset into the pte as 5/27 as well.
*/
#define MAX_SWAPFILES_SHIFT 5
-#define MAX_SWAPFILES (1 << MAX_SWAPFILES_SHIFT)
+#define MAX_SWAPFILES ((1 << MAX_SWAPFILES_SHIFT)-1)
+
+/* Use last entry for page migration swap entries */
+#define SWP_TYPE_MIGRATION MAX_SWAPFILES
/*
* Magic header for a swap area. The first part of the union is
@@ -293,7 +296,6 @@ static inline void disable_swap_token(vo
#define swap_duplicate(swp) /*NOTHING*/
#define swap_free(swp) /*NOTHING*/
#define read_swap_cache_async(swp,vma,addr) NULL
-#define lookup_swap_cache(swp) NULL
#define valid_swaphandles(swp, off) 0
#define can_share_swap_page(p) 0
#define move_to_swap_cache(p, swp) 1
@@ -302,6 +304,12 @@ static inline void disable_swap_token(vo
#define delete_from_swap_cache(p) /*NOTHING*/
#define swap_token_default_timeout 0
+#ifdef CONFIG_MIGRATION
+extern struct page* lookup_swap_cache(swp_entry_t);
+#else
+#define lookup_swap_cache(swp) NULL
+#endif
+
static inline int remove_exclusive_swap_page(struct page *p)
{
return 0;
Index: linux-2.6.17-rc1/mm/migrate.c
===================================================================
--- linux-2.6.17-rc1.orig/mm/migrate.c 2006-04-03 22:07:40.000000000 -0700
+++ linux-2.6.17-rc1/mm/migrate.c 2006-04-03 23:44:10.000000000 -0700
@@ -32,6 +32,18 @@
#define lru_to_page(_head) (list_entry((_head)->prev, struct page, lru))
+#ifndef CONFIG_SWAP
+struct page *lookup_swap_cache(swp_entry_t entry)
+{
+ if (unlikely(swp_type(entry) == SWP_TYPE_MIGRATION)) {
+ struct page *page = pfn_to_page(swp_offset(entry));
+ get_page(page);
+ return page;
+ }
+ return NULL;
+}
+#endif
+
/*
* Isolate one page from the LRU lists. If successful put it onto
* the indicated list with elevated page count.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
* [RFC 1/6] Swapless V1: try_to_unmap() - Rename ignrefs to "migration"
From: Christoph Lameter @ 2006-04-04 6:57 UTC (permalink / raw)
To: linux-mm
Cc: Lee Schermerhorn, Christoph Lameter, lhms-devel,
Hirokazu Takahashi, Marcelo Tosatti, KAMEZAWA Hiroyuki
In-Reply-To: <20060404065739.24532.95451.sendpatchset@schroedinger.engr.sgi.com>
migrate is a better name since we implement special handling for
page migration later.
Signed-off-by: Christoph Lameter <clameter@sgi.com>
Index: linux-2.6.17-rc1/mm/rmap.c
===================================================================
--- linux-2.6.17-rc1.orig/mm/rmap.c 2006-04-02 20:22:10.000000000 -0700
+++ linux-2.6.17-rc1/mm/rmap.c 2006-04-03 22:33:56.000000000 -0700
@@ -578,7 +578,7 @@ void page_remove_rmap(struct page *page)
* repeatedly from either try_to_unmap_anon or try_to_unmap_file.
*/
static int try_to_unmap_one(struct page *page, struct vm_area_struct *vma,
- int ignore_refs)
+ int migration)
{
struct mm_struct *mm = vma->vm_mm;
unsigned long address;
@@ -602,7 +602,7 @@ static int try_to_unmap_one(struct page
*/
if ((vma->vm_flags & VM_LOCKED) ||
(ptep_clear_flush_young(vma, address, pte)
- && !ignore_refs)) {
+ && !migration)) {
ret = SWAP_FAIL;
goto out_unmap;
}
@@ -736,7 +736,7 @@ static void try_to_unmap_cluster(unsigne
pte_unmap_unlock(pte - 1, ptl);
}
-static int try_to_unmap_anon(struct page *page, int ignore_refs)
+static int try_to_unmap_anon(struct page *page, int migration)
{
struct anon_vma *anon_vma;
struct vm_area_struct *vma;
@@ -747,7 +747,7 @@ static int try_to_unmap_anon(struct page
return ret;
list_for_each_entry(vma, &anon_vma->head, anon_vma_node) {
- ret = try_to_unmap_one(page, vma, ignore_refs);
+ ret = try_to_unmap_one(page, vma, migration);
if (ret == SWAP_FAIL || !page_mapped(page))
break;
}
@@ -764,7 +764,7 @@ static int try_to_unmap_anon(struct page
*
* This function is only called from try_to_unmap for object-based pages.
*/
-static int try_to_unmap_file(struct page *page, int ignore_refs)
+static int try_to_unmap_file(struct page *page, int migration)
{
struct address_space *mapping = page->mapping;
pgoff_t pgoff = page->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT);
@@ -778,7 +778,7 @@ static int try_to_unmap_file(struct page
spin_lock(&mapping->i_mmap_lock);
vma_prio_tree_foreach(vma, &iter, &mapping->i_mmap, pgoff, pgoff) {
- ret = try_to_unmap_one(page, vma, ignore_refs);
+ ret = try_to_unmap_one(page, vma, migration);
if (ret == SWAP_FAIL || !page_mapped(page))
goto out;
}
@@ -863,16 +863,16 @@ out:
* SWAP_AGAIN - we missed a mapping, try again later
* SWAP_FAIL - the page is unswappable
*/
-int try_to_unmap(struct page *page, int ignore_refs)
+int try_to_unmap(struct page *page, int migration)
{
int ret;
BUG_ON(!PageLocked(page));
if (PageAnon(page))
- ret = try_to_unmap_anon(page, ignore_refs);
+ ret = try_to_unmap_anon(page, migration);
else
- ret = try_to_unmap_file(page, ignore_refs);
+ ret = try_to_unmap_file(page, migration);
if (!page_mapped(page))
ret = SWAP_SUCCESS;
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
* [RFC 0/6] Swapless Page Migration V1: Overview
From: Christoph Lameter @ 2006-04-04 6:57 UTC (permalink / raw)
To: linux-mm
Cc: Lee Schermerhorn, Christoph Lameter, lhms-devel,
Hirokazu Takahashi, Marcelo Tosatti, KAMEZAWA Hiroyuki
Swapless Page migration
Currently page migration is depending on the ability to assign swap entries
to pages. This means that page migration will not work without swap although
that swap space is never used.
This patchset removes that dependency by introducing a special type of
swap entry that encodes a pfn number of the page being migrated. If that
swap pte is encountered then do_swap_page() will simply wait for the page
to become unlocked again (meaning page migration is complete) and then refetch
the pte. The special type of swap entry is only in use while the page to be
migrated is locked and therefore we can hopefully get away with just a few
supporting functions.
To some extend this covers the same ground as Lee's and Marcelo's migration
cache. However, I hope that this approach simplifies things without opening
up any holes. Please check.
The patchset is also a prerequisite for later patches that enable
migration of VM_LOCKED vmas and add the ability to exempt vmas from
page migration.
The patchset consists of six patches:
1. try_to_unmap(): Rename ignrefs to "migration"
We will be using that try_to_unmap flag in the next patch to
mean that page migration has called try_to_unmap().
2. Add SWP_TYPE_MIGRATION
Add the SWP_TYPE_MIGRATION and a few necessary handlers for this
type of entry.
3. try_to_unmap(): Create migration entries if migration calls
try_to_unmap for pages without PageSwapCache() set.
4. Remove migration ptes
This is a similar logic to remove_from_swap(). We walk through
the reverse maps and replace all SWP_TYPE_MIGRATION entries with
the correct pte. Since we only do that to SWP_TYPE_MIGRATION entries
we can simplify the function.
5. Rip out old swap migration code
Remove all the old swap based code. Note that this also removes the fallback
to swap if all other attempts to migrate fail and also the ability to
migrate to swap (which was never used)
6. Revise main migration code
Revise the migration logic to use the new SWP_TYPE_MIGRATION. This means
that anonymous pages without a mapping may be migrated. Therefore we have
to deal with page counts differently.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
* Page Migration: Make do_swap_page redo the fault
From: Christoph Lameter @ 2006-04-04 5:33 UTC (permalink / raw)
To: akpm; +Cc: linux-mm
It is better to redo the complete fault if do_swap_page() finds
that the page is not in PageSwapCache() because the page migration
code may have replaced the swap pte already with a pte pointing
to valid memory.
do_swap_page may interpret an invalid swap entry without this patch
because we do not reload the pte if we are looping back. The page
migration code may already have reused the swap entry referenced by our
local swp_entry.
Signed-off-by: Christoph Lameter <clameter@sgi.com>
Index: linux-2.6.17-rc1/mm/memory.c
===================================================================
--- linux-2.6.17-rc1.orig/mm/memory.c 2006-04-02 20:22:10.000000000 -0700
+++ linux-2.6.17-rc1/mm/memory.c 2006-04-03 22:22:56.000000000 -0700
@@ -1879,7 +1879,6 @@ static int do_swap_page(struct mm_struct
goto out;
entry = pte_to_swp_entry(orig_pte);
-again:
page = lookup_swap_cache(entry);
if (!page) {
swapin_readahead(entry, address, vma);
@@ -1907,7 +1906,7 @@ again:
/* Page migration has occured */
unlock_page(page);
page_cache_release(page);
- goto again;
+ goto out;
}
/*
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
* Re: Avoid excessive time spend on concurrent slab shrinking
From: Christoph Lameter @ 2006-04-01 18:49 UTC (permalink / raw)
To: David Chinner; +Cc: Nathan Scott, Andrew Morton, nickpiggin, linux-mm, dgc
In-Reply-To: <20060401183038.GY27189130@melbourne.sgi.com>
On Sun, 2 Apr 2006, David Chinner wrote:
> same hash chain, which tends to implicate not enough hash buckets.
>
> > If its useful for experimenting, Christoph, you can easily tweak the
> > cluster hash size manually by dinking with xfs_iget.c::xfs_chash_init.
>
> Just use the ihashsize mount option - the cluster hash size is proportional
> to the inode hash size which is changed by the ihashsize mount option.
>
> Cheers,
XFS settings visible via /proc/mounts are
rw,ihashsize=32768,sunit=32,swidth=25
Not enough hash buckets? This was the default selection by xfs.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
* Re: Avoid excessive time spend on concurrent slab shrinking
From: David Chinner @ 2006-04-01 18:30 UTC (permalink / raw)
To: Nathan Scott; +Cc: Andrew Morton, Christoph Lameter, nickpiggin, linux-mm, dgc
In-Reply-To: <20060401155942.E961681@wobbly.melbourne.sgi.com>
On Sat, Apr 01, 2006 at 03:59:42PM +1000, Nathan Scott wrote:
> On Fri, Mar 31, 2006 at 05:25:18PM -0800, Andrew Morton wrote:
> > Christoph Lameter <clameter@sgi.com> wrote:
> > ...
> > It appears that we're being busy in xfs_iextract(), but it would be sad if
> > the problem was really lock contention in xfs_iextract(), and we just
> > happened to catch it when it was running.
> >
> > Or maybe xfs_iextract is just slow. So this is one thing we need to get to
> > the bottom of (profiles might tell us).
>
> I assume (profiles would be good to prove it) we are spending
> time walking the hash bucket list there Christoph (while we're
> holding the ch_lock spinlock on the hash bucket)? [CC'ing Dave
> Chinner for any further comment, he's been looking at the chash
> list for unrelated reasons recently..]
You'll only get contention if something else is trying to walk the
same hash chain, which tends to implicate not enough hash buckets.
> If its useful for experimenting, Christoph, you can easily tweak the
> cluster hash size manually by dinking with xfs_iget.c::xfs_chash_init.
Just use the ihashsize mount option - the cluster hash size is proportional
to the inode hash size which is changed by the ihashsize mount option.
Cheers,
Dave.
--
Dave Chinner
R&D Software Enginner
SGI Australian Software Group
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
* Re: Avoid excessive time spend on concurrent slab shrinking
From: David Chinner @ 2006-04-01 18:24 UTC (permalink / raw)
To: Christoph Lameter; +Cc: Andrew Morton, nickpiggin, linux-mm
In-Reply-To: <Pine.LNX.4.64.0603311619590.9173@schroedinger.engr.sgi.com>
On Fri, Mar 31, 2006 at 04:22:29PM -0800, Christoph Lameter wrote:
> Some traces:
>
> Stack traceback for pid 16836
> 0xe00000380bc68000 16836 1 1 6 R
> 0xa00000020b8e6050 [xfs]xfs_iextract+0x190
> 0xa00000020b8e63a0 [xfs]xfs_ireclaim+0x80
> 0xa00000020b921c70 [xfs]xfs_finish_reclaim+0x330
> 0xa00000020b921fa0 [xfs]xfs_reclaim+0x140
> 0xa00000020b93f820 [xfs]linvfs_clear_inode+0x260
Christoph, what machine, what XFS mount options? Did the latest upgrade
lose the "ihashsize=xxxxx" mount option that used to be set on all
the large filesystems?
Cheers,
Dave.
--
Dave Chinner
R&D Software Enginner
SGI Australian Software Group
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
* Re: Avoid excessive time spend on concurrent slab shrinking
From: Nathan Scott @ 2006-04-01 5:59 UTC (permalink / raw)
To: Andrew Morton; +Cc: Christoph Lameter, nickpiggin, linux-mm, dgc
In-Reply-To: <20060331172518.40a5b03d.akpm@osdl.org>
On Fri, Mar 31, 2006 at 05:25:18PM -0800, Andrew Morton wrote:
> Christoph Lameter <clameter@sgi.com> wrote:
> ...
> It appears that we're being busy in xfs_iextract(), but it would be sad if
> the problem was really lock contention in xfs_iextract(), and we just
> happened to catch it when it was running.
>
> Or maybe xfs_iextract is just slow. So this is one thing we need to get to
> the bottom of (profiles might tell us).
I assume (profiles would be good to prove it) we are spending
time walking the hash bucket list there Christoph (while we're
holding the ch_lock spinlock on the hash bucket)? [CC'ing Dave
Chinner for any further comment, he's been looking at the chash
list for unrelated reasons recently..]
> Assuming that there's nothing we can do to improve the XFS situation, our
> options appear to be, in order of preference:
>
> a) move some/all of dispose_list() outside iprune_mutex.
>
> b) make iprune_mutex an rwlock, take it for reading around
> dispose_list(), for writing elsewhere.
>
> c) go back to single-threading shrink_slab (or just shrink_icache_memory())
>
> For this one we'd need to understand which observations prompted Nick
> to make shrinker_rwsem an rwsem?
>
> We also need to understand why this has become worse. Perhaps xfs_iextract
> got slower (cc's Nathan). Do you have any idea whenabout in kernel history
> this started happening?
Nothings changed in xfs_iextract for many years. Its quite possible
the simple hash with linked list buckets is no longer an effective
choice of algorithm here for the inode cluster hash... or perhaps the
hash table is too small... or... but anyway, I would not expect any
difference between kernel versions here (esp. the two vendor kernel
versions Christoph will be comparing - they'll be behaving exactly
the same way in this regard from XFS's POV as the code in question is
identical).
Its also quite possible some other performance bottleneck was moved
out of the way, and lock contention on the chashlist lock is now the
next biggest thing in line..
If its useful for experimenting, Christoph, you can easily tweak the
cluster hash size manually by dinking with xfs_iget.c::xfs_chash_init.
cheers.
--
Nathan
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
* Re: Avoid excessive time spend on concurrent slab shrinking
From: Nick Piggin @ 2006-04-01 2:34 UTC (permalink / raw)
To: Andrew Morton; +Cc: Christoph Lameter, linux-mm, Nathan Scott
In-Reply-To: <20060331172518.40a5b03d.akpm@osdl.org>
Andrew Morton wrote:
> c) go back to single-threading shrink_slab (or just shrink_icache_memory())
>
> For this one we'd need to understand which observations prompted Nick
> to make shrinker_rwsem an rwsem?
>
This was when I was looking for reasons why inode and dentry caches
would sometimes apparently explode on people and consume most of their
memory. One of the reasons was here, when slab caches did build up, and
multiple processes would start reclaim, scanning would skew away from
slab.
Considering the actual slab shrinkers are single threaded, I agree this
could cause more semaphore contention.
One thing we could do is ensure shrinker->nr gets incremented, but not
actually have more than one thread enter slab reclaim at once.
Or have the trylock&abort behaviour pushed down into the actual
shrinkers themselves, then at least we can get concurrent icache and
dcache scanning happening.
--
SUSE Labs, Novell Inc.
Send instant messages to your online friends http://au.messenger.yahoo.com
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
* Re: Avoid excessive time spend on concurrent slab shrinking
From: Andrew Morton @ 2006-04-01 1:25 UTC (permalink / raw)
To: Christoph Lameter; +Cc: nickpiggin, linux-mm, Nathan Scott
In-Reply-To: <Pine.LNX.4.64.0603311619590.9173@schroedinger.engr.sgi.com>
Christoph Lameter <clameter@sgi.com> wrote:
>
> Some traces:
>
> Stack traceback for pid 16836
> 0xe00000380bc68000 16836 1 1 6 R
> 0xa00000020b8e6050 [xfs]xfs_iextract+0x190
> 0xa00000020b8e63a0 [xfs]xfs_ireclaim+0x80
> 0xa00000020b921c70 [xfs]xfs_finish_reclaim+0x330
> 0xa00000020b921fa0 [xfs]xfs_reclaim+0x140
> 0xa00000020b93f820 [xfs]linvfs_clear_inode+0x260
> 0xa0000001001855f0 clear_inode+0x310
> 0xa000000100185f70 dispose_list+0x90
> 0xa000000100186c40 shrink_icache_memory+0x480
> 0xa000000100105bb0 shrink_slab+0x290
> 0xa000000100107cc0 try_to_free_pages+0x380
> 0xa0000001000f9f70 __alloc_pages+0x330
> 0xa0000001000ed940 page_cache_alloc_cold+0x160
> 0xa0000001000fe3a0 __do_page_cache_readahead+0x120
> 0xa0000001000fe820 blockable_page_cache_readahead+0xe0
> 0xa0000001000fea50 make_ahead_window+0x150
> 0xa0000001000fee30 page_cache_readahead+0x390
> 0xa0000001000ee730 do_generic_mapping_read+0x190
> 0xa0000001000efd80 __generic_file_aio_read+0x2c0
> 0xa00000020b93c190 [xfs]xfs_read+0x3b0
> 0xa00000020b934170 [xfs]linvfs_aio_read+0x130
OK, thanks. Is that a typical trace?
It appears that we're being busy in xfs_iextract(), but it would be sad if
the problem was really lock contention in xfs_iextract(), and we just
happened to catch it when it was running.
Or maybe xfs_iextract is just slow. So this is one thing we need to get to
the bottom of (profiles might tell us).
Assuming that there's nothing we can do to improve the XFS situation, our
options appear to be, in order of preference:
a) move some/all of dispose_list() outside iprune_mutex.
b) make iprune_mutex an rwlock, take it for reading around
dispose_list(), for writing elsewhere.
c) go back to single-threading shrink_slab (or just shrink_icache_memory())
For this one we'd need to understand which observations prompted Nick
to make shrinker_rwsem an rwsem?
We also need to understand why this has become worse. Perhaps xfs_iextract
got slower (cc's Nathan). Do you have any idea whenabout in kernel history
this started happening?
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
* Re: Avoid excessive time spend on concurrent slab shrinking
From: Christoph Lameter @ 2006-04-01 0:22 UTC (permalink / raw)
To: Andrew Morton; +Cc: nickpiggin, linux-mm
In-Reply-To: <20060331160032.6e437226.akpm@osdl.org>
On Fri, 31 Mar 2006, Andrew Morton wrote:
> > A build server. Lots of scripts running, compilers etc etc.
>
> Interesting. Many CPUs?
12 processors. 6 nodes.
> A plain old sysrq-T would be great. That'll tell us who owns iprune_sem,
> and what he's up to while holding it. Actually five-odd sysrq-T's would be
> better.
Some traces:
Stack traceback for pid 16836
0xe00000380bc68000 16836 1 1 6 R
0xa00000020b8e6050 [xfs]xfs_iextract+0x190
0xa00000020b8e63a0 [xfs]xfs_ireclaim+0x80
0xa00000020b921c70 [xfs]xfs_finish_reclaim+0x330
0xa00000020b921fa0 [xfs]xfs_reclaim+0x140
0xa00000020b93f820 [xfs]linvfs_clear_inode+0x260
0xa0000001001855f0 clear_inode+0x310
0xa000000100185f70 dispose_list+0x90
0xa000000100186c40 shrink_icache_memory+0x480
0xa000000100105bb0 shrink_slab+0x290
0xa000000100107cc0 try_to_free_pages+0x380
0xa0000001000f9f70 __alloc_pages+0x330
0xa0000001000ed940 page_cache_alloc_cold+0x160
0xa0000001000fe3a0 __do_page_cache_readahead+0x120
0xa0000001000fe820 blockable_page_cache_readahead+0xe0
0xa0000001000fea50 make_ahead_window+0x150
0xa0000001000fee30 page_cache_readahead+0x390
0xa0000001000ee730 do_generic_mapping_read+0x190
0xa0000001000efd80 __generic_file_aio_read+0x2c0
0xa00000020b93c190 [xfs]xfs_read+0x3b0
0xa00000020b934170 [xfs]linvfs_aio_read+0x130
Stack traceback for pid 19357
0xe000003815dc0000 19357 19108 0 10 D
0xa000000100524b80 schedule+0x2940
0xa000000100521ee0 __down+0x260
0xa000000100186880 shrink_icache_memory+0xc0
0xa000000100105bb0 shrink_slab+0x290
0xa000000100107cc0 try_to_free_pages+0x380
0xa0000001000f9f70 __alloc_pages+0x330
0xa00000010012e7d0 alloc_page_vma+0x150
0xa0000001001108d0 __handle_mm_fault+0x390
0xa00000010052c520 ia64_do_page_fault+0x280
0xa00000010000caa0 ia64_leave_kernel
0xa0000001000f29b0 file_read_actor+0xb0
0xa0000001000ee830 do_generic_mapping_read+0x290
0xa0000001000efd80 __generic_file_aio_read+0x2c0
0xa00000020b93c190 [xfs]xfs_read+0x3b0
0xa00000020b934170 [xfs]linvfs_aio_read+0x130
0xa000000100146430 do_sync_read+0x170
0xa000000100147f20 vfs_read+0x200
0xa000000100148790 sys_read+0x70
0xa00000010000c830 ia64_trace_syscall+0xd0
Stack traceback for pid 12033
0xe000003414cd0000 12033 18401 0 10 D
0xa000000100524b80 schedule+0x2940
0xa000000100521ee0 __down+0x260
0xa000000100186880 shrink_icache_memory+0xc0
0xa000000100105bb0 shrink_slab+0x290
0xa000000100107cc0 try_to_free_pages+0x380
0xa0000001000f9f70 __alloc_pages+0x330
0xa00000010012e7d0 alloc_page_vma+0x150
0xa0000001001108d0 __handle_mm_fault+0x390
0xa00000010052c520 ia64_do_page_fault+0x280
0xa00000010000caa0 ia64_leave_kernel
0xa0000001000f29b0 file_read_actor+0xb0
0xa0000001000ee830 do_generic_mapping_read+0x290
0xa0000001000efd80 __generic_file_aio_read+0x2c0
0xa00000020b93c190 [xfs]xfs_read+0x3b0
0xa00000020b934170 [xfs]linvfs_aio_read+0x130
0xa000000100146430 do_sync_read+0x170
0xa000000100147f20 vfs_read+0x200
0xa000000100148790 sys_read+0x70
0xa00000010000c830 ia64_trace_syscall+0xd0
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
* Re: Avoid excessive time spend on concurrent slab shrinking
From: Andrew Morton @ 2006-04-01 0:14 UTC (permalink / raw)
To: clameter, nickpiggin, linux-mm
In-Reply-To: <20060331160032.6e437226.akpm@osdl.org>
Andrew Morton <akpm@osdl.org> wrote:
>
> A plain old sysrq-T would be great.
>
Really great.
We do potentially-vast gobs of waiting for I/O in
prune_icache->dispose_list->truncate_inode_pages().
But then, why would dispose_list() run truncate_inode_pages()? Reclaiming
an inode which has no links to it, perhaps - it's been a while since I was
in there <wishes he added more comments last time he understood that stuff>
clear_inode() does wait_on_inode()...
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
* Re: Avoid excessive time spend on concurrent slab shrinking
From: Andrew Morton @ 2006-04-01 0:00 UTC (permalink / raw)
To: Christoph Lameter; +Cc: nickpiggin, linux-mm
In-Reply-To: <Pine.LNX.4.64.0603311541260.8948@schroedinger.engr.sgi.com>
Christoph Lameter <clameter@sgi.com> wrote:
>
> On Fri, 31 Mar 2006, Andrew Morton wrote:
>
> > > System sluggish in general. cscope takes 20 minutes to start etc. Dropping
> > > the caches restored performance.
> >
> > OK. What sort of system was it, and what was the workload? FIlesystem types?
>
> A build server. Lots of scripts running, compilers etc etc.
Interesting. Many CPUs?
> > It's been like that for an awful long time. Can you think why this has
> > only just now been noticed?
>
> Testing has reached new level of thoroughness because of the new releases
> that are due soon...
>
> > > We just noticed general sluggishness and took some stackdumps to see what
> > > the system was up to.
> >
> > OK. But was it D-state sleep (semaphore lock contention) or what?
>
> Yes, lots of processes waiting on semaphores in
> shrink_slab->shrink_icache_memory. Need to look at this in more detail it
> seems.
Please. Or at least suggest a means-of-reproducing.
A plain old sysrq-T would be great. That'll tell us who owns iprune_sem,
and what he's up to while holding it. Actually five-odd sysrq-T's would be
better.
If the lock holder is stuck on disk I/O or a congested queue or something
then that's very different from the lock holder being in a
pointlessly-burn-CPU-scanning-stuff condition.
> I looked at the old release that worked. Seems that it did the same thing
> in terms of slab shrinking. Concurrent slab shrinking was no problem. So
> you may be right. Its something unrelated to the code in vmscan.c. Maybe
> Nick knows something about this?
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
* Re: Avoid excessive time spend on concurrent slab shrinking
From: Christoph Lameter @ 2006-03-31 23:48 UTC (permalink / raw)
To: Andrew Morton; +Cc: nickpiggin, linux-mm
In-Reply-To: <20060331153235.754deb0c.akpm@osdl.org>
On Fri, 31 Mar 2006, Andrew Morton wrote:
> > System sluggish in general. cscope takes 20 minutes to start etc. Dropping
> > the caches restored performance.
>
> OK. What sort of system was it, and what was the workload? FIlesystem types?
A build server. Lots of scripts running, compilers etc etc.
> It's been like that for an awful long time. Can you think why this has
> only just now been noticed?
Testing has reached new level of thoroughness because of the new releases
that are due soon...
> > We just noticed general sluggishness and took some stackdumps to see what
> > the system was up to.
>
> OK. But was it D-state sleep (semaphore lock contention) or what?
Yes, lots of processes waiting on semaphores in
shrink_slab->shrink_icache_memory. Need to look at this in more detail it
seems.
I looked at the old release that worked. Seems that it did the same thing
in terms of slab shrinking. Concurrent slab shrinking was no problem. So
you may be right. Its something unrelated to the code in vmscan.c. Maybe
Nick knows something about this?
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
* Re: Avoid excessive time spend on concurrent slab shrinking
From: Andrew Morton @ 2006-03-31 23:46 UTC (permalink / raw)
To: Christoph Lameter; +Cc: nickpiggin, linux-mm
In-Reply-To: <Pine.LNX.4.64.0603311507130.8617@schroedinger.engr.sgi.com>
Christoph Lameter <clameter@sgi.com> wrote:
>
> On Fri, 31 Mar 2006, Andrew Morton wrote:
>
> > Christoph Lameter <clameter@sgi.com> wrote:
> > >
> > > We experienced that concurrent slab shrinking on 2.6.16 can slow down a
> > > system excessively due to lock contention.
> >
> > How much?
>
> System sluggish in general. cscope takes 20 minutes to start etc. Dropping
> the caches restored performance.
OK. What sort of system was it, and what was the workload? FIlesystem types?
What sort of overhead was it? sleeping-in-D-state?
pingponging-cachelines-around?
It's been like that for an awful long time. Can you think why this has
only just now been noticed?
> > Which lock(s)?
>
> Seems to be mainly iprune_sem. So its inode reclaim.
But why on earth would iprune_mutex make such a difference? The kernel can
throw away inodes at a great old rate, and it takes quite some time to
restore them.
I fear that something new is happening, and that prune_icache() is now
doing lots of work without achieving anything.
We have fiddled with various things in fs/inode.c which could affect this
over the past year. I wonder if one of those changes has caused the inode
scan to now scan lots of unreclaimable inodes.
> > > Slab shrinking is a global
> > > operation so it does not make sense for multiple slab shrink operations
> > > to be ongoing at the same time.
> >
> > That's how it used to be - it was a semaphore and we baled out if
> > down_trylock() failed. If we're going to revert that change then I'd
> > prefer to just go back to doing it that way (only with a mutex).
>
> No problem with that. Seems that the behavior <2.6.9 was okay. This showed
> up during beta testing of a new major distribution release.
OK.
> > The reason we made that change in 2.6.9:
> >
> > Use an rwsem to protect the shrinker list instead of a regular
> > semaphore. Modifications to the list are now done under the write lock,
> > shrink_slab takes the read lock, and access to shrinker->nr becomes racy
> > (which is no concurrent.
> >
> > Previously, having the slab scanner get preempted or scheduling while
> > holding the semaphore would cause other tasks to skip putting pressure on
> > the slab.
> >
> > Also, make shrink_icache_memory return -1 if it can't do anything in
> > order to hold pressure on this cache and prevent useless looping in
> > shrink_slab.
>
> Shrink_icache_memory() never returns -1.
if (!(gfp_mask & __GFP_FS))
return -1;
> > Note the lack of performance numbers? How are we to judge which the
> > regression which your proposal introduces is outweighed by the (unmeasured)
> > gain it provides?
>
> We just noticed general sluggishness and took some stackdumps to see what
> the system was up to.
OK. But was it D-state sleep (semaphore lock contention) or what?
> Do we have a benchmark for slab shrinking?
Nope. In general reclaim shouldn't be a performance problem because the
things which we reclaim take so much work to reestablish. It only causes
problems when we're repeatedly scanning lots of things which aren't
actually reclaimable. Hence my suspicions are aroused...
> > We need a *lot* of testing results with varied workloads and varying
> > machine types before we can say that changes like this are of aggregate
> > benefit and do not introduce bad corner-case regressions.
>
> The slowdown of the system running concurrent slab reclaim is pretty
> severe. Machine is basically unusable until you manually trigger the
> dropping of the caches.
bad.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
* Re: Avoid excessive time spend on concurrent slab shrinking
From: Andrew Morton @ 2006-03-31 23:45 UTC (permalink / raw)
To: Christoph Lameter; +Cc: nickpiggin, linux-mm
In-Reply-To: <Pine.LNX.4.64.0603311441400.8465@schroedinger.engr.sgi.com>
(Resent to correct linux-mm address)
Christoph Lameter <clameter@sgi.com> wrote:
>
> We experienced that concurrent slab shrinking on 2.6.16 can slow down a
> system excessively due to lock contention.
How much?
Which lock(s)?
> Slab shrinking is a global
> operation so it does not make sense for multiple slab shrink operations
> to be ongoing at the same time.
That's how it used to be - it was a semaphore and we baled out if
down_trylock() failed. If we're going to revert that change then I'd
prefer to just go back to doing it that way (only with a mutex).
The reason we made that change in 2.6.9:
Use an rwsem to protect the shrinker list instead of a regular
semaphore. Modifications to the list are now done under the write lock,
shrink_slab takes the read lock, and access to shrinker->nr becomes racy
(which is no concurrent.
Previously, having the slab scanner get preempted or scheduling while
holding the semaphore would cause other tasks to skip putting pressure on
the slab.
Also, make shrink_icache_memory return -1 if it can't do anything in
order to hold pressure on this cache and prevent useless looping in
shrink_slab.
Note the lack of performance numbers? How are we to judge which the
regression which your proposal introduces is outweighed by the (unmeasured)
gain it provides?
> The single shrinking task can perform the
> shrinking for all nodes and processors in the system.
Probably. But we _can_ sometimes do disk I/O while holding that lock, down
in the inode-releasing code, iirc. Could get bad with a `-o sync' mounted
filesystem.
> Introduce an atomic
> counter that works in the same was as in shrink_zone to limit concurrent
> shrinking.
No, a simple mutex_trylock() should suffice.
> Also calculate the time it took to do the shrinking and wait at least twice
> that time before doing it again. If we are spending excessive time
> on slab shrinking then we need to pause for some time to insure that the
> system is capable of archiving other tasks.
No way, sorry. I've had it with "gee let's do this, it might be better"
"optimisations" in that code.
We need a *lot* of testing results with varied workloads and varying
machine types before we can say that changes like this are of aggregate
benefit and do not introduce bad corner-case regressions.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
* Re: Avoid excessive time spend on concurrent slab shrinking
From: Christoph Lameter @ 2006-03-31 23:17 UTC (permalink / raw)
To: Andrew Morton; +Cc: nickpiggin, linux-mm
In-Reply-To: <20060331150120.21fad488.akpm@osdl.org>
On Fri, 31 Mar 2006, Andrew Morton wrote:
> Christoph Lameter <clameter@sgi.com> wrote:
> >
> > We experienced that concurrent slab shrinking on 2.6.16 can slow down a
> > system excessively due to lock contention.
>
> How much?
System sluggish in general. cscope takes 20 minutes to start etc. Dropping
the caches restored performance.
> Which lock(s)?
Seems to be mainly iprune_sem. So its inode reclaim.
> > Slab shrinking is a global
> > operation so it does not make sense for multiple slab shrink operations
> > to be ongoing at the same time.
>
> That's how it used to be - it was a semaphore and we baled out if
> down_trylock() failed. If we're going to revert that change then I'd
> prefer to just go back to doing it that way (only with a mutex).
No problem with that. Seems that the behavior <2.6.9 was okay. This showed
up during beta testing of a new major distribution release.
> The reason we made that change in 2.6.9:
>
> Use an rwsem to protect the shrinker list instead of a regular
> semaphore. Modifications to the list are now done under the write lock,
> shrink_slab takes the read lock, and access to shrinker->nr becomes racy
> (which is no concurrent.
>
> Previously, having the slab scanner get preempted or scheduling while
> holding the semaphore would cause other tasks to skip putting pressure on
> the slab.
>
> Also, make shrink_icache_memory return -1 if it can't do anything in
> order to hold pressure on this cache and prevent useless looping in
> shrink_slab.
Shrink_icache_memory() never returns -1.
> Note the lack of performance numbers? How are we to judge which the
> regression which your proposal introduces is outweighed by the (unmeasured)
> gain it provides?
We just noticed general sluggishness and took some stackdumps to see what
the system was up to. Do we have a benchmark for slab shrinking?
> We need a *lot* of testing results with varied workloads and varying
> machine types before we can say that changes like this are of aggregate
> benefit and do not introduce bad corner-case regressions.
The slowdown of the system running concurrent slab reclaim is pretty
severe. Machine is basically unusable until you manually trigger the
dropping of the caches.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
* Avoid excessive time spend on concurrent slab shrinking
From: Christoph Lameter @ 2006-03-31 22:44 UTC (permalink / raw)
To: akpm, nickpiggin; +Cc: linux-mm
We experienced that concurrent slab shrinking on 2.6.16 can slow down a
system excessively due to lock contention. Slab shrinking is a global
operation so it does not make sense for multiple slab shrink operations
to be ongoing at the same time. The single shrinking task can perform the
shrinking for all nodes and processors in the system. Introduce an atomic
counter that works in the same was as in shrink_zone to limit concurrent
shrinking.
Also calculate the time it took to do the shrinking and wait at least twice
that time before doing it again. If we are spending excessive time
on slab shrinking then we need to pause for some time to insure that the
system is capable of archiving other tasks.
Signed-off-by: Christoph Lameter <clameter@sgi.com>
Index: linux-2.6.16/mm/vmscan.c
===================================================================
--- linux-2.6.16.orig/mm/vmscan.c 2006-03-19 21:53:29.000000000 -0800
+++ linux-2.6.16/mm/vmscan.c 2006-03-31 14:38:18.000000000 -0800
@@ -130,6 +130,8 @@ static long total_memory;
static LIST_HEAD(shrinker_list);
static DECLARE_RWSEM(shrinker_rwsem);
+static atomic_t active_shrinkers;
+static unsigned long next_slab_shrink;
/*
* Add a shrinker callback to be called from the vm
@@ -187,12 +189,18 @@ int shrink_slab(unsigned long scanned, g
{
struct shrinker *shrinker;
int ret = 0;
+ unsigned long shrinkstart;
if (scanned == 0)
scanned = SWAP_CLUSTER_MAX;
- if (!down_read_trylock(&shrinker_rwsem))
- return 1; /* Assume we'll be able to shrink next time */
+ if (atomic_read(&active_shrinkers) ||
+ time_before(jiffies, next_slab_shrink) ||
+ !down_read_trylock(&shrinker_rwsem))
+ /* Assume we'll be able to shrink next time */
+ return 1;
+ atomic_inc(&active_shrinkers);
+ shrinkstart = jiffies;
list_for_each_entry(shrinker, &shrinker_list, list) {
unsigned long long delta;
@@ -239,6 +247,12 @@ int shrink_slab(unsigned long scanned, g
shrinker->nr += total_scan;
}
+ /*
+ * If slab shrinking took a long time then lets at least wait
+ * twice as long as it took before we do it again.
+ */
+ next_slab_shrink = jiffies + 2 * (jiffies - shrinkstart);
+ atomic_dec(&active_shrinkers);
up_read(&shrinker_rwsem);
return ret;
}
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
* RE: [patch] don't allow free hugetlb count fall below reserved count
From: Chen, Kenneth W @ 2006-03-31 1:20 UTC (permalink / raw)
To: 'David Gibson'; +Cc: linux-mm, akpm
In-Reply-To: <20060331004156.GK19421@localhost.localdomain>
David Gibson wrote on Thursday, March 30, 2006 4:42 PM
> Ken - did you keep working on your alternative strict reservation
> patches? Last I recall they seemed to be converging on mine in all
> the points I thought really mattered, except that I hadn't updated
> mine to remove some of the problems you pointed out in it while
> developing your patches (e.g. unnecessarily taking a lock on reserve).
>
> I'm actually on a very long leave at the moment, so I'm not really
> doing anything active. Those problems should be fixed at some point,
> though, either with patches to my approach, or by replacing it with
> yours.
Since andrew already merged your reservation patch for 2.6.17, I will
shelf mine for now ...
I will work on the base kernel and add stuff to the current code.
- Ken
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
* Re: [patch] don't allow free hugetlb count fall below reserved count
From: 'David Gibson' @ 2006-03-31 0:41 UTC (permalink / raw)
To: Chen, Kenneth W; +Cc: linux-mm, akpm
In-Reply-To: <200603310013.k2V0Dng26534@unix-os.sc.intel.com>
On Thu, Mar 30, 2006 at 04:14:34PM -0800, Chen, Kenneth W wrote:
> With strict page reservation, I think kernel should enforce number of
> free hugetlb page don't fall below reserved count. Currently it is
> possible in the sysctl path. Add proper check in sysctl to disallow
> that.
Hmm.. maybe. I have no strong view either way. With this patch
you're safer against accidentally taking hugepages away from a process
which needs them. On the other hand, leaving it out gives a sysadmin
more flexibility to free up normal memory at the expense of risking
crashes for hugepage processes.
Ken - did you keep working on your alternative strict reservation
patches? Last I recall they seemed to be converging on mine in all
the points I thought really mattered, except that I hadn't updated
mine to remove some of the problems you pointed out in it while
developing your patches (e.g. unnecessarily taking a lock on reserve).
I'm actually on a very long leave at the moment, so I'm not really
doing anything active. Those problems should be fixed at some point,
though, either with patches to my approach, or by replacing it with
yours.
> Signed-off-by: Ken Chen <kenneth.w.chen@intel.com>
>
> --- ./mm/hugetlb.c.orig 2006-03-30 15:32:20.000000000 -0800
> +++ ./mm/hugetlb.c 2006-03-30 15:48:22.000000000 -0800
> @@ -334,6 +334,7 @@
> return nr_huge_pages;
>
> spin_lock(&hugetlb_lock);
> + count = max(count, reserved_huge_pages);
> try_to_free_low(count);
> while (count < nr_huge_pages) {
> struct page *page = dequeue_huge_page(NULL, 0);
>
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
* [patch] don't allow free hugetlb count fall below reserved count
From: Chen, Kenneth W @ 2006-03-31 0:14 UTC (permalink / raw)
To: linux-mm; +Cc: 'David Gibson', akpm
With strict page reservation, I think kernel should enforce number of
free hugetlb page don't fall below reserved count. Currently it is
possible in the sysctl path. Add proper check in sysctl to disallow
that.
Signed-off-by: Ken Chen <kenneth.w.chen@intel.com>
--- ./mm/hugetlb.c.orig 2006-03-30 15:32:20.000000000 -0800
+++ ./mm/hugetlb.c 2006-03-30 15:48:22.000000000 -0800
@@ -334,6 +334,7 @@
return nr_huge_pages;
spin_lock(&hugetlb_lock);
+ count = max(count, reserved_huge_pages);
try_to_free_low(count);
while (count < nr_huge_pages) {
struct page *page = dequeue_huge_page(NULL, 0);
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
* [patch] fix extra page ref count in follow_hugetlb_page
From: Chen, Kenneth W @ 2006-03-30 23:19 UTC (permalink / raw)
To: linux-mm; +Cc: akpm, 'Adam Litke'
"[PATCH] optimize follow_hugetlb_page" breaks mlock on hugepage areas.
I mis-interpret pages argument and made get_page() unconditional. It
should only get a ref count when "pages" argument is non-null.
Credit goes to Adam Litke who spotted the bug.
Signed-off-by: Ken Chen <kenneth.w.chen@intel.com>
Acked-by: Adam Litke <agl@us.ibm.com>
--- ./mm/hugetlb.c.orig 2006-03-30 15:54:20.000000000 -0800
+++ ./mm/hugetlb.c 2006-03-30 15:54:56.000000000 -0800
@@ -555,9 +555,10 @@ int follow_hugetlb_page(struct mm_struct
pfn_offset = (vaddr & ~HPAGE_MASK) >> PAGE_SHIFT;
page = pte_page(*pte);
same_page:
- get_page(page);
- if (pages)
+ if (pages) {
+ get_page(page);
pages[i] = page + pfn_offset;
+ }
if (vmas)
vmas[i] = vma;
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox