Re: [PATCH] [0/6] HUGETLB memory commitment

From: Andy Whitcroft
Date: Mon Mar 29 2004 - 08:14:23 EST


--On 28 March 2004 11:10 -0800 "Martin J. Bligh" <mbligh@xxxxxxxxxxx> wrote:

> 1. Stop hugepages using the existing overcommit pool for small pages,
> which breaks small page allocations by prematurely the pool.
> 2. Give hugepages their own over-commit pool, instead of prefaulting.

Indeed. The previous patches I submitted only address #1. Attached is
another patch which should address #2, it supplies hugetlb commit
accounting. This is checked and applied when the segment is created. It
also supplements the meminfo information to display this new commitment.
The patch only implments strict commitment, but as has been stated here
often, it is not clear that overcommit of unswappable memory makes any
sense in the absence of demand allocation. When that is implemented then
this will likely need a policy.

Patch applies on top of my previous patch and has been tested on i386.

-apw---
file | 1 +
fs/hugetlbfs/inode.c | 32 ++++++++++++++++++++++++++++++--
fs/proc/proc_misc.c | 1 +
include/linux/hugetlb.h | 3 +++
4 files changed, 35 insertions(+), 2 deletions(-)

diff -X /home/apw/lib/vdiff.excl -rupN reference/file current/file
--- reference/file 1970-01-01 01:00:00.000000000 +0100
+++ current/file 2004-03-29 12:10:17.000000000 +0100
@@ -0,0 +1 @@
+this is more text
diff -X /home/apw/lib/vdiff.excl -rupN reference/fs/hugetlbfs/inode.c current/fs/hugetlbfs/inode.c
--- reference/fs/hugetlbfs/inode.c 2004-03-25 02:43:00.000000000 +0000
+++ current/fs/hugetlbfs/inode.c 2004-03-29 13:26:57.000000000 +0100
@@ -32,6 +32,25 @@
/* some random number */
#define HUGETLBFS_MAGIC 0x958458f6

+atomic_t hugetlb_committed_space = ATOMIC_INIT(0);
+
+int hugetlb_acct_memory(long delta)
+{
+ atomic_add(delta, &hugetlb_committed_space);
+ if (delta > 0 && atomic_read(&hugetlb_committed_space) >
+ hugetlb_total_pages()) {
+ atomic_add(-delta, &hugetlb_committed_space);
+ return -ENOMEM;
+ }
+ return 0;
+}
+
+int hugetlbfs_report_meminfo(char *buf)
+{
+ long htlb = atomic_read(&hugetlb_committed_space);
+ return sprintf(buf, "HugeCommited_AS: %5lu\n", htlb);
+}
+
static struct super_operations hugetlbfs_ops;
static struct address_space_operations hugetlbfs_aops;
struct file_operations hugetlbfs_file_operations;
@@ -200,6 +219,7 @@ static void hugetlbfs_delete_inode(struc

if (inode->i_data.nrpages)
truncate_hugepages(&inode->i_data, 0);
+ hugetlb_acct_memory(-(inode->i_size / PAGE_SIZE));

security_inode_delete(inode);

@@ -231,6 +251,8 @@ static void hugetlbfs_forget_inode(struc
return;
}

+ hugetlb_acct_memory(-(inode->i_size / PAGE_SIZE));
+
/* write_inode_now() ? */
inodes_stat.nr_unused--;
hlist_del_init(&inode->i_hash);
@@ -241,6 +263,7 @@ out_truncate:
spin_unlock(&inode_lock);
if (inode->i_data.nrpages)
truncate_hugepages(&inode->i_data, 0);
+ hugetlb_acct_memory(-(inode->i_size / PAGE_SIZE));

if (sbinfo->free_inodes >= 0) {
spin_lock(&sbinfo->stat_lock);
@@ -350,6 +373,10 @@ static int hugetlbfs_setattr(struct dent
error = hugetlb_vmtruncate(inode, attr->ia_size);
if (error)
goto out;
+ /* We rely on the fact that the sizes are hugepage aligned,
+ * and that hugetlb_vmtruncate prevents extend. */
+ hugetlb_acct_memory((attr->ia_size - i_size_read(inode)) /
+ PAGE_SIZE);
attr->ia_valid &= ~ATTR_SIZE;
}
error = inode_setattr(inode, attr);
@@ -710,8 +737,9 @@ struct file *hugetlb_zero_setup(size_t s
if (!capable(CAP_IPC_LOCK))
return ERR_PTR(-EPERM);

- if (!is_hugepage_mem_enough(size))
- return ERR_PTR(-ENOMEM);
+ error = hugetlb_acct_memory(size / PAGE_SIZE);
+ if (error)
+ return ERR_PTR(error);

root = hugetlbfs_vfsmount->mnt_root;
snprintf(buf, 16, "%lu", hugetlbfs_counter());
diff -X /home/apw/lib/vdiff.excl -rupN reference/fs/proc/proc_misc.c current/fs/proc/proc_misc.c
--- reference/fs/proc/proc_misc.c 2004-03-29 12:10:18.000000000 +0100
+++ current/fs/proc/proc_misc.c 2004-03-29 13:27:04.000000000 +0100
@@ -232,6 +232,7 @@ static int meminfo_read_proc(char *page,
);

len += hugetlb_report_meminfo(page + len);
+ len += hugetlbfs_report_meminfo(page + len);

return proc_calc_metrics(page, start, off, count, eof, len);
#undef K
diff -X /home/apw/lib/vdiff.excl -rupN reference/include/linux/hugetlb.h current/include/linux/hugetlb.h
--- reference/include/linux/hugetlb.h 2004-03-29 12:10:22.000000000 +0100
+++ current/include/linux/hugetlb.h 2004-03-29 13:22:38.000000000 +0100
@@ -115,11 +115,14 @@ static inline void set_file_hugepages(st
{
file->f_op = &hugetlbfs_file_operations;
}
+int hugetlbfs_report_meminfo(char *);
+
#else /* !CONFIG_HUGETLBFS */

#define is_file_hugepages(file) 0
#define set_file_hugepages(file) BUG()
#define hugetlb_zero_setup(size) ERR_PTR(-ENOSYS)
+#define hugetlbfs_report_meminfo(buf) 0

#endif /* !CONFIG_HUGETLBFS */