Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 176260
b: refs/heads/master
c: 570a335
h: refs/heads/master
v: v3
  • Loading branch information
Hugh Dickins authored and Linus Torvalds committed Dec 15, 2009
1 parent edc5721 commit 8786a97
Show file tree
Hide file tree
Showing 5 changed files with 288 additions and 65 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 8d69aaee80c123b460918816cbfa2e83224c3646
refs/heads/master: 570a335b8e22579e2a51a68136d2b1f907a20eec
22 changes: 16 additions & 6 deletions trunk/include/linux/swap.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,15 +145,18 @@ enum {
SWP_DISCARDABLE = (1 << 2), /* blkdev supports discard */
SWP_DISCARDING = (1 << 3), /* now discarding a free cluster */
SWP_SOLIDSTATE = (1 << 4), /* blkdev seeks are cheap */
SWP_CONTINUED = (1 << 5), /* swap_map has count continuation */
/* add others here before... */
SWP_SCANNING = (1 << 8), /* refcount in scan_swap_map */
};

#define SWAP_CLUSTER_MAX 32

#define SWAP_MAP_MAX 0x7e
#define SWAP_MAP_BAD 0x7f
#define SWAP_HAS_CACHE 0x80 /* There is a swap cache of entry. */
#define SWAP_MAP_MAX 0x3e /* Max duplication count, in first swap_map */
#define SWAP_MAP_BAD 0x3f /* Note pageblock is bad, in first swap_map */
#define SWAP_HAS_CACHE 0x40 /* Flag page is cached, in first swap_map */
#define SWAP_CONT_MAX 0x7f /* Max count, in each swap_map continuation */
#define COUNT_CONTINUED 0x80 /* See swap_map continuation for full count */

/*
* The in-memory structure used to track swap areas.
Expand Down Expand Up @@ -311,9 +314,10 @@ extern long total_swap_pages;
extern void si_swapinfo(struct sysinfo *);
extern swp_entry_t get_swap_page(void);
extern swp_entry_t get_swap_page_of_type(int);
extern void swap_duplicate(swp_entry_t);
extern int swapcache_prepare(swp_entry_t);
extern int valid_swaphandles(swp_entry_t, unsigned long *);
extern int add_swap_count_continuation(swp_entry_t, gfp_t);
extern int swap_duplicate(swp_entry_t);
extern int swapcache_prepare(swp_entry_t);
extern void swap_free(swp_entry_t);
extern void swapcache_free(swp_entry_t, struct page *page);
extern int free_swap_and_cache(swp_entry_t);
Expand Down Expand Up @@ -385,8 +389,14 @@ static inline void show_swap_cache_info(void)
#define free_swap_and_cache(swp) is_migration_entry(swp)
#define swapcache_prepare(swp) is_migration_entry(swp)

static inline void swap_duplicate(swp_entry_t swp)
static inline int add_swap_count_continuation(swp_entry_t swp, gfp_t gfp_mask)
{
return 0;
}

static inline int swap_duplicate(swp_entry_t swp)
{
return 0;
}

static inline void swap_free(swp_entry_t swp)
Expand Down
19 changes: 16 additions & 3 deletions trunk/mm/memory.c
Original file line number Diff line number Diff line change
Expand Up @@ -572,7 +572,7 @@ struct page *vm_normal_page(struct vm_area_struct *vma, unsigned long addr,
* covered by this vma.
*/

static inline void
static inline unsigned long
copy_one_pte(struct mm_struct *dst_mm, struct mm_struct *src_mm,
pte_t *dst_pte, pte_t *src_pte, struct vm_area_struct *vma,
unsigned long addr, int *rss)
Expand All @@ -586,7 +586,9 @@ copy_one_pte(struct mm_struct *dst_mm, struct mm_struct *src_mm,
if (!pte_file(pte)) {
swp_entry_t entry = pte_to_swp_entry(pte);

swap_duplicate(entry);
if (swap_duplicate(entry) < 0)
return entry.val;

/* make sure dst_mm is on swapoff's mmlist. */
if (unlikely(list_empty(&dst_mm->mmlist))) {
spin_lock(&mmlist_lock);
Expand Down Expand Up @@ -635,6 +637,7 @@ copy_one_pte(struct mm_struct *dst_mm, struct mm_struct *src_mm,

out_set_pte:
set_pte_at(dst_mm, addr, dst_pte, pte);
return 0;
}

static int copy_pte_range(struct mm_struct *dst_mm, struct mm_struct *src_mm,
Expand All @@ -646,6 +649,7 @@ static int copy_pte_range(struct mm_struct *dst_mm, struct mm_struct *src_mm,
spinlock_t *src_ptl, *dst_ptl;
int progress = 0;
int rss[2];
swp_entry_t entry = (swp_entry_t){0};

again:
rss[1] = rss[0] = 0;
Expand Down Expand Up @@ -674,7 +678,10 @@ static int copy_pte_range(struct mm_struct *dst_mm, struct mm_struct *src_mm,
progress++;
continue;
}
copy_one_pte(dst_mm, src_mm, dst_pte, src_pte, vma, addr, rss);
entry.val = copy_one_pte(dst_mm, src_mm, dst_pte, src_pte,
vma, addr, rss);
if (entry.val)
break;
progress += 8;
} while (dst_pte++, src_pte++, addr += PAGE_SIZE, addr != end);

Expand All @@ -684,6 +691,12 @@ static int copy_pte_range(struct mm_struct *dst_mm, struct mm_struct *src_mm,
add_mm_rss(dst_mm, rss[0], rss[1]);
pte_unmap_unlock(orig_dst_pte, dst_ptl);
cond_resched();

if (entry.val) {
if (add_swap_count_continuation(entry, GFP_KERNEL) < 0)
return -ENOMEM;
progress = 0;
}
if (addr != end)
goto again;
return 0;
Expand Down
6 changes: 5 additions & 1 deletion trunk/mm/rmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -822,7 +822,11 @@ static int try_to_unmap_one(struct page *page, struct vm_area_struct *vma,
* Store the swap location in the pte.
* See handle_pte_fault() ...
*/
swap_duplicate(entry);
if (swap_duplicate(entry) < 0) {
set_pte_at(mm, address, pte, pteval);
ret = SWAP_FAIL;
goto out_unmap;
}
if (list_empty(&mm->mmlist)) {
spin_lock(&mmlist_lock);
if (list_empty(&mm->mmlist))
Expand Down
Loading

0 comments on commit 8786a97

Please sign in to comment.