fix OProfile locking
Subsystems (3)
PATCH 1/1 fix OProfile locking
Below uses get_task_mm() as discussed. It also fixes up Anton's previous patch. Zwane's soaked this patch all night w/o problems.
regards
john
Index: linux-cvs/kernel/fork.c
===================================================================
RCS file: /home/moz/cvs//linux-2.5/kernel/fork.c,v retrieving revision 1.212
kernel/fork.c +2 -0
@@ -483,6 +483,7 @@ void mmput(struct mm_struct *mm)mmdrop (mm); } } +EXPORT_SYMBOL_GPL (mmput);/** * get_task_mm - acquire a reference to the task's mm
@@ -514,6 +515,7 @@ struct mm_struct *get_task_mm(struct tastask_unlock (task);return mm; } +EXPORT_SYMBOL_GPL (get_task_mm);/* Please note the differences between mmput and mm_release. * mmput is called whenever we stop holding onto a mm_struct,
Index: linux-cvs/drivers/oprofile/buffer_sync.c
===================================================================
RCS file: /home/moz/cvs//linux-2.5/drivers/oprofile/buffer_sync.c,v retrieving revision 1.24
drivers/oprofile/buffer_sync.c +11 -26
@@ -133,7 +133,7 @@ static struct notifier_block module_loadstatic void end_sync (void ) { -end_cpu_timers (); +end_cpu_work ();/* make sure we don't leak task structs */ process_task_mortuary ();process_task_mortuary ();
@@ -144,7 +144,7 @@ int sync_start(void) {int err; -start_cpu_timers (); +start_cpu_work (); err =task_handoff_register (&task_free_nb);if (err)
@@ -339,40 +339,25 @@ static void add_sample(struct mm_struct } } - +static void release_mm (struct mm_struct * mm) { -if (mm) -up_read (&mm->mmap_sem); +if (!mm) +return ; +up_read (&mm->mmap_sem); +mmput (mm); } -/* Take the task's mmap_sem to protect ourselves from -* races when we do lookup_dcookie(). -*/ static struct mm_struct *take_tasks_mm (struct task_struct * task) { -struct mm_struct * mm; - -/* Subtle. We don't need to keep a reference to this task's mm, -* because, for the mm to be freed on another CPU, that would have -* to go through the task exit notifier, which ends up sleeping -* on the buffer_sem we hold, so we end up with mutual exclusion -* anyway. -*/ -task_lock (task); - mm = task->mm; -task_unlock (task); - -if (mm) { -/* needed to walk the task's VMAs */ +struct mm_struct * mm =get_task_mm (task); +if (mm)down_read (&mm->mmap_sem); - } -return mm; } - - + +static inline int is_ctx_switch (unsigned long val) {return val == ~0UL ;
Index: linux-cvs/drivers/oprofile/cpu_buffer.c
===================================================================
RCS file: /home/moz/cvs//linux-2.5/drivers/oprofile/cpu_buffer.c,v retrieving revision 1.15
drivers/oprofile/cpu_buffer.c +6 -6
@@ -30,7 +30,7 @@ struct oprofile_cpu_buffer cpu_buffer[NRstatic void wq_sync_buffer (void *);#define DEFAULT_TIMER_EXPIRE (HZ / 10) -int timers_enabled; +int work_enabled;static void __free_cpu_buffers (int num) {
@@ -80,11 +80,11 @@ void free_cpu_buffers(void) } -void start_cpu_timers (void ) +void start_cpu_work (void ) {int i; - timers_enabled =1 ; + work_enabled =1 ;for_each_online_cpu (i) {struct oprofile_cpu_buffer * b = &cpu_buffer[i];
@@ -98,11 +98,11 @@ void start_cpu_timers(void) } -void end_cpu_timers (void ) +void end_cpu_work (void ) {int i; - timers_enabled =0 ; + work_enabled =0 ;for_each_online_cpu (i) {struct oprofile_cpu_buffer * b = &cpu_buffer[i];
@@ -220,6 +220,6 @@ static void wq_sync_buffer(void * data)sync_buffer (b->cpu);/* don't re-add the work if we're shutting down */ -if (timers_enabled) +if (work_enabled)schedule_delayed_work (&b->work,DEFAULT_TIMER_EXPIRE ); }
Index: linux-cvs/drivers/oprofile/cpu_buffer.h
===================================================================
RCS file: /home/moz/cvs//linux-2.5/drivers/oprofile/cpu_buffer.h,v retrieving revision 1.7
drivers/oprofile/cpu_buffer.h +2 -2
@@ -20,8 +20,8 @@ struct task_struct;int alloc_cpu_buffers (void );void free_cpu_buffers (void ); -void start_cpu_timers (void ); -void end_cpu_timers (void ); +void start_cpu_work (void ); +void end_cpu_work (void );/* CPU buffer is composed of such entries (which are * also used for context switch notes)