Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 131184
b: refs/heads/master
c: 5a6fe12
h: refs/heads/master
v: v3
  • Loading branch information
Mel Gorman authored and Linus Torvalds committed Feb 10, 2009
1 parent 5e80d6c commit a0e9d03
Show file tree
Hide file tree
Showing 9 changed files with 66 additions and 44 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: 4c098bcd55fad34dcf224bf8343db6a9ac58fc68
refs/heads/master: 5a6fe125950676015f5108fb71b2a67441755003
8 changes: 5 additions & 3 deletions trunk/fs/hugetlbfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,8 @@ static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma)

if (hugetlb_reserve_pages(inode,
vma->vm_pgoff >> huge_page_order(h),
len >> huge_page_shift(h), vma))
len >> huge_page_shift(h), vma,
vma->vm_flags))
goto out;

ret = 0;
Expand Down Expand Up @@ -947,7 +948,7 @@ static int can_do_hugetlb_shm(void)
can_do_mlock());
}

struct file *hugetlb_file_setup(const char *name, size_t size)
struct file *hugetlb_file_setup(const char *name, size_t size, int acctflag)
{
int error = -ENOMEM;
struct file *file;
Expand Down Expand Up @@ -981,7 +982,8 @@ struct file *hugetlb_file_setup(const char *name, size_t size)

error = -ENOMEM;
if (hugetlb_reserve_pages(inode, 0,
size >> huge_page_shift(hstate_inode(inode)), NULL))
size >> huge_page_shift(hstate_inode(inode)), NULL,
acctflag))
goto out_inode;

d_instantiate(dentry, inode);
Expand Down
5 changes: 3 additions & 2 deletions trunk/include/linux/hugetlb.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ unsigned long hugetlb_total_pages(void);
int hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma,
unsigned long address, int write_access);
int hugetlb_reserve_pages(struct inode *inode, long from, long to,
struct vm_area_struct *vma);
struct vm_area_struct *vma,
int acctflags);
void hugetlb_unreserve_pages(struct inode *inode, long offset, long freed);

extern unsigned long hugepages_treat_as_movable;
Expand Down Expand Up @@ -138,7 +139,7 @@ static inline struct hugetlbfs_sb_info *HUGETLBFS_SB(struct super_block *sb)

extern const struct file_operations hugetlbfs_file_operations;
extern struct vm_operations_struct hugetlb_vm_ops;
struct file *hugetlb_file_setup(const char *name, size_t);
struct file *hugetlb_file_setup(const char *name, size_t, int);
int hugetlb_get_quota(struct address_space *mapping, long delta);
void hugetlb_put_quota(struct address_space *mapping, long delta);

Expand Down
3 changes: 1 addition & 2 deletions trunk/include/linux/mm.h
Original file line number Diff line number Diff line change
Expand Up @@ -1129,8 +1129,7 @@ extern unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
unsigned long flag, unsigned long pgoff);
extern unsigned long mmap_region(struct file *file, unsigned long addr,
unsigned long len, unsigned long flags,
unsigned int vm_flags, unsigned long pgoff,
int accountable);
unsigned int vm_flags, unsigned long pgoff);

static inline unsigned long do_mmap(struct file *file, unsigned long addr,
unsigned long len, unsigned long prot,
Expand Down
8 changes: 5 additions & 3 deletions trunk/ipc/shm.c
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,7 @@ static int newseg(struct ipc_namespace *ns, struct ipc_params *params)
struct file * file;
char name[13];
int id;
int acctflag = 0;

if (size < SHMMIN || size > ns->shm_ctlmax)
return -EINVAL;
Expand All @@ -364,11 +365,12 @@ static int newseg(struct ipc_namespace *ns, struct ipc_params *params)

sprintf (name, "SYSV%08x", key);
if (shmflg & SHM_HUGETLB) {
/* hugetlb_file_setup takes care of mlock user accounting */
file = hugetlb_file_setup(name, size);
/* hugetlb_file_setup applies strict accounting */
if (shmflg & SHM_NORESERVE)
acctflag = VM_NORESERVE;
file = hugetlb_file_setup(name, size, acctflag);
shp->mlock_user = current_user();
} else {
int acctflag = 0;
/*
* Do not allow no accounting for OVERCOMMIT_NEVER, even
* if it's asked for.
Expand Down
2 changes: 1 addition & 1 deletion trunk/mm/fremap.c
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size,
flags &= MAP_NONBLOCK;
get_file(file);
addr = mmap_region(file, start, size,
flags, vma->vm_flags, pgoff, 1);
flags, vma->vm_flags, pgoff);
fput(file);
if (IS_ERR_VALUE(addr)) {
err = addr;
Expand Down
39 changes: 25 additions & 14 deletions trunk/mm/hugetlb.c
Original file line number Diff line number Diff line change
Expand Up @@ -2269,14 +2269,12 @@ void hugetlb_change_protection(struct vm_area_struct *vma,

int hugetlb_reserve_pages(struct inode *inode,
long from, long to,
struct vm_area_struct *vma)
struct vm_area_struct *vma,
int acctflag)
{
long ret, chg;
long ret = 0, chg;
struct hstate *h = hstate_inode(inode);

if (vma && vma->vm_flags & VM_NORESERVE)
return 0;

/*
* Shared mappings base their reservation on the number of pages that
* are already allocated on behalf of the file. Private mappings need
Expand All @@ -2285,29 +2283,42 @@ int hugetlb_reserve_pages(struct inode *inode,
*/
if (!vma || vma->vm_flags & VM_SHARED)
chg = region_chg(&inode->i_mapping->private_list, from, to);
else {
struct resv_map *resv_map = resv_map_alloc();
if (!resv_map)
return -ENOMEM;

else
chg = to - from;

set_vma_resv_map(vma, resv_map);
set_vma_resv_flags(vma, HPAGE_RESV_OWNER);
}

if (chg < 0)
return chg;

if (hugetlb_get_quota(inode->i_mapping, chg))
return -ENOSPC;

/*
* Only apply hugepage reservation if asked. We still have to
* take the filesystem quota because it is an upper limit
* defined for the mount and not necessarily memory as a whole
*/
if (acctflag & VM_NORESERVE) {
reset_vma_resv_huge_pages(vma);
return 0;
}

ret = hugetlb_acct_memory(h, chg);
if (ret < 0) {
hugetlb_put_quota(inode->i_mapping, chg);
return ret;
}
if (!vma || vma->vm_flags & VM_SHARED)
region_add(&inode->i_mapping->private_list, from, to);
else {
struct resv_map *resv_map = resv_map_alloc();

if (!resv_map)
return -ENOMEM;

set_vma_resv_map(vma, resv_map);
set_vma_resv_flags(vma, HPAGE_RESV_OWNER);
}

return 0;
}

Expand Down
38 changes: 22 additions & 16 deletions trunk/mm/mmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -918,7 +918,6 @@ unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
struct inode *inode;
unsigned int vm_flags;
int error;
int accountable = 1;
unsigned long reqprot = prot;

/*
Expand Down Expand Up @@ -1019,8 +1018,6 @@ unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
return -EPERM;
vm_flags &= ~VM_MAYEXEC;
}
if (is_file_hugepages(file))
accountable = 0;

if (!file->f_op || !file->f_op->mmap)
return -ENODEV;
Expand Down Expand Up @@ -1053,8 +1050,7 @@ unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
if (error)
return error;

return mmap_region(file, addr, len, flags, vm_flags, pgoff,
accountable);
return mmap_region(file, addr, len, flags, vm_flags, pgoff);
}
EXPORT_SYMBOL(do_mmap_pgoff);

Expand Down Expand Up @@ -1092,17 +1088,23 @@ int vma_wants_writenotify(struct vm_area_struct *vma)

/*
* We account for memory if it's a private writeable mapping,
* and VM_NORESERVE wasn't set.
* not hugepages and VM_NORESERVE wasn't set.
*/
static inline int accountable_mapping(unsigned int vm_flags)
static inline int accountable_mapping(struct file *file, unsigned int vm_flags)
{
/*
* hugetlb has its own accounting separate from the core VM
* VM_HUGETLB may not be set yet so we cannot check for that flag.
*/
if (file && is_file_hugepages(file))
return 0;

return (vm_flags & (VM_NORESERVE | VM_SHARED | VM_WRITE)) == VM_WRITE;
}

unsigned long mmap_region(struct file *file, unsigned long addr,
unsigned long len, unsigned long flags,
unsigned int vm_flags, unsigned long pgoff,
int accountable)
unsigned int vm_flags, unsigned long pgoff)
{
struct mm_struct *mm = current->mm;
struct vm_area_struct *vma, *prev;
Expand All @@ -1128,18 +1130,22 @@ unsigned long mmap_region(struct file *file, unsigned long addr,

/*
* Set 'VM_NORESERVE' if we should not account for the
* memory use of this mapping. We only honor MAP_NORESERVE
* if we're allowed to overcommit memory.
* memory use of this mapping.
*/
if ((flags & MAP_NORESERVE) && sysctl_overcommit_memory != OVERCOMMIT_NEVER)
vm_flags |= VM_NORESERVE;
if (!accountable)
vm_flags |= VM_NORESERVE;
if ((flags & MAP_NORESERVE)) {
/* We honor MAP_NORESERVE if allowed to overcommit */
if (sysctl_overcommit_memory != OVERCOMMIT_NEVER)
vm_flags |= VM_NORESERVE;

/* hugetlb applies strict overcommit unless MAP_NORESERVE */
if (file && is_file_hugepages(file))
vm_flags |= VM_NORESERVE;
}

/*
* Private writable mapping: check memory availability
*/
if (accountable_mapping(vm_flags)) {
if (accountable_mapping(file, vm_flags)) {
charged = len >> PAGE_SHIFT;
if (security_vm_enough_memory(charged))
return -ENOMEM;
Expand Down
5 changes: 3 additions & 2 deletions trunk/mm/mprotect.c
Original file line number Diff line number Diff line change
Expand Up @@ -151,10 +151,11 @@ mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
/*
* If we make a private mapping writable we increase our commit;
* but (without finer accounting) cannot reduce our commit if we
* make it unwritable again.
* make it unwritable again. hugetlb mapping were accounted for
* even if read-only so there is no need to account for them here
*/
if (newflags & VM_WRITE) {
if (!(oldflags & (VM_ACCOUNT|VM_WRITE|
if (!(oldflags & (VM_ACCOUNT|VM_WRITE|VM_HUGETLB|
VM_SHARED|VM_NORESERVE))) {
charged = nrpages;
if (security_vm_enough_memory(charged))
Expand Down

0 comments on commit a0e9d03

Please sign in to comment.