diff options
author | David Smith <dsmith@redhat.com> | 2010-03-16 15:47:36 -0500 |
---|---|---|
committer | David Smith <dsmith@redhat.com> | 2010-03-16 15:47:36 -0500 |
commit | d7c88bfad6ef6188fcbd888bd1235486aa31a5e6 (patch) | |
tree | b5057a0953169e94f5441a99b660f856657762a1 /tapset | |
parent | 1fe5254260d0c3b6438553cf5f4af645820647fe (diff) | |
download | systemtap-steved-d7c88bfad6ef6188fcbd888bd1235486aa31a5e6.tar.gz systemtap-steved-d7c88bfad6ef6188fcbd888bd1235486aa31a5e6.tar.xz systemtap-steved-d7c88bfad6ef6188fcbd888bd1235486aa31a5e6.zip |
Fixed PR 11372 by removing (most) embedded-C from proc_mem.stp.
* tapset/proc_mem.stp: Tried to remove as much embedded-C as possible.
* tapset/atomic.stp: New file.
* testsuite/buildok/atomic.stp: New file.
* testsuite/systemtap.base/atomic.exp: Ditto.
* testsuite/systemtap.base/atomic_module.c: Ditto.
* testsuite/systemtap.base/atomic_module.makefile: Ditto.
Diffstat (limited to 'tapset')
-rw-r--r-- | tapset/atomic.stp | 19 | ||||
-rw-r--r-- | tapset/proc_mem.stp | 285 |
2 files changed, 169 insertions, 135 deletions
diff --git a/tapset/atomic.stp b/tapset/atomic.stp new file mode 100644 index 00000000..d0581455 --- /dev/null +++ b/tapset/atomic.stp @@ -0,0 +1,19 @@ +// Atomic functions. +// Copyright (C) 2010 Red Hat Inc. +// +// This file is part of systemtap, and is free software. You can +// redistribute it and/or modify it under the terms of the GNU General +// Public License (GPL); either version 2, or (at your option) any +// later version. + +function atomic_long_read:long(addr:long) +%{ /* pure */ + atomic_long_t *a = (atomic_long_t *)(long)THIS->addr; + + /* We call deref() here to ensure the memory is valid to read. + * Note the result is thrown away, then we use the "real" + * atomic read function now that we know the address is safe. */ + (void)deref(sizeof(*a), a); + THIS->__retvalue = atomic_long_read(a); + CATCH_DEREF_FAULT(); +%} diff --git a/tapset/proc_mem.stp b/tapset/proc_mem.stp index cebc1550..28bd13a7 100644 --- a/tapset/proc_mem.stp +++ b/tapset/proc_mem.stp @@ -22,56 +22,72 @@ #else #define _STP_PF_KTHREAD PF_KTHREAD #endif - /* Returns the mm for the current proc. Slightly paranoid. Only returns - if the task isn't starting, exiting or (coopted by) a kernel thread. */ - static struct mm_struct *_stp_proc_mm(void) - { - if (current->flags & (_STP_PF_KTHREAD | PF_EXITING | PF_STARTING)) - return NULL; - return current->mm; - } + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34) #include <linux/mm_types.h> -static inline unsigned long k_get_mm_counter(struct mm_struct *mm, int member) -{ -#if USE_SPLIT_PTLOCKS - return (unsigned long)atomic_long_read(&mm->rss_stat.count[member]); #else - return mm->rss_stat.count[member]; -#endif -} +/* Define our own mm types */ +enum { + MM_FILEPAGES, + MM_ANONPAGES +}; #endif %} -function _stp_get_mm_counter_file_rss:long(mm:long) -%(kernel_v >= "2.6.34" %? -%{ /* pure */ /* unprivileged */ - THIS->__retvalue = k_get_mm_counter((struct mm_struct*)(unsigned long)THIS->mm, MM_FILEPAGES); +/* Try to be slightly paranoid. Only returns 1 if the task isn't + starting, exiting or (coopted by) a kernel thread. */ +function _stp_valid_task:long(tsk:long) +%{ + struct task_struct *tsk = (struct task_struct *)(long)THIS->tsk; + + THIS->__retvalue = 0; + if (tsk) { + unsigned int flags = kread(&(tsk->flags)); + + if (flags & ~(_STP_PF_KTHREAD | PF_EXITING | PF_STARTING)) + THIS->__retvalue = 1; + } + CATCH_DEREF_FAULT(); %} -%: + +function _MM_FILEPAGES:long() +%{ /* pure */ /* unprivileged */ + THIS->__retvalue = MM_FILEPAGES; +%} + +function _MM_ANONPAGES:long() +%{ /* pure */ /* unprivileged */ + THIS->__retvalue = MM_ANONPAGES; +%} + +function _stp_get_mm_counter:long(mm:long, member:long) { +%(kernel_v >= "2.6.34" %? %( CONFIG_NR_CPUS >= CONFIG_SPLIT_PTLOCK_CPUS %? - return @cast(mm, "mm_struct", "kernel<linux/sched.h>")->_file_rss->counter; + val = atomic_long_read(&@cast(mm, "mm_struct", "kernel<linux/sched.h>")->rss_stat->count[member]) %: - return @cast(mm, "mm_struct", "kernel<linux/sched.h>")->_file_rss; + val = @cast(mm, "mm_struct", "kernel<linux/sched.h>")->rss_stat->count[member] %) -} -%) - -function _stp_get_mm_counter_anon_rss(mm:long) -%(kernel_v >= "2.6.34" %? -%{ /* pure */ /* unprivileged */ - THIS->__retvalue = k_get_mm_counter((struct mm_struct*)(unsigned long)THIS->mm, MM_ANONPAGES); -%} + if (val < 0) + return 0 +%: /* kernel < 2.6.34 */ + if (member == _MM_FILEPAGES()) { +%( CONFIG_NR_CPUS >= CONFIG_SPLIT_PTLOCK_CPUS %? + val = atomic_long_read(&@cast(mm, "mm_struct", "kernel<linux/sched.h>")->_file_rss) %: -{ + val = @cast(mm, "mm_struct", "kernel<linux/sched.h>")->_file_rss +%) + } + else if (member == _MM_ANONPAGES()) { %( CONFIG_NR_CPUS >= CONFIG_SPLIT_PTLOCK_CPUS %? - return @cast(mm, "mm_struct", "kernel<linux/sched.h>")->_anon_rss->counter; + val = atomic_long_read(&@cast(mm, "mm_struct", "kernel<linux/sched.h>")->_anon_rss) %: - return @cast(mm, "mm_struct", "kernel<linux/sched.h>")->_anon_rss; + val = @cast(mm, "mm_struct", "kernel<linux/sched.h>")->_anon_rss %) -} + } %) + return val +} /** * sfunction proc_mem_size - Total program virtual memory size in pages @@ -81,13 +97,15 @@ function _stp_get_mm_counter_anon_rss(mm:long) * number of pages couldn't be retrieved. */ function proc_mem_size:long () -%{ /* pure */ /* unprivileged */ - struct mm_struct *mm = _stp_proc_mm (); - if (mm) - THIS->__retvalue = mm->total_vm; - else - THIS->__retvalue = 0; -%} +{ + task = task_current() + if (_stp_valid_task(task)) { + mm = @cast(task, "task_struct", "kernel<linux/sched.h>")->mm + if (mm != 0) + return @cast(mm, "mm_struct", "kernel<linux/sched.h>")->total_vm + } + return 0 +} /** * sfunction proc_mem_size_pid - Total program virtual memory size in pages @@ -100,14 +118,13 @@ function proc_mem_size:long () */ function proc_mem_size_pid:long (pid:long) { - task = pid2task(pid); - if (task != 0) - { - mm = @cast(task, "task_struct", "kernel<linux/sched.h>")->mm; - if (mm != 0) - return @cast(mm, "mm_struct", "kernel<linux/sched.h>")->total_vm; - } - return 0; + task = pid2task(pid) + if (_stp_valid_task(task)) { + mm = @cast(task, "task_struct", "kernel<linux/sched.h>")->mm + if (mm != 0) + return @cast(mm, "mm_struct", "kernel<linux/sched.h>")->total_vm + } + return 0 } /** @@ -118,19 +135,16 @@ function proc_mem_size_pid:long (pid:long) * pages couldn't be retrieved. */ function proc_mem_rss:long () -%{ /* pure */ /* unprivileged */ - struct mm_struct *mm = _stp_proc_mm (); - if (mm) -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34) - THIS->__retvalue = k_get_mm_counter(mm, MM_FILEPAGES) - + k_get_mm_counter(mm, MM_ANONPAGES); -#else - THIS->__retvalue = (get_mm_counter(mm, file_rss) - + get_mm_counter(mm, anon_rss)); -#endif - else - THIS->__retvalue = 0; -%} +{ + task = task_current() + if (_stp_valid_task(task)) { + mm = @cast(task, "task_struct", "kernel<linux/sched.h>")->mm + if (mm != 0) + return (_stp_get_mm_counter(mm, _MM_FILEPAGES()) + + _stp_get_mm_counter(mm, _MM_ANONPAGES())) + } + return 0 +} /** * sfunction proc_mem_rss_pid - Program resident set size in pages @@ -143,15 +157,14 @@ function proc_mem_rss:long () */ function proc_mem_rss_pid:long (pid:long) { - task = pid2task(pid); - if (task) - { - mm = @cast(task, "task_struct", "kernel<linux/sched.h>")->mm; - if (mm != 0) - return (_stp_get_mm_counter_file_rss (mm) - + _stp_get_mm_counter_anon_rss (mm)); - } - return 0; + task = pid2task(pid) + if (_stp_valid_task(task)) { + mm = @cast(task, "task_struct", "kernel<linux/sched.h>")->mm + if (mm != 0) + return (_stp_get_mm_counter(mm, _MM_FILEPAGES()) + + _stp_get_mm_counter(mm, _MM_ANONPAGES())) + } + return 0 } /** @@ -162,17 +175,15 @@ function proc_mem_rss_pid:long (pid:long) * number of pages couldn't be retrieved. */ function proc_mem_shr:long () -%{ /* pure */ /* unprivileged */ - struct mm_struct *mm = _stp_proc_mm (); - if (mm) -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34) - THIS->__retvalue = k_get_mm_counter(mm, MM_FILEPAGES); -#else - THIS->__retvalue = get_mm_counter(mm, file_rss); -#endif - else - THIS->__retvalue = 0; -%} +{ + task = task_current() + if (_stp_valid_task(task)) { + mm = @cast(task, "task_struct", "kernel<linux/sched.h>")->mm + if (mm != 0) + return _stp_get_mm_counter(mm, _MM_FILEPAGES()) + } + return 0 +} /** * sfunction proc_mem_shr_pid - Program shared pages (from shared mappings) @@ -185,16 +196,23 @@ function proc_mem_shr:long () */ function proc_mem_shr_pid:long (pid:long) { - task = pid2task(pid); - if (task) - { - mm = @cast(task, "task_struct", "kernel<linux/sched.h>")->mm; - if (mm != 0) - return _stp_get_mm_counter_file_rss (mm); - } - return 0; + task = pid2task(pid) + if (_stp_valid_task(task)) { + mm = @cast(task, "task_struct", "kernel<linux/sched.h>")->mm + if (mm != 0) + return _stp_get_mm_counter(mm, _MM_FILEPAGES()) + } + return 0 } +function _stp_mem_txt_adjust:long (start_code:long, end_code:long) +%{ /* pure */ + unsigned long start_code = (unsigned long) THIS->start_code; + unsigned long end_code = (unsigned long) THIS->end_code; + THIS->__retvalue = (PAGE_ALIGN(end_code) + - (start_code & PAGE_MASK)) >> PAGE_SHIFT; +%} + /** * sfunction proc_mem_txt - Program text (code) size in pages * @@ -203,22 +221,18 @@ function proc_mem_shr_pid:long (pid:long) * couldn't be retrieved. */ function proc_mem_txt:long () -%{ /* pure */ /* unprivileged */ - struct mm_struct *mm = _stp_proc_mm (); - if (mm) - THIS->__retvalue = (PAGE_ALIGN(mm->end_code) - - (mm->start_code & PAGE_MASK)) >> PAGE_SHIFT; - else - THIS->__retvalue = 0; -%} - -function _stp_mem_txt_adjust:long (start_code:long, end_code:long) -%{ /* pure */ - unsigned long start_code = (unsigned long) THIS->start_code; - unsigned long end_code = (unsigned long) THIS->end_code; - THIS->__retvalue = (PAGE_ALIGN(end_code) - - (start_code & PAGE_MASK)) >> PAGE_SHIFT; -%} +{ + task = task_current() + if (_stp_valid_task(task)) { + mm = @cast(task, "task_struct", "kernel<linux/sched.h>")->mm + if (mm != 0) { + s = @cast(mm, "mm_struct", "kernel<linux/sched.h>")->start_code + e = @cast(mm, "mm_struct", "kernel<linux/sched.h>")->end_code + return _stp_mem_txt_adjust(s, e) + } + } + return 0 +} /** * sfunction proc_mem_txt_pid - Program text (code) size in pages @@ -231,18 +245,16 @@ function _stp_mem_txt_adjust:long (start_code:long, end_code:long) */ function proc_mem_txt_pid:long (pid:long) { - task = pid2task(pid); - if (task != 0) - { - mm = @cast(task, "task_struct", "kernel<linux/sched.h>")->mm; - if (mm != 0) - { - s = @cast(mm, "mm_struct", "kernel<linux/sched.h>")->start_code; - e = @cast(mm, "mm_struct", "kernel<linux/sched.h>")->end_code; - return _stp_mem_txt_adjust (s, e); - } + task = pid2task(pid) + if (_stp_valid_task(task)) { + mm = @cast(task, "task_struct", "kernel<linux/sched.h>")->mm + if (mm != 0) { + s = @cast(mm, "mm_struct", "kernel<linux/sched.h>")->start_code + e = @cast(mm, "mm_struct", "kernel<linux/sched.h>")->end_code + return _stp_mem_txt_adjust (s, e) } - return 0; + } + return 0 } /** @@ -253,13 +265,18 @@ function proc_mem_txt_pid:long (pid:long) * pages couldn't be retrieved. */ function proc_mem_data:long () -%{ /* pure */ /* unprivileged */ - struct mm_struct *mm = _stp_proc_mm (); - if (mm) - THIS->__retvalue = mm->total_vm - mm->shared_vm; - else - THIS->__retvalue = 0; -%} +{ + task = task_current() + if (_stp_valid_task(task)) { + mm = @cast(task, "task_struct", "kernel<linux/sched.h>")->mm + if (mm != 0) { + t = @cast(mm, "mm_struct", "kernel<linux/sched.h>")->total_vm + s = @cast(mm, "mm_struct", "kernel<linux/sched.h>")->shared_vm + return (t - s) + } + } + return 0 +} /** * sfunction proc_mem_data_pid - Program data size (data + stack) in pages @@ -272,18 +289,16 @@ function proc_mem_data:long () */ function proc_mem_data_pid:long (pid:long) { - task = pid2task(pid); - if (task != 0) - { - mm = @cast(task, "task_struct", "kernel<linux/sched.h>")->mm; - if (mm != 0) - { - t = @cast(mm, "mm_struct", "kernel<linux/sched.h>")->total_vm; - s = @cast(mm, "mm_struct", "kernel<linux/sched.h>")->shared_vm; - return t - s; - } + task = pid2task(pid) + if (_stp_valid_task(task)) { + mm = @cast(task, "task_struct", "kernel<linux/sched.h>")->mm + if (mm != 0) { + t = @cast(mm, "mm_struct", "kernel<linux/sched.h>")->total_vm + s = @cast(mm, "mm_struct", "kernel<linux/sched.h>")->shared_vm + return t - s } - return 0; + } + return 0 } /** |