From: Nishanth Aravamudan <nacc@us.ibm.com>
To: Greg KH <gregkh@suse.de>
Cc: Nick Piggin <npiggin@suse.de>,
Christoph Lameter <clameter@sgi.com>,
wli@holomorphy.com, agl@us.ibm.com, luick@cray.com,
Lee.Schermerhorn@hp.com, linux-mm@kvack.org
Subject: Re: [RFC][PATCH] hugetlb: add information and interface in sysfs [Was Re: [RFC][PATCH 4/5] Documentation: add node files to sysfs ABI]
Date: Fri, 2 May 2008 10:58:22 -0700 [thread overview]
Message-ID: <20080502175822.GA9418@us.ibm.com> (raw)
In-Reply-To: <20080501030844.GB4911@suse.de>
On 30.04.2008 [20:08:44 -0700], Greg KH wrote:
> On Wed, Apr 30, 2008 at 12:19:41PM -0700, Nishanth Aravamudan wrote:
> > On 29.04.2008 [11:26:13 -0700], Greg KH wrote:
> > > On Tue, Apr 29, 2008 at 11:14:15AM -0700, Nishanth Aravamudan wrote:
> > > > On 29.04.2008 [10:22:43 -0700], Greg KH wrote:
> > > > > On Tue, Apr 29, 2008 at 10:11:15AM -0700, Nishanth Aravamudan wrote:
> > > > > > +struct hstate_attribute {
> > > > > > + struct attribute attr;
> > > > > > + ssize_t (*show)(struct hstate *h, char *buf);
> > > > > > + ssize_t (*store)(struct hstate *h, const char *buf, size_t count);
> > > > > > +};
> > > > >
> > > > > Do you need your own attribute type with show and store? Can't you just
> > > > > use the "default" kobject attributes?
> > > >
> > > > Hrm, I don't know? Probably. Like I said, I was using the
> > > > /sys/kernel/slab code as my reference. Can you explain this more? Or
> > > > just point me to the source/documentation I should read for info.
> > >
> > > Documentation/kobject.txt, with sample examples in samples/kobject/ for
> > > you to copy and use.
> > >
> > > > Are you referring to kobj_attr_show/kobj_attr_store? Should I just be
> > > > using kobj_sysfs_ops, then, most likely?
> > >
> > > See the above examples for more details.
> > >
> > > > > Also, you have no release function for your kobject to be cleaned up,
> > > > > that's a major bug.
> > > >
> > > > Well, these kobjects never go away? They will be statically initialized
> > > > at boot-time and then stick around until the kernel goes away. Looking
> > > > at /sys/kernel/slab's code, again, the release() function there does a
> > > > kfree() on the containing kmem_cache, but for hugetlb, the hstates are
> > > > static... If we do move to dynamic allocations ever (or allow adding
> > > > hugepage sizes at run-time somehow), then perhaps we'll need a release
> > > > method then?
> > >
> > > Yes you will. Please always create one, what happens when you want to
> > > clean them up at shut-down time...
> >
> > Does this look better? I really appreciate the review, Greg.
>
> See my previous email, you should not embed a kobject into this
> structure. Just use a pointer to one, it will shrink this patch a lot.
Ok, I did that -- and the patch grew (due to adding a helper
function to figure out which hstate a kobject corresponds to?). I'm
sure I'm doing something stupid.
FWIW, this patch does work with Jon's efforts and shows 64k/16m/16g at
run-time, all correct and such.
commit 164d446024a76b9d785b11141e1b53b330f6ce4d
Author: Nishanth Aravamudan <nacc@us.ibm.com>
Date: Fri Apr 25 15:34:58 2008 -0700
hugetlb: present information in sysfs
Signed-off-by: Nishanth Aravamudan <nacc@us.ibm.com>
diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
index 4fe8d16..4898f32 100644
--- a/include/linux/hugetlb.h
+++ b/include/linux/hugetlb.h
@@ -3,6 +3,9 @@
#include <linux/fs.h>
#include <linux/shm.h>
+#include <linux/mempolicy.h>
+#include <asm/tlbflush.h>
+#include <asm/hugetlb.h>
#ifdef CONFIG_HUGETLBFS
struct hugetlbfs_config {
@@ -69,10 +72,6 @@ static inline void set_file_hugepages(struct file *file)
#ifdef CONFIG_HUGETLB_PAGE
-#include <linux/mempolicy.h>
-#include <asm/tlbflush.h>
-#include <asm/hugetlb.h>
-
struct ctl_table;
static inline int is_vm_hugetlb_page(struct vm_area_struct *vma)
@@ -132,6 +131,7 @@ struct hstate {
unsigned int nr_huge_pages_node[MAX_NUMNODES];
unsigned int free_huge_pages_node[MAX_NUMNODES];
unsigned int surplus_huge_pages_node[MAX_NUMNODES];
+ char name[32];
};
struct huge_bm_page {
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index bd07510..c87eeca 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -15,6 +15,7 @@
#include <linux/cpuset.h>
#include <linux/mutex.h>
#include <linux/bootmem.h>
+#include <linux/sysfs.h>
#include <asm/page.h>
#include <asm/pgtable.h>
@@ -659,76 +660,6 @@ static void __init report_hugepages(void)
}
}
-static int __init hugetlb_init(void)
-{
- BUILD_BUG_ON(HPAGE_SHIFT == 0);
-
- if (!size_to_hstate(HPAGE_SIZE)) {
- huge_add_hstate(HUGETLB_PAGE_ORDER);
- parsed_hstate->max_huge_pages = default_hstate_resv;
- }
-
- hugetlb_init_hstates();
-
- gather_bootmem_prealloc();
-
- report_hugepages();
-
- return 0;
-}
-module_init(hugetlb_init);
-
-/* Should be called on processing a hugepagesz=... option */
-void __init huge_add_hstate(unsigned order)
-{
- struct hstate *h;
- if (size_to_hstate(PAGE_SIZE << order)) {
- printk("hugepagesz= specified twice, ignoring\n");
- return;
- }
- BUG_ON(max_hstate >= HUGE_MAX_HSTATE);
- h = &hstates[max_hstate++];
- h->order = order;
- h->mask = ~((1ULL << (order + PAGE_SHIFT)) - 1);
- hugetlb_init_hstate(h);
- parsed_hstate = h;
-}
-
-static int __init hugetlb_setup(char *s)
-{
- unsigned long *mhp;
-
- if (!max_hstate)
- mhp = &default_hstate_resv;
- else
- mhp = &parsed_hstate->max_huge_pages;
-
- if (sscanf(s, "%lu", mhp) <= 0)
- *mhp = 0;
-
- /*
- * Global state is always initialized later in hugetlb_init.
- * But we need to allocate >= MAX_ORDER hstates here early to still
- * use the bootmem allocator.
- */
- if (max_hstate > 0 && parsed_hstate->order >= MAX_ORDER)
- hugetlb_init_hstate(parsed_hstate);
-
- return 1;
-}
-__setup("hugepages=", hugetlb_setup);
-
-static unsigned int cpuset_mems_nr(unsigned int *array)
-{
- int node;
- unsigned int nr = 0;
-
- for_each_node_mask(node, cpuset_current_mems_allowed)
- nr += array[node];
-
- return nr;
-}
-
#ifdef CONFIG_SYSCTL
#ifdef CONFIG_HIGHMEM
static void try_to_free_low(struct hstate *h, unsigned long count)
@@ -839,6 +770,236 @@ out:
return ret;
}
+#ifdef CONFIG_SYSFS
+#define HSTATE_ATTR_RO(_name) \
+ static struct kobj_attribute _name##_attr = __ATTR_RO(_name)
+
+#define HSTATE_ATTR(_name) \
+ static struct kobj_attribute _name##_attr = \
+ __ATTR(_name, 0644, _name##_show, _name##_store)
+
+static struct kobject *hugepages_kobj;
+static struct kobject *hstate_kobjs[HUGE_MAX_HSTATE];
+
+static struct hstate *kobj_to_hstate(struct kobject *kobj)
+{
+ int i;
+ for (i = 0; i < HUGE_MAX_HSTATE; i++)
+ if (hstate_kobjs[i] == kobj)
+ return &hstates[i];
+ BUG();
+ return NULL;
+}
+
+static ssize_t nr_hugepages_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ struct hstate *h = kobj_to_hstate(kobj);
+ return sprintf(buf, "%lu\n", h->nr_huge_pages);
+}
+static ssize_t nr_hugepages_store(struct kobject *kobj,
+ struct kobj_attribute *attr, const char *buf, size_t count)
+{
+ int tmp, err;
+ unsigned long input;
+ struct hstate *h = kobj_to_hstate(kobj);
+
+ err = strict_strtoul(buf, 10, &input);
+ if (err)
+ return 0;
+
+ h->max_huge_pages = set_max_huge_pages(h, input, &tmp);
+ max_huge_pages[h - hstates] = h->max_huge_pages;
+
+ return count;
+}
+HSTATE_ATTR(nr_hugepages);
+
+static ssize_t nr_overcommit_hugepages_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ struct hstate *h = kobj_to_hstate(kobj);
+ return sprintf(buf, "%lu\n", h->nr_overcommit_huge_pages);
+}
+static ssize_t nr_overcommit_hugepages_store(struct kobject *kobj,
+ struct kobj_attribute *attr, const char *buf, size_t count)
+{
+ int err;
+ unsigned long input;
+ struct hstate *h = kobj_to_hstate(kobj);
+
+ err = strict_strtoul(buf, 10, &input);
+ if (err)
+ return 0;
+
+ spin_lock(&hugetlb_lock);
+ h->nr_overcommit_huge_pages = input;
+ sysctl_overcommit_huge_pages[h - hstates] = h->nr_overcommit_huge_pages;
+ spin_unlock(&hugetlb_lock);
+
+ return count;
+}
+HSTATE_ATTR(nr_overcommit_hugepages);
+
+static ssize_t free_hugepages_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ struct hstate *h = kobj_to_hstate(kobj);
+ return sprintf(buf, "%lu\n", h->free_huge_pages);
+}
+HSTATE_ATTR_RO(free_hugepages);
+
+static ssize_t resv_hugepages_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ struct hstate *h = kobj_to_hstate(kobj);
+ return sprintf(buf, "%lu\n", h->resv_huge_pages);
+}
+HSTATE_ATTR_RO(resv_hugepages);
+
+static ssize_t surplus_hugepages_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ struct hstate *h = kobj_to_hstate(kobj);
+ return sprintf(buf, "%lu\n", h->surplus_huge_pages);
+}
+HSTATE_ATTR_RO(surplus_hugepages);
+
+static struct attribute *hstate_attrs[] = {
+ &nr_hugepages_attr.attr,
+ &nr_overcommit_hugepages_attr.attr,
+ &free_hugepages_attr.attr,
+ &resv_hugepages_attr.attr,
+ &surplus_hugepages_attr.attr,
+ NULL,
+};
+
+static struct attribute_group hstate_attr_group = {
+ .attrs = hstate_attrs,
+};
+
+static int __init hugetlb_sysfs_add_hstate(struct hstate *h)
+{
+ int retval;
+
+ hstate_kobjs[h - hstates] = kobject_create_and_add(h->name, hugepages_kobj);
+ if (!hstate_kobjs[h - hstates])
+ return -ENOMEM;
+
+ retval = sysfs_create_group(hstate_kobjs[h - hstates], &hstate_attr_group);
+ if (retval)
+ kobject_put(hstate_kobjs[h - hstates]);
+
+ return retval;
+}
+
+static void __init hugetlb_sysfs_init(void)
+{
+ struct hstate *h;
+ int err;
+
+ hugepages_kobj = kobject_create_and_add("hugepages", kernel_kobj);
+ if (!hugepages_kobj)
+ return;
+
+ for_each_hstate(h) {
+ err = hugetlb_sysfs_add_hstate(h);
+ if (err)
+ printk(KERN_ERR "Hugetlb: Unable to add hstate %s",
+ h->name);
+ }
+}
+#else
+static void __init hugetlb_sysfs_init(void)
+{
+}
+#endif
+
+static int __init hugetlb_init(void)
+{
+ BUILD_BUG_ON(HPAGE_SHIFT == 0);
+
+ if (!size_to_hstate(HPAGE_SIZE)) {
+ huge_add_hstate(HUGETLB_PAGE_ORDER);
+ parsed_hstate->max_huge_pages = default_hstate_resv;
+ }
+
+ hugetlb_init_hstates();
+
+ gather_bootmem_prealloc();
+
+ report_hugepages();
+
+ hugetlb_sysfs_init();
+
+ return 0;
+}
+module_init(hugetlb_init);
+
+static void __exit hugetlb_exit(void)
+{
+ struct hstate *h;
+
+ for_each_hstate(h)
+ kobject_put(hstate_kobjs[h - hstates]);
+
+ kobject_put(hugepages_kobj);
+}
+module_exit(hugetlb_exit);
+
+/* Should be called on processing a hugepagesz=... option */
+void __init huge_add_hstate(unsigned order)
+{
+ struct hstate *h;
+ if (size_to_hstate(PAGE_SIZE << order)) {
+ printk("hugepagesz= specified twice, ignoring\n");
+ return;
+ }
+ BUG_ON(max_hstate >= HUGE_MAX_HSTATE);
+ h = &hstates[max_hstate++];
+ h->order = order;
+ h->mask = ~((1ULL << (order + PAGE_SHIFT)) - 1);
+ snprintf(h->name, 32, "hugepages-%lu", huge_page_size(h)/1024);
+ hugetlb_init_hstate(h);
+ parsed_hstate = h;
+}
+
+static int __init hugetlb_setup(char *s)
+{
+ unsigned long *mhp;
+
+ if (!max_hstate)
+ mhp = &default_hstate_resv;
+ else
+ mhp = &parsed_hstate->max_huge_pages;
+
+ if (sscanf(s, "%lu", mhp) <= 0)
+ *mhp = 0;
+
+ /*
+ * Global state is always initialized later in hugetlb_init.
+ * But we need to allocate >= MAX_ORDER hstates here early to still
+ * use the bootmem allocator.
+ */
+ if (max_hstate > 0 && parsed_hstate->order >= MAX_ORDER)
+ hugetlb_init_hstate(parsed_hstate);
+
+ return 1;
+}
+__setup("hugepages=", hugetlb_setup);
+
+static unsigned int cpuset_mems_nr(unsigned int *array)
+{
+ int node;
+ unsigned int nr = 0;
+
+ for_each_node_mask(node, cpuset_current_mems_allowed)
+ nr += array[node];
+
+ return nr;
+}
+
+
int hugetlb_sysctl_handler(struct ctl_table *table, int write,
struct file *file, void __user *buffer,
size_t *length, loff_t *ppos)
--
Nishanth Aravamudan <nacc@us.ibm.com>
IBM Linux Technology Center
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
next prev parent reply other threads:[~2008-05-02 17:58 UTC|newest]
Thread overview: 51+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-04-11 23:44 [PATCH 1/5] hugetlb: numafy several functions Nishanth Aravamudan
2008-04-11 23:47 ` [RFC][PATCH 2/5] " Nishanth Aravamudan
2008-04-11 23:47 ` [PATCH 3/5] hugetlb: interleave dequeueing of huge pages Nishanth Aravamudan
2008-04-11 23:49 ` [RFC][PATCH 4/5] Documentation: add node files to sysfs ABI Nishanth Aravamudan
2008-04-11 23:50 ` [RFC][PATCH 5/5] Documentation: update ABI and hugetlbpage.txt for per-node files Nishanth Aravamudan
2008-04-11 23:56 ` [RFC][PATCH 4/5] Documentation: add node files to sysfs ABI Greg KH
2008-04-12 0:27 ` Nishanth Aravamudan
2008-04-12 9:41 ` Nick Piggin
2008-04-12 10:26 ` Christoph Lameter
2008-04-14 21:09 ` Nishanth Aravamudan
2008-04-13 3:41 ` Greg KH
2008-04-14 21:05 ` Nishanth Aravamudan
2008-04-17 23:16 ` Nishanth Aravamudan
2008-04-17 23:22 ` Christoph Lameter
2008-04-17 23:36 ` Nishanth Aravamudan
2008-04-17 23:39 ` Christoph Lameter
2008-04-18 6:04 ` Nishanth Aravamudan
2008-04-18 17:27 ` Nishanth Aravamudan
2008-04-20 2:24 ` Greg KH
2008-04-21 16:43 ` Nishanth Aravamudan
2008-04-20 2:21 ` Greg KH
2008-04-21 6:06 ` Christoph Lameter
2008-04-21 16:41 ` Nishanth Aravamudan
2008-04-22 5:14 ` Nick Piggin
2008-04-22 16:56 ` Nishanth Aravamudan
2008-04-23 1:03 ` Nick Piggin
2008-04-23 18:32 ` Nishanth Aravamudan
2008-04-23 19:07 ` Adam Litke
2008-04-24 7:13 ` Nick Piggin
2008-04-24 15:54 ` Nishanth Aravamudan
2008-04-27 3:49 ` [RFC][PATCH] hugetlb: add information and interface in sysfs [Was Re: [RFC][PATCH 4/5] Documentation: add node files to sysfs ABI] Nishanth Aravamudan
2008-04-27 5:10 ` Greg KH
2008-04-28 17:22 ` Nishanth Aravamudan
2008-04-28 17:29 ` Greg KH
2008-04-29 17:11 ` Nishanth Aravamudan
2008-04-29 17:22 ` Greg KH
2008-04-29 18:14 ` Nishanth Aravamudan
2008-04-29 18:26 ` Greg KH
2008-04-29 23:48 ` Nishanth Aravamudan
2008-05-01 3:07 ` Greg KH
2008-05-01 18:25 ` Nishanth Aravamudan
2008-04-30 19:19 ` Nishanth Aravamudan
2008-05-01 3:08 ` Greg KH
2008-05-02 17:58 ` Nishanth Aravamudan [this message]
2008-04-28 20:31 ` Christoph Lameter
2008-04-28 20:52 ` Nishanth Aravamudan
2008-04-28 21:29 ` Christoph Lameter
2008-04-29 16:43 ` Nishanth Aravamudan
2008-04-29 17:01 ` Christoph Lameter
2008-04-14 14:52 ` [RFC][PATCH 2/5] hugetlb: numafy several functions Adam Litke
2008-04-14 21:10 ` Nishanth Aravamudan
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20080502175822.GA9418@us.ibm.com \
--to=nacc@us.ibm.com \
--cc=Lee.Schermerhorn@hp.com \
--cc=agl@us.ibm.com \
--cc=clameter@sgi.com \
--cc=gregkh@suse.de \
--cc=linux-mm@kvack.org \
--cc=luick@cray.com \
--cc=npiggin@suse.de \
--cc=wli@holomorphy.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.