git://ftp.safe.ca
/
safe
/
jmp
/
linux-2.6
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Merge branch 'tracing/core-v2' into tracing-for-linus
[safe/jmp/linux-2.6]
/
mm
/
swapfile.c
diff --git
a/mm/swapfile.c
b/mm/swapfile.c
index
fb926ef
..
312fafe
100644
(file)
--- a/
mm/swapfile.c
+++ b/
mm/swapfile.c
@@
-33,6
+33,7
@@
#include <asm/pgtable.h>
#include <asm/tlbflush.h>
#include <linux/swapops.h>
#include <asm/pgtable.h>
#include <asm/tlbflush.h>
#include <linux/swapops.h>
+#include <linux/page_cgroup.h>
static DEFINE_SPINLOCK(swap_lock);
static unsigned int nr_swapfiles;
static DEFINE_SPINLOCK(swap_lock);
static unsigned int nr_swapfiles;
@@
-470,8
+471,9
@@
out:
return NULL;
}
return NULL;
}
-static int swap_entry_free(struct swap_info_struct *p,
unsigned long offse
t)
+static int swap_entry_free(struct swap_info_struct *p,
swp_entry_t en
t)
{
{
+ unsigned long offset = swp_offset(ent);
int count = p->swap_map[offset];
if (count < SWAP_MAP_MAX) {
int count = p->swap_map[offset];
if (count < SWAP_MAP_MAX) {
@@
-486,6
+488,7
@@
static int swap_entry_free(struct swap_info_struct *p, unsigned long offset)
swap_list.next = p - swap_info;
nr_swap_pages++;
p->inuse_pages--;
swap_list.next = p - swap_info;
nr_swap_pages++;
p->inuse_pages--;
+ mem_cgroup_uncharge_swap(ent);
}
}
return count;
}
}
return count;
@@
-501,7
+504,7
@@
void swap_free(swp_entry_t entry)
p = swap_info_get(entry);
if (p) {
p = swap_info_get(entry);
if (p) {
- swap_entry_free(p,
swp_offset(entry)
);
+ swap_entry_free(p,
entry
);
spin_unlock(&swap_lock);
}
}
spin_unlock(&swap_lock);
}
}
@@
-581,7
+584,7
@@
int free_swap_and_cache(swp_entry_t entry)
p = swap_info_get(entry);
if (p) {
p = swap_info_get(entry);
if (p) {
- if (swap_entry_free(p,
swp_offset(entry)
) == 1) {
+ if (swap_entry_free(p,
entry
) == 1) {
page = find_get_page(&swapper_space, entry.val);
if (page && !trylock_page(page)) {
page_cache_release(page);
page = find_get_page(&swapper_space, entry.val);
if (page && !trylock_page(page)) {
page_cache_release(page);
@@
-632,7
+635,7
@@
int swap_type_of(dev_t device, sector_t offset, struct block_device **bdev_p)
if (!bdev) {
if (bdev_p)
if (!bdev) {
if (bdev_p)
- *bdev_p =
sis->bdev
;
+ *bdev_p =
bdget(sis->bdev->bd_dev)
;
spin_unlock(&swap_lock);
return i;
spin_unlock(&swap_lock);
return i;
@@
-644,7
+647,7
@@
int swap_type_of(dev_t device, sector_t offset, struct block_device **bdev_p)
struct swap_extent, list);
if (se->start_block == offset) {
if (bdev_p)
struct swap_extent, list);
if (se->start_block == offset) {
if (bdev_p)
- *bdev_p =
sis->bdev
;
+ *bdev_p =
bdget(sis->bdev->bd_dev)
;
spin_unlock(&swap_lock);
bdput(bdev);
spin_unlock(&swap_lock);
bdput(bdev);
@@
-695,8
+698,10
@@
static int unuse_pte(struct vm_area_struct *vma, pmd_t *pmd,
pte_t *pte;
int ret = 1;
pte_t *pte;
int ret = 1;
- if (mem_cgroup_try_charge
(vma->vm_mm, GFP_KERNEL, &ptr))
+ if (mem_cgroup_try_charge
_swapin(vma->vm_mm, page, GFP_KERNEL, &ptr)) {
ret = -ENOMEM;
ret = -ENOMEM;
+ goto out_nolock;
+ }
pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl);
if (unlikely(!pte_same(*pte, swp_entry_to_pte(entry)))) {
pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl);
if (unlikely(!pte_same(*pte, swp_entry_to_pte(entry)))) {
@@
-720,6
+725,7
@@
static int unuse_pte(struct vm_area_struct *vma, pmd_t *pmd,
activate_page(page);
out:
pte_unmap_unlock(pte, ptl);
activate_page(page);
out:
pte_unmap_unlock(pte, ptl);
+out_nolock:
return ret;
}
return ret;
}
@@
-1374,7
+1380,7
@@
out:
return ret;
}
return ret;
}
-
asmlinkage long sys_swapoff(const char __user *
specialfile)
+
SYSCALL_DEFINE1(swapoff, const char __user *,
specialfile)
{
struct swap_info_struct * p = NULL;
unsigned short *swap_map;
{
struct swap_info_struct * p = NULL;
unsigned short *swap_map;
@@
-1494,6
+1500,9
@@
asmlinkage long sys_swapoff(const char __user * specialfile)
spin_unlock(&swap_lock);
mutex_unlock(&swapon_mutex);
vfree(swap_map);
spin_unlock(&swap_lock);
mutex_unlock(&swapon_mutex);
vfree(swap_map);
+ /* Destroy swap account informatin */
+ swap_cgroup_swapoff(type);
+
inode = mapping->host;
if (S_ISBLK(inode->i_mode)) {
struct block_device *bdev = I_BDEV(inode);
inode = mapping->host;
if (S_ISBLK(inode->i_mode)) {
struct block_device *bdev = I_BDEV(inode);
@@
-1627,7
+1636,7
@@
late_initcall(max_swapfiles_check);
*
* The swapon system call
*/
*
* The swapon system call
*/
-
asmlinkage long sys_swapon(const char __user * specialfile, int
swap_flags)
+
SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int,
swap_flags)
{
struct swap_info_struct * p;
char *name = NULL;
{
struct swap_info_struct * p;
char *name = NULL;
@@
-1811,6
+1820,11
@@
asmlinkage long sys_swapon(const char __user * specialfile, int swap_flags)
}
swap_map[page_nr] = SWAP_MAP_BAD;
}
}
swap_map[page_nr] = SWAP_MAP_BAD;
}
+
+ error = swap_cgroup_swapon(type, maxpages);
+ if (error)
+ goto bad_swap;
+
nr_good_pages = swap_header->info.last_page -
swap_header->info.nr_badpages -
1 /* header page */;
nr_good_pages = swap_header->info.last_page -
swap_header->info.nr_badpages -
1 /* header page */;
@@
-1882,6
+1896,7
@@
bad_swap:
bd_release(bdev);
}
destroy_swap_extents(p);
bd_release(bdev);
}
destroy_swap_extents(p);
+ swap_cgroup_swapoff(type);
bad_swap_2:
spin_lock(&swap_lock);
p->swap_file = NULL;
bad_swap_2:
spin_lock(&swap_lock);
p->swap_file = NULL;