lkml.org 
[lkml]   [2002]   [Nov]   [1]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[2.5. PATCH] cpufreq: update HyperThreading support in p4-clockmod.c driver
    This patch updates the p4-clockmod.c driver to correctly manage
    HyperThreading-enabled Pentium IVs as well as those models which do
    not support HyperThreading. Additionally, an EXPORT_SYMBOL was
    missing. (spotted by Marc-Christian Petersen - thanks!)

    Dominik

    diff -ruN linux-2545original/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c linux/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c
    --- linux-2545original/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c Thu Oct 31 12:00:00 2002
    +++ linux/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c Thu Oct 31 20:00:00 2002
    @@ -50,7 +50,6 @@
    MODULE_PARM(stock_freq, "i");

    static struct cpufreq_driver *cpufreq_p4_driver;
    -static unsigned int cpufreq_p4_old_state = 0;


    static int cpufreq_p4_setdc(unsigned int cpu, unsigned int newstate)
    @@ -58,24 +57,50 @@
    u32 l, h;
    unsigned long cpus_allowed;
    struct cpufreq_freqs freqs;
    + int hyperthreading;
    +

    if (!cpu_online(cpu) || (newstate > DC_DISABLE) ||
    (newstate == DC_RESV))
    return -EINVAL;
    - cpu = cpu >> 1; /* physical CPU #nr */
    +
    + /* switch to physical CPU where state is to be changed*/
    + cpus_allowed = current->cpus_allowed;
    +
    + /* hyperthreading? */
    +#ifdef CONFIG_SMP
    + hyperthreading = ((cpu_has_ht) && (smp_num_siblings == 2));
    +#else
    + hyperthreading = 0;
    +#endif
    + if (hyperthreading) {
    + unsigned int phys_cpu = cpu / 2;
    + set_cpus_allowed(current, 3 << (phys_cpu));
    + BUG_ON((cpu & ~1) != (smp_processor_id() & ~1));
    + cpu = phys_cpu * 2;
    + } else {
    + set_cpus_allowed(current, 1 << cpu);
    + BUG_ON(cpu != smp_processor_id());
    + }
    + /* get current state */
    + rdmsr(MSR_IA32_THERM_CONTROL, l, h);
    + l = l >> 1;
    + l &= 0x7;
    +
    + if (l == newstate) {
    + set_cpus_allowed(current, cpus_allowed);
    + return 0;
    + }

    /* notifiers */
    - freqs.old = stock_freq * cpufreq_p4_old_state / 8;
    + freqs.old = stock_freq * l / 8;
    freqs.new = stock_freq * newstate / 8;
    - freqs.cpu = 2*cpu;
    - cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
    - freqs.cpu++;
    + freqs.cpu = cpu;
    cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
    -
    - /* switch to physical CPU where state is to be changed*/
    - cpus_allowed = current->cpus_allowed;
    - set_cpus_allowed(current, 3 << (2 * cpu));
    - BUG_ON(cpu != (smp_processor_id() >> 1));
    + if (hyperthreading) {
    + freqs.cpu++;
    + cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
    + }

    rdmsr(MSR_IA32_THERM_STATUS, l, h);
    if (l & 0x01)
    @@ -86,10 +111,10 @@

    rdmsr(MSR_IA32_THERM_CONTROL, l, h);
    if (newstate == DC_DISABLE) {
    - printk(KERN_INFO PFX "CPU#%d,%d disabling modulation\n", cpu, (cpu + 1));
    + printk(KERN_INFO PFX "CPU#%d disabling modulation\n", cpu);
    wrmsr(MSR_IA32_THERM_CONTROL, l & ~(1<<4), h);
    } else {
    - printk(KERN_INFO PFX "CPU#%d,%d setting duty cycle to %d%%\n", cpu, (cpu + 1), ((125 * newstate) / 10));
    + printk(KERN_INFO PFX "CPU#%d setting duty cycle to %d%%\n", cpu, ((125 * newstate) / 10));
    /* bits 63 - 5 : reserved
    * bit 4 : enable/disable
    * bits 3-1 : duty cycle
    @@ -104,9 +129,10 @@

    /* notifiers */
    cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
    - freqs.cpu--;
    - cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
    - cpufreq_p4_old_state = newstate;
    + if (hyperthreading) {
    + freqs.cpu--;
    + cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
    + }

    return 0;
    }
    @@ -143,9 +169,9 @@
    /* if (number_states == 1) */
    {
    if (policy->cpu == CPUFREQ_ALL_CPUS) {
    - for (i=0; i<(NR_CPUS/2); i++)
    - if (cpu_online(2*i))
    - cpufreq_p4_setdc((2*i), newstate);
    + for (i=0; i<NR_CPUS; i++)
    + if (cpu_online(i))
    + cpufreq_p4_setdc(i, newstate);
    } else {
    cpufreq_p4_setdc(policy->cpu, newstate);
    }
    @@ -235,7 +261,6 @@
    for (i=0;i<NR_CPUS;i++)
    driver->cpu_cur_freq[i] = stock_freq;
    #endif
    - cpufreq_p4_old_state = DC_DISABLE;

    driver->verify = &cpufreq_p4_verify;
    driver->setpolicy = &cpufreq_p4_setpolicy;
    diff -ruN linux-2545original/arch/i386/kernel/i386_ksyms.c linux/arch/i386/kernel/i386_ksyms.c
    --- linux-2545original/arch/i386/kernel/i386_ksyms.c.original Thu Oct 31 12:00:00 2002
    +++ linux/arch/i386/kernel/i386_ksyms.c Thu Oct 31 20:00:00 2002
    @@ -145,6 +145,7 @@

    #ifdef CONFIG_SMP
    EXPORT_SYMBOL(cpu_data);
    +EXPORT_SYMBOL(smp_num_siblings);
    EXPORT_SYMBOL(cpu_online_map);
    EXPORT_SYMBOL(cpu_callout_map);
    EXPORT_SYMBOL_NOVERS(__write_lock_failed);[unhandled content-type:application/pgp-signature]
    \
     
     \ /
      Last update: 2005-03-22 13:30    [W:0.027 / U:1.296 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site