profiling: Implement a simple task exit notifier when disabled

Some kernel code currently depends on the profiling subsystem solely for
its task exit notifier. The rest of the profiling subsystem is left
unused.

Add a simple task exit notifier implemented in kernel/exit.c to make
such code work properly even when profiling is disabled. This will allow
unnecessary profiling code to be disabled without breakage.

Signed-off-by: Danny Lin <danny@kdrag0n.dev>
This commit is contained in:
Danny Lin 2019-04-07 23:34:36 -07:00 committed by spakkkk
parent c03e3c60c3
commit c4200b8164
2 changed files with 32 additions and 17 deletions

View File

@ -67,9 +67,6 @@ static inline void profile_hit(int type, void *ip)
struct task_struct;
struct mm_struct;
/* task is in do_exit() */
void profile_task_exit(struct task_struct * task);
/* task is dead, free task struct ? Returns 1 if
* the task was taken, 0 if the task should be freed.
*/
@ -81,9 +78,6 @@ void profile_munmap(unsigned long addr);
int task_handoff_register(struct notifier_block * n);
int task_handoff_unregister(struct notifier_block * n);
int profile_event_register(enum profile_type, struct notifier_block * n);
int profile_event_unregister(enum profile_type, struct notifier_block * n);
struct pt_regs;
#else
@ -120,20 +114,15 @@ static inline int task_handoff_unregister(struct notifier_block * n)
return -ENOSYS;
}
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_task_exit(a) do { } while (0)
#define profile_handoff_task(a) (0)
#define profile_munmap(a) do { } while (0)
#endif /* CONFIG_PROFILING */
/* task is in do_exit() */
void profile_task_exit(struct task_struct * task);
int profile_event_register(enum profile_type, struct notifier_block * n);
int profile_event_unregister(enum profile_type, struct notifier_block * n);
#endif /* _LINUX_PROFILE_H */

View File

@ -776,6 +776,32 @@ static void check_stack_usage(void)
static inline void check_stack_usage(void) {}
#endif
#ifndef CONFIG_PROFILING
static BLOCKING_NOTIFIER_HEAD(task_exit_notifier);
int profile_event_register(enum profile_type t, struct notifier_block *n)
{
if (t == PROFILE_TASK_EXIT)
return blocking_notifier_chain_register(&task_exit_notifier, n);
return -ENOSYS;
}
int profile_event_unregister(enum profile_type t, struct notifier_block *n)
{
if (t == PROFILE_TASK_EXIT)
return blocking_notifier_chain_unregister(&task_exit_notifier,
n);
return -ENOSYS;
}
void profile_task_exit(struct task_struct *tsk)
{
blocking_notifier_call_chain(&task_exit_notifier, 0, tsk);
}
#endif
void __noreturn do_exit(long code)
{
struct task_struct *tsk = current;