Re: [PATCH 7/8] IA64 various hugepage size - Add proc control to reserve and free

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Add proc control to reserve and free various sized hugepages

cat /proc/hugetlb/hugepages will show huge pages information

echo "size nr" > /proc/hugetlb/hugepages will modify the page number for size.

e.g 
echo "64k 1000" > /proc/hugetlb/hugepages will allocate 1000 pages of 64k page.

echo "64k 0" > /proc/hugetlb/hugepages will free all the 64k pages

Signed-off-by: Zou Nan hai <[email protected]>


diff -Nraup a/mm/hugetlb.c b/mm/hugetlb.c
--- a/mm/hugetlb.c	2006-04-13 08:36:16.000000000 +0800
+++ b/mm/hugetlb.c	2006-04-13 08:31:38.000000000 +0800
@@ -15,6 +15,9 @@
 #include <linux/cpuset.h>
 #include <linux/mutex.h>
 
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+
 #include <asm/page.h>
 #include <asm/pgtable.h>
 
@@ -259,38 +262,6 @@ void hugetlb_truncate_reservation(struct
 	spin_unlock(&hugetlb_lock);
 }
 
-static int __init hugetlb_init(void)
-{
-	unsigned long i, j;
-
-#ifndef ARCH_HAS_VARIABLE_HUGEPAGE_SIZE
-	if (HPAGE_SHIFT(0) == 0)
-		return 0;
-#endif
-
-	for (i = 0; i < MAX_NUMNODES; ++i)
-		for (j = 0; j < MAX_ORDER; ++j)
-			INIT_LIST_HEAD(&hugepage_freelists[i][j]);
-
-	for (i = 0; i < max_huge_pages; ++i) {
-		if (!alloc_fresh_huge_page(HUGETLB_INIT_PAGE_ORDER))
-			break;
-	}
-	max_huge_pages = free_huge_pages[HUGETLB_INIT_PAGE_ORDER] =
nr_huge_pages[HUGETLB_INIT_PAGE_ORDER] = i;
-	printk("Total HugeTLB memory allocated, %ld\n", 
-		free_huge_pages[HUGETLB_INIT_PAGE_ORDER]);
-	return 0;
-}
-module_init(hugetlb_init);
-
-static int __init hugetlb_setup(char *s)
-{
-	if (sscanf(s, "%lu", &max_huge_pages) <= 0)
-		max_huge_pages = 0;
-	return 1;
-}
-__setup("hugepages=", hugetlb_setup);
-
 #ifdef CONFIG_SYSCTL
 static void update_and_free_page(struct page *page, int order)
 {
@@ -364,8 +335,120 @@ int hugetlb_sysctl_handler(struct ctl_ta
 		HUGETLB_INIT_PAGE_ORDER);
 	return 0;
 }
+#ifdef ARCH_HAS_VARIABLE_HUGEPAGE_SIZE
+static char *
+bitvector_process(char *p, unsigned long vector)
+{
+	int i,j;
+	const char *units[]={ "", "K", "M", "G", "T" };
+
+	for (i=0, j=0; i < 64; i++ , j=i/10) {
+		if (vector & 0x1) {
+			p += sprintf(p, "%d%s ", 1 << (i-j*10), units[j]);
+		}
+		vector >>= 1;
+	}
+	return p;
+}
+
+static int proc_hugetlb_pagesizes_show(struct seq_file *s, void *p)
+{
+	int order;
+	char buf[32];
+	for (order = 0; order < MAX_ORDER; order++) {
+		if (!is_valid_hpage_size(1UL<<(order+PAGE_SHIFT)))
+			continue;
+		bitvector_process(buf, (1UL<<(order+PAGE_SHIFT)));
+		seq_printf(s, "%s\t%ld\t%ld\t%ld\n",
+				buf, nr_huge_pages[order],
+				free_huge_pages[order],
+				reserved_huge_pages[order]);
+	}
+
+	return 0;
+}
+
+static ssize_t proc_hugetlb_pagesizes_write(struct file *file,
+	const char __user *buffer, size_t length, loff_t *ppos)
+{
+	char buf[64];
+	unsigned long nr, order;
+	unsigned long long size;
+	char *rest;
+	if (!buffer || length >= sizeof(buf))
+		return -EINVAL;
+	if (copy_from_user(buf, buffer, length))
+		return -EFAULT;
+	buf[length] = 0;
+
+	size = memparse(buf, &rest);
+	order = __ffs(size) - PAGE_SHIFT;
+	if (order >= MAX_ORDER || !is_valid_hpage_size(size))
+		return -EINVAL;
+	if (sscanf(rest, "%ld", &nr) != 1)
+		return -EINVAL;
+	set_max_huge_pages(nr, order);
+	return length;
+}
+
+static int proc_hugetlb_pagesizes_open(struct inode *inode, struct file
*file)
+{
+	return single_open(file, proc_hugetlb_pagesizes_show, NULL);
+}
+
+static struct file_operations proc_hugetlb_pagesizes_operations = {
+        .open           = proc_hugetlb_pagesizes_open,
+        .read           = seq_read,
+        .write          = proc_hugetlb_pagesizes_write,
+        .llseek         = seq_lseek,
+        .release        = single_release,
+};
+#endif /* ARCH_HAS_VARIABLE_HUGEPAGE_SIZE */
 #endif /* CONFIG_SYSCTL */
 
+static int __init hugetlb_init(void)
+{
+	unsigned long i, j;
+	struct proc_dir_entry *pde;
+
+#ifndef ARCH_HAS_VARIABLE_HUGEPAGE_SIZE
+	if (HPAGE_SHIFT(0) == 0)
+		return 0;
+#endif
+
+	for (i = 0; i < MAX_NUMNODES; ++i)
+		for (j = 0; j < MAX_ORDER; ++j)
+			INIT_LIST_HEAD(&hugepage_freelists[i][j]);
+
+	for (i = 0; i < max_huge_pages; ++i) {
+		if (!alloc_fresh_huge_page(HUGETLB_INIT_PAGE_ORDER))
+			break;
+	}
+	max_huge_pages = free_huge_pages[HUGETLB_INIT_PAGE_ORDER] =
nr_huge_pages[HUGETLB_INIT_PAGE_ORDER] = i;
+	printk("Total HugeTLB memory allocated, %ld\n",
+		free_huge_pages[HUGETLB_INIT_PAGE_ORDER]);
+
+#ifdef ARCH_HAS_VARIABLE_HUGEPAGE_SIZE
+        if (!proc_mkdir("hugetlb", NULL))
+		return 1;
+        pde = create_proc_entry("hugetlb/hugepages", 0, NULL);
+        if (!pde)
+                return 1;
+        pde->proc_fops = &proc_hugetlb_pagesizes_operations;
+#endif
+	return 0;
+}
+module_init(hugetlb_init);
+
+static int __init hugetlb_setup(char *s)
+{
+	if (sscanf(s, "%lu", &max_huge_pages) <= 0)
+		max_huge_pages = 0;
+	return 1;
+}
+__setup("hugepages=", hugetlb_setup);
+
+
 int hugetlb_report_meminfo(char *buf)
 {
 	return sprintf(buf,




-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux