Login
[x]
Log in using an account from:
Fedora Account System
Red Hat Associate
Red Hat Customer
Or login using a Red Hat Bugzilla account
Forgot Password
Login:
Hide Forgot
Create an Account
Red Hat Bugzilla – Attachment 148864 Details for
Bug 215407
Add smaps functionality to RHEL-4
[?]
New
Simple Search
Advanced Search
My Links
Browse
Requests
Reports
Current State
Search
Tabular reports
Graphical reports
Duplicates
Other Reports
User Changes
Plotly Reports
Bug Status
Bug Severity
Non-Defaults
|
Product Dashboard
Help
Page Help!
Bug Writing Guidelines
What's new
Browser Support Policy
5.0.4.rh83 Release notes
FAQ
Guides index
User guide
Web Services
Contact
Legal
This site requires JavaScript to be enabled to function correctly, please enable it.
[patch]
Fifth take of the smaps patch
linux-2.6.9-smaps-5.patch (text/plain), 11.02 KB, created by
Chris Lalancette
on 2007-02-27 14:48:17 UTC
(
hide
)
Description:
Fifth take of the smaps patch
Filename:
MIME Type:
Creator:
Chris Lalancette
Created:
2007-02-27 14:48:17 UTC
Size:
11.02 KB
patch
obsolete
>diff -urp linux-2.6.9.orig/Documentation/filesystems/proc.txt linux-2.6.9/Documentation/filesystems/proc.txt >--- linux-2.6.9.orig/Documentation/filesystems/proc.txt 2006-12-06 13:58:52.000000000 -0500 >+++ linux-2.6.9/Documentation/filesystems/proc.txt 2006-12-06 13:59:34.000000000 -0500 >@@ -133,6 +133,7 @@ Table 1-1: Process specific entries in / > statm Process memory status information > status Process status in human readable form > wchan If CONFIG_KALLSYMS is set, a pre-decoded wchan >+ smaps Extension based on maps, presenting the rss size for each mapped file > .............................................................................. > > For example, to get the status information of a process, all you have to do is >diff -urp linux-2.6.9.orig/fs/proc/base.c linux-2.6.9/fs/proc/base.c >--- linux-2.6.9.orig/fs/proc/base.c 2006-12-06 13:58:52.000000000 -0500 >+++ linux-2.6.9/fs/proc/base.c 2006-12-06 14:03:04.000000000 -0500 >@@ -11,6 +11,40 @@ > * go into icache. We cache the reference to task_struct upon lookup too. > * Eventually it should become a filesystem in its own. We don't use the > * rest of procfs anymore. >+ * >+ * >+ * Changelog: >+ * 17-Jan-2005 >+ * Allan Bezerra >+ * Bruna Moreira <bruna.moreira@indt.org.br> >+ * Edjard Mota <edjard.mota@indt.org.br> >+ * Ilias Biris <ilias.biris@indt.org.br> >+ * Mauricio Lin <mauricio.lin@indt.org.br> >+ * >+ * Embedded Linux Lab - 10LE Instituto Nokia de Tecnologia - INdT >+ * >+ * A new process specific entry (smaps) included in /proc. It shows the >+ * size of rss for each memory area. The maps entry lacks information >+ * about physical memory size (rss) for each mapped file, i.e., >+ * rss information for executables and library files. >+ * This additional information is useful for any tools that need to know >+ * about physical memory consumption for a process specific library. >+ * >+ * Changelog: >+ * 21-Feb-2005 >+ * Embedded Linux Lab - 10LE Instituto Nokia de Tecnologia - INdT >+ * Pud inclusion in the page table walking. >+ * >+ * ChangeLog: >+ * 10-Mar-2005 >+ * 10LE Instituto Nokia de Tecnologia - INdT: >+ * A better way to walks through the page table as suggested by Hugh Dickins. >+ * >+ * Simo Piiroinen <simo.piiroinen@nokia.com>: >+ * Smaps information related to shared, private, clean and dirty pages. >+ * >+ * Paul Mundt <paul.mundt@nokia.com>: >+ * Overall revision about smaps. > */ > > #include <asm/uaccess.h> >@@ -62,6 +96,9 @@ enum pid_directory_inos { > PROC_TGID_MOUNTS, > PROC_TGID_MOUNTSTATS, > PROC_TGID_WCHAN, >+#ifdef CONFIG_MMU >+ PROC_TGID_SMAPS, >+#endif > #ifdef CONFIG_SCHEDSTATS > PROC_TGID_SCHEDSTAT, > #endif >@@ -92,6 +129,9 @@ enum pid_directory_inos { > PROC_TID_MOUNTS, > PROC_TID_MOUNTSTATS, > PROC_TID_WCHAN, >+#ifdef CONFIG_MMU >+ PROC_TID_SMAPS, >+#endif > #ifdef CONFIG_SCHEDSTATS > PROC_TID_SCHEDSTAT, > #endif >@@ -133,6 +173,9 @@ static struct pid_entry tgid_base_stuff[ > E(PROC_TGID_EXE, "exe", S_IFLNK|S_IRWXUGO), > E(PROC_TGID_MOUNTS, "mounts", S_IFREG|S_IRUGO), > E(PROC_TGID_MOUNTSTATS, "mountstats", S_IFREG|S_IRUSR), >+#ifdef CONFIG_MMU >+ E(PROC_TGID_SMAPS, "smaps", S_IFREG|S_IRUSR), >+#endif > #ifdef CONFIG_SECURITY > E(PROC_TGID_ATTR, "attr", S_IFDIR|S_IRUGO|S_IXUGO), > #endif >@@ -161,6 +204,9 @@ static struct pid_entry tid_base_stuff[] > E(PROC_TID_ROOT, "root", S_IFLNK|S_IRWXUGO), > E(PROC_TID_EXE, "exe", S_IFLNK|S_IRWXUGO), > E(PROC_TID_MOUNTS, "mounts", S_IFREG|S_IRUGO), >+#ifdef CONFIG_MMU >+ E(PROC_TID_SMAPS, "smaps", S_IFREG|S_IRUSR), >+#endif > #ifdef CONFIG_SECURITY > E(PROC_TID_ATTR, "attr", S_IFDIR|S_IRUGO|S_IXUGO), > #endif >@@ -528,6 +574,36 @@ static struct file_operations proc_maps_ > .release = seq_release_private, > }; > >+#ifdef CONFIG_MMU >+extern struct seq_operations proc_pid_smaps_op; >+static int smaps_open(struct inode *inode, struct file *file) >+{ >+ struct proc_maps_private *priv; >+ struct task_struct *task = proc_task(inode); >+ int ret = -ENOMEM; >+ >+ priv = kzalloc(sizeof(*priv), GFP_KERNEL); >+ if (priv) { >+ ret = seq_open(file, &proc_pid_smaps_op); >+ if (!ret) { >+ struct seq_file *m = file->private_data; >+ priv->task = task; >+ m->private = priv; >+ } else { >+ kfree(priv); >+ } >+ } >+ return ret; >+} >+ >+static struct file_operations proc_smaps_operations = { >+ .open = smaps_open, >+ .read = seq_read, >+ .llseek = seq_lseek, >+ .release = seq_release_private, >+}; >+#endif >+ > extern struct seq_operations mounts_op; > static int mounts_open(struct inode *inode, struct file *file) > { >@@ -1477,6 +1553,12 @@ static struct dentry *proc_pident_lookup > case PROC_TGID_MOUNTSTATS: > inode->i_fop = &proc_mountstats_operations; > break; >+#ifdef CONFIG_MMU >+ case PROC_TID_SMAPS: >+ case PROC_TGID_SMAPS: >+ inode->i_fop = &proc_smaps_operations; >+ break; >+#endif > #ifdef CONFIG_SECURITY > case PROC_TID_ATTR: > inode->i_nlink = 2; >diff -urp linux-2.6.9.orig/fs/proc/task_mmu.c linux-2.6.9/fs/proc/task_mmu.c >--- linux-2.6.9.orig/fs/proc/task_mmu.c 2006-12-06 13:58:52.000000000 -0500 >+++ linux-2.6.9/fs/proc/task_mmu.c 2006-12-06 13:59:34.000000000 -0500 >@@ -2,6 +2,7 @@ > #include <linux/hugetlb.h> > #include <linux/seq_file.h> > #include <linux/proc_fs.h> >+#include <linux/highmem.h> > #include <asm/elf.h> > #include <asm/uaccess.h> > >@@ -96,6 +97,112 @@ static int show_map(struct seq_file *m, > return 0; > } > >+struct mem_size_stats >+{ >+ unsigned long resident; >+ unsigned long shared_clean; >+ unsigned long shared_dirty; >+ unsigned long private_clean; >+ unsigned long private_dirty; >+}; >+ >+static void smaps_pte_range(struct vm_area_struct *vma, pmd_t *pmd, >+ unsigned long addr, unsigned long end, >+ struct mem_size_stats *mss) >+{ >+ pte_t *pte, ptent; >+ unsigned long pfn; >+ struct page *page; >+ >+ pte = pte_offset_map(pmd, addr); >+ do { >+ ptent = *pte; >+ if (pte_none(ptent) || !pte_present(ptent)) >+ continue; >+ >+ mss->resident += PAGE_SIZE; >+ pfn = pte_pfn(ptent); >+ if (!pfn_valid(pfn)) >+ continue; >+ >+ page = pfn_to_page(pfn); >+ if (page_count(page) >= 2) { >+ if (pte_dirty(ptent)) >+ mss->shared_dirty += PAGE_SIZE; >+ else >+ mss->shared_clean += PAGE_SIZE; >+ } else { >+ if (pte_dirty(ptent)) >+ mss->private_dirty += PAGE_SIZE; >+ else >+ mss->private_clean += PAGE_SIZE; >+ } >+ } while (pte++, addr += PAGE_SIZE, addr != end); >+ pte_unmap(pte - 1); >+ cond_resched(); >+} >+ >+static inline void smaps_pmd_range(struct vm_area_struct *vma, pgd_t *pgd, >+ unsigned long addr, unsigned long end, >+ struct mem_size_stats *mss) >+{ >+ pmd_t *pmd; >+ unsigned long next; >+ >+ pmd = pmd_offset(pgd, addr); >+ do { >+ next = pmd_addr_end(addr, end); >+ if (pmd_none_or_clear_bad(pmd)) >+ continue; >+ smaps_pte_range(vma, pmd, addr, next, mss); >+ } while (pmd++, addr = next, addr != end); >+} >+ >+static inline void smaps_pgd_range(struct vm_area_struct *vma, >+ unsigned long addr, unsigned long end, >+ struct mem_size_stats *mss) >+{ >+ pgd_t *pgd; >+ unsigned long next; >+ >+ pgd = pgd_offset(vma->vm_mm, addr); >+ do { >+ next = pgd_addr_end(addr, end); >+ if (pgd_none_or_clear_bad(pgd)) >+ continue; >+ smaps_pmd_range(vma, pgd, addr, next, mss); >+ } while (pgd++, addr = next, addr != end); >+} >+ >+static int show_smap(struct seq_file *m, void *v) >+{ >+ struct vm_area_struct *vma = v; >+ unsigned long vma_len = (vma->vm_end - vma->vm_start); >+ struct mem_size_stats mss; >+ >+ memset(&mss, 0, sizeof mss); >+ >+ show_map(m, v); >+ >+ if (vma->vm_mm && !is_vm_hugetlb_page(vma)) >+ smaps_pgd_range(vma, vma->vm_start, vma->vm_end, &mss); >+ >+ seq_printf(m, >+ "Size: %8lu kB\n" >+ "Rss: %8lu kB\n" >+ "Shared_Clean: %8lu kB\n" >+ "Shared_Dirty: %8lu kB\n" >+ "Private_Clean: %8lu kB\n" >+ "Private_Dirty: %8lu kB\n", >+ vma_len >> 10, >+ mss.resident >> 10, >+ mss.shared_clean >> 10, >+ mss.shared_dirty >> 10, >+ mss.private_clean >> 10, >+ mss.private_dirty >> 10); >+ return 0; >+} >+ > static void *m_start(struct seq_file *m, loff_t *pos) > { > struct proc_maps_private *priv = m->private; >@@ -164,6 +271,13 @@ struct seq_operations proc_pid_maps_op = > .show = show_map > }; > >+struct seq_operations proc_pid_smaps_op = { >+ .start = m_start, >+ .next = m_next, >+ .stop = m_stop, >+ .show = show_smap >+}; >+ > struct mm_struct *mm_for_maps(struct task_struct *task) > { > struct mm_struct *mm = get_task_mm(task); >diff -urp linux-2.6.9.orig/include/asm-generic/pgtable.h linux-2.6.9/include/asm-generic/pgtable.h >--- linux-2.6.9.orig/include/asm-generic/pgtable.h 2006-12-06 13:58:47.000000000 -0500 >+++ linux-2.6.9/include/asm-generic/pgtable.h 2006-12-06 13:59:34.000000000 -0500 >@@ -137,4 +137,56 @@ static inline void ptep_mkdirty(pte_t *p > #ifndef __HAVE_ARCH_LAZY_MMU_UPDATE > #define lazy_mmu_prot_update(pte) do { } while (0) > #endif >+ >+/* >+ * When walking page tables, get the address of the next boundary, >+ * or the end address of the range if that comes earlier. Although no >+ * vma end wraps to 0, rounded up __boundary may wrap to 0 throughout. >+ */ >+ >+#define pgd_addr_end(addr, end) \ >+({ unsigned long __boundary = ((addr) + PGDIR_SIZE) & PGDIR_MASK; \ >+ (__boundary - 1 < (end) - 1)? __boundary: (end); \ >+}) >+ >+#ifndef pmd_addr_end >+#define pmd_addr_end(addr, end) \ >+({ unsigned long __boundary = ((addr) + PMD_SIZE) & PMD_MASK; \ >+ (__boundary - 1 < (end) - 1)? __boundary: (end); \ >+}) >+#endif >+ >+ >+#ifndef __ASSEMBLY__ >+/* >+ * When walking page tables, we usually want to skip any p?d_none entries; >+ * and any p?d_bad entries - reporting the error before resetting to none. >+ * Do the tests inline, but report and clear the bad entry in mm/memory.c. >+ */ >+void pgd_clear_bad(pgd_t *); >+void pmd_clear_bad(pmd_t *); >+ >+static inline int pgd_none_or_clear_bad(pgd_t *pgd) >+{ >+ if (pgd_none(*pgd)) >+ return 1; >+ if (unlikely(pgd_bad(*pgd))) { >+ pgd_clear_bad(pgd); >+ return 1; >+ } >+ return 0; >+} >+ >+static inline int pmd_none_or_clear_bad(pmd_t *pmd) >+{ >+ if (pmd_none(*pmd)) >+ return 1; >+ if (unlikely(pmd_bad(*pmd))) { >+ pmd_clear_bad(pmd); >+ return 1; >+ } >+ return 0; >+} >+#endif /* !__ASSEMBLY__ */ >+ > #endif /* _ASM_GENERIC_PGTABLE_H */ >diff -urp linux-2.6.9.orig/mm/memory.c linux-2.6.9/mm/memory.c >--- linux-2.6.9.orig/mm/memory.c 2006-12-06 13:58:52.000000000 -0500 >+++ linux-2.6.9/mm/memory.c 2006-12-06 13:59:34.000000000 -0500 >@@ -83,6 +83,24 @@ EXPORT_SYMBOL(high_memory); > EXPORT_SYMBOL(vmalloc_earlyreserve); > > /* >+ * If a p?d_bad entry is found while walking page tables, report >+ * the error, before resetting entry to p?d_none. Usually (but >+ * very seldom) called out from the p?d_none_or_clear_bad macros. >+ */ >+ >+void pgd_clear_bad(pgd_t *pgd) >+{ >+ pgd_ERROR(*pgd); >+ pgd_clear(pgd); >+} >+ >+void pmd_clear_bad(pmd_t *pmd) >+{ >+ pmd_ERROR(*pmd); >+ pmd_clear(pmd); >+} >+ >+/* > * We special-case the C-O-W ZERO_PAGE, because it's such > * a common occurrence (no need to read the page to know > * that it's zero - better for the cache and memory subsystem).
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 215407
:
141096
|
142996
| 148864