static void end_sync(void)
{
- end_cpu_timers();
+ end_cpu_work();
/* make sure we don't leak task structs */
process_task_mortuary();
process_task_mortuary();
{
int err;
- start_cpu_timers();
+ start_cpu_work();
err = task_handoff_register(&task_free_nb);
if (err)
}
}
-
+
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;
static void wq_sync_buffer(void *);
#define DEFAULT_TIMER_EXPIRE (HZ / 10)
-int timers_enabled;
+int work_enabled;
static void __free_cpu_buffers(int num)
{
}
-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];
}
-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];
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);
}
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)
mmdrop(mm);
}
}
+EXPORT_SYMBOL_GPL(mmput);
/**
* get_task_mm - acquire a reference to the task's mm
task_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,