static int pmi_notifier(struct notifier_block *nb, unsigned long event, void *data) { struct cpufreq_policy *policy = data; struct cpufreq_frequency_table *cbe_freqs; u8 node; /* Should this really be called for CPUFREQ_ADJUST, CPUFREQ_INCOMPATIBLE * and CPUFREQ_NOTIFY policy events?) */ if (event == CPUFREQ_START) return 0; cbe_freqs = cpufreq_frequency_get_table(policy->cpu); node = cbe_cpu_to_node(policy->cpu); pr_debug("got notified, event=%lu, node=%u\n", event, node); if (pmi_slow_mode_limit[node] != 0) { pr_debug("limiting node %d to slow mode %d\n", node, pmi_slow_mode_limit[node]); cpufreq_verify_within_limits(policy, 0, cbe_freqs[pmi_slow_mode_limit[node]].frequency); } return 0; }
int cbe_cpufreq_set_pmode_pmi(int cpu, unsigned int pmode) { int ret; pmi_message_t pmi_msg; #ifdef DEBUG long time; #endif pmi_msg.type = PMI_TYPE_FREQ_CHANGE; pmi_msg.data1 = cbe_cpu_to_node(cpu); pmi_msg.data2 = pmode; #ifdef DEBUG time = jiffies; #endif pmi_send_message(pmi_msg); #ifdef DEBUG time = jiffies - time; time = jiffies_to_msecs(time); pr_debug("had to wait %lu ms for a transition using " \ "PMI\n", time); #endif ret = pmi_msg.data2; pr_debug("PMI returned slow mode %d\n", ret); return ret; }
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; }
static int pmi_notifier(struct notifier_block *nb, unsigned long event, void *data) { struct cpufreq_policy *policy = data; struct cpufreq_frequency_table *cbe_freqs; u8 node; cbe_freqs = cpufreq_frequency_get_table(policy->cpu); node = cbe_cpu_to_node(policy->cpu); pr_debug("got notified, event=%lu, node=%u\n", event, node); if (pmi_slow_mode_limit[node] != 0) { pr_debug("limiting node %d to slow mode %d\n", node, pmi_slow_mode_limit[node]); cpufreq_verify_within_limits(policy, 0, cbe_freqs[pmi_slow_mode_limit[node]].frequency); } return 0; }