Say Y here if you want to reduce the chances of the tree compiling,
and are prepared to dig into driver internals to fix compile errors.
+Profiling support
+CONFIG_PROFILING
+ Say Y here to enable the extended profiling support mechanisms used
+ by profilers such as OProfile.
+
Software Suspend
CONFIG_SOFTWARE_SUSPEND
Enable the possibilty of suspendig machine. It doesn't need APM.
source net/bluetooth/Config.in
+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+ mainmenu_option next_comment
+ comment 'Profiling support'
+ bool 'Profiling support (EXPERIMENTAL)' CONFIG_PROFILING
+ endmenu
+fi
+
mainmenu_option next_comment
comment 'Kernel hacking'
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
--- /dev/null
+#ifndef _LINUX_PROFILE_H
+#define _LINUX_PROFILE_H
+
+#ifdef __KERNEL__
+
+#include <linux/kernel.h>
+#include <linux/config.h>
+#include <linux/init.h>
+#include <asm/errno.h>
+
+enum profile_type {
+ EXIT_TASK,
+ EXIT_MMAP,
+ EXEC_UNMAP
+};
+
+#ifdef CONFIG_PROFILING
+
+struct notifier_block;
+struct task_struct;
+struct mm_struct;
+
+/* task is in do_exit() */
+void profile_exit_task(struct task_struct * task);
+
+/* change of vma mappings */
+void profile_exec_unmap(struct mm_struct * mm);
+
+/* exit of all vmas for a task */
+void profile_exit_mmap(struct mm_struct * mm);
+
+int profile_event_register(enum profile_type, struct notifier_block * n);
+
+int profile_event_unregister(enum profile_type, struct notifier_block * n);
+
+#else
+
+static inline int profile_event_register(enum profile_type t, struct notifier_block * n)
+{
+ return -ENOSYS;
+}
+
+static inline int profile_event_unregister(enum profile_type t, struct notifier_block * n)
+{
+ return -ENOSYS;
+}
+
+#define profile_exit_task(a) do { } while (0)
+#define profile_exec_unmap(a) do { } while (0)
+#define profile_exit_mmap(a) do { } while (0)
+
+#endif /* CONFIG_PROFILING */
+
+#endif /* __KERNEL__ */
+
+#endif /* _LINUX_PROFILE_H */
#
export-objs = signal.o sys.o kmod.o workqueue.o ksyms.o pm.o exec_domain.o \
- printk.o platform.o suspend.o dma.o module.o cpufreq.o
+ printk.o platform.o suspend.o dma.o module.o cpufreq.o \
+ profile.o
-obj-y = sched.o fork.o exec_domain.o panic.o printk.o \
+obj-y = sched.o fork.o exec_domain.o panic.o printk.o profile.o \
module.o exit.o itimer.o time.o softirq.o resource.o \
sysctl.o capability.o ptrace.o timer.o user.o \
signal.o sys.o kmod.o workqueue.o futex.o platform.o pid.o
#include <linux/file.h>
#include <linux/binfmts.h>
#include <linux/ptrace.h>
+#include <linux/profile.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
{
struct dentry *proc_dentry;
task_t *leader;
-
- if (p->state < TASK_ZOMBIE)
- BUG();
+
+ BUG_ON(p->state < TASK_ZOMBIE);
+
if (p != current)
wait_task_inactive(p);
+
atomic_dec(&p->user->processes);
security_ops->task_free_security(p);
free_uid(p->user);
current->comm, current->pid,
preempt_count());
+ profile_exit_task(tsk);
+
fake_volatile:
acct_process(code);
__exit_mm(tsk);
--- /dev/null
+/*
+ * linux/kernel/profile.c
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/profile.h>
+#include <linux/bootmem.h>
+#include <linux/notifier.h>
+#include <linux/mm.h>
+
+/* Profile event notifications */
+
+#ifdef CONFIG_PROFILING
+
+static DECLARE_RWSEM(profile_rwsem);
+static struct notifier_block * exit_task_notifier;
+static struct notifier_block * exit_mmap_notifier;
+static struct notifier_block * exec_unmap_notifier;
+
+void profile_exit_task(struct task_struct * task)
+{
+ down_read(&profile_rwsem);
+ notifier_call_chain(&exit_task_notifier, 0, task);
+ up_read(&profile_rwsem);
+}
+
+void profile_exit_mmap(struct mm_struct * mm)
+{
+ down_read(&profile_rwsem);
+ notifier_call_chain(&exit_mmap_notifier, 0, mm);
+ up_read(&profile_rwsem);
+}
+
+void profile_exec_unmap(struct mm_struct * mm)
+{
+ down_read(&profile_rwsem);
+ notifier_call_chain(&exec_unmap_notifier, 0, mm);
+ up_read(&profile_rwsem);
+}
+
+int profile_event_register(enum profile_type type, struct notifier_block * n)
+{
+ int err = -EINVAL;
+
+ down_write(&profile_rwsem);
+
+ switch (type) {
+ case EXIT_TASK:
+ err = notifier_chain_register(&exit_task_notifier, n);
+ break;
+ case EXIT_MMAP:
+ err = notifier_chain_register(&exit_mmap_notifier, n);
+ break;
+ case EXEC_UNMAP:
+ err = notifier_chain_register(&exec_unmap_notifier, n);
+ break;
+ }
+
+ up_write(&profile_rwsem);
+
+ return err;
+}
+
+
+int profile_event_unregister(enum profile_type type, struct notifier_block * n)
+{
+ int err = -EINVAL;
+
+ down_write(&profile_rwsem);
+
+ switch (type) {
+ case EXIT_TASK:
+ err = notifier_chain_unregister(&exit_task_notifier, n);
+ break;
+ case EXIT_MMAP:
+ err = notifier_chain_unregister(&exit_mmap_notifier, n);
+ break;
+ case EXEC_UNMAP:
+ err = notifier_chain_unregister(&exec_unmap_notifier, n);
+ break;
+ }
+
+ up_write(&profile_rwsem);
+ return err;
+}
+
+#endif /* CONFIG_PROFILING */
+
+EXPORT_SYMBOL_GPL(profile_event_register);
+EXPORT_SYMBOL_GPL(profile_event_unregister);
#include <linux/fs.h>
#include <linux/personality.h>
#include <linux/security.h>
+#include <linux/profile.h>
#include <asm/uaccess.h>
#include <asm/pgalloc.h>
if (mpnt->vm_start >= end)
return 0;
+ /* Something will probably happen, so notify. */
+ if (mpnt->vm_file && (mpnt->vm_flags & VM_EXEC))
+ profile_exec_unmap(mm);
+
/*
* If we need to split any vma, do it now to save pain later.
*/
mmu_gather_t *tlb;
struct vm_area_struct * mpnt;
+ profile_exit_mmap(mm);
+
release_segments(mm);
+
spin_lock(&mm->page_table_lock);
tlb = tlb_gather_mmu(mm, 1);