static enum hrtimer_restart profile_spus(struct hrtimer *timer) { ktime_t kt; int cpu, node, k, num_samples, spu_num; if (!spu_prof_running) goto stop; for_each_online_cpu(cpu) { if (cbe_get_hw_thread_id(cpu)) continue; node = cbe_cpu_to_node(cpu); /* There should only be one kernel thread at a time processing * the samples. In the very unlikely case that the processing * is taking a very long time and multiple kernel threads are * started to process the samples. Make sure only one kernel * thread is working on the samples array at a time. The * sample array must be loaded and then processed for a given * cpu. The sample array is not per cpu. */ spin_lock_irqsave(&sample_array_lock, sample_array_lock_flags); num_samples = cell_spu_pc_collection(cpu); if (num_samples == 0) { spin_unlock_irqrestore(&sample_array_lock, sample_array_lock_flags); continue; } for (k = 0; k < SPUS_PER_NODE; k++) { spu_num = k + (node * SPUS_PER_NODE); spu_sync_buffer(spu_num, samples + (k * TRACE_ARRAY_SIZE), num_samples); } spin_unlock_irqrestore(&sample_array_lock, sample_array_lock_flags); } smp_wmb(); /* insure spu event buffer updates are written */ /* don't want events intermingled... */ kt = ktime_set(0, profiling_interval); if (!spu_prof_running) goto stop; hrtimer_forward(timer, timer->base->get_time(), kt); return HRTIMER_RESTART; stop: printk(KERN_INFO "SPU_PROF: spu-prof timer ending\n"); return HRTIMER_NORESTART; }
static enum hrtimer_restart profile_spus(struct hrtimer *timer) { ktime_t kt; int cpu, node, k, num_samples, spu_num; if (!spu_prof_running) goto stop; for_each_online_cpu(cpu) { if (cbe_get_hw_thread_id(cpu)) continue; node = cbe_cpu_to_node(cpu); spin_lock_irqsave(&oprof_spu_smpl_arry_lck, oprof_spu_smpl_arry_lck_flags); num_samples = cell_spu_pc_collection(cpu); if (num_samples == 0) { spin_unlock_irqrestore(&oprof_spu_smpl_arry_lck, oprof_spu_smpl_arry_lck_flags); continue; } for (k = 0; k < SPUS_PER_NODE; k++) { spu_num = k + (node * SPUS_PER_NODE); spu_sync_buffer(spu_num, samples + (k * TRACE_ARRAY_SIZE), num_samples); } spin_unlock_irqrestore(&oprof_spu_smpl_arry_lck, oprof_spu_smpl_arry_lck_flags); } smp_wmb(); /* insure spu event buffer updates are written */ kt = ktime_set(0, profiling_interval); if (!spu_prof_running) goto stop; hrtimer_forward(timer, timer->base->get_time(), kt); return HRTIMER_RESTART; stop: printk(KERN_INFO "SPU_PROF: spu-prof timer ending\n"); return HRTIMER_NORESTART; }