Perché alcuni modelli di CPU della famiglia 6 Intel (Core 2, Pentium M) non sono supportati da intel_idle?


25

Ho ottimizzato il mio kernel Linux per i processori Intel Core 2 Quad (Yorkfield) e ho notato i seguenti messaggi da dmesg:

[    0.019526] cpuidle: using governor menu
[    0.531691] clocksource: acpi_pm: mask: 0xffffff max_cycles: 0xffffff, max_idle_ns: 2085701024 ns
[    0.550918] intel_idle: does not run on family 6 model 23
[    0.554415] tsc: Marking TSC unstable due to TSC halts in idle

PowerTop mostra solo gli stati C1, C2 e C3 utilizzati per il pacchetto e i singoli core:

          Package   |            CPU 0
POLL        0.0%    | POLL        0.0%    0.1 ms
C1          0.0%    | C1          0.0%    0.0 ms
C2          8.2%    | C2          9.9%    0.4 ms
C3         84.9%    | C3         82.5%    0.9 ms

                    |            CPU 1
                    | POLL        0.1%    1.6 ms
                    | C1          0.0%    1.5 ms
                    | C2          9.6%    0.4 ms
                    | C3         82.7%    1.0 ms

                    |            CPU 2
                    | POLL        0.0%    0.1 ms
                    | C1          0.0%    0.0 ms
                    | C2          7.2%    0.3 ms
                    | C3         86.5%    1.0 ms

                    |            CPU 3
                    | POLL        0.0%    0.1 ms
                    | C1          0.0%    0.0 ms
                    | C2          5.9%    0.3 ms
                    | C3         87.7%    1.0 ms

Curioso, ho fatto una query sysfse ho scoperto che il acpi_idledriver legacy era in uso (mi aspettavo di vedere il intel_idledriver):

cat /sys/devices/system/cpu/cpuidle/current_driver

acpi_idle

Guardando il codice sorgente del kernel, l'attuale driver intel_idle contiene un messaggio di debug in cui si nota che alcuni modelli della famiglia Intel 6 non sono supportati dal driver:

if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL && boot_cpu_data.x86 == 6)
    pr_debug("does not run on family %d model %d\n", boot_cpu_data.x86, boot_cpu_data.x86_model);

Un fork precedente (22 novembre 2010) di intel_idle.c mostra il supporto previsto per i processori Core 2 (il modello 23 attualmente copre sia Core 2 Duo che Quad):

#ifdef FUTURE_USE
    case 0x17:  /* 23 - Core 2 Duo */
        lapic_timer_reliable_states = (1 << 2) | (1 << 1); /* C2, C1 */
#endif

Il codice sopra è stato eliminato nel commit di dicembre 2010 .

Sfortunatamente, non c'è quasi documentazione nel codice sorgente, quindi non c'è spiegazione riguardo alla mancanza di supporto per la funzione inattiva in queste CPU.

La mia attuale configurazione del kernel è la seguente:

CONFIG_SMP=y
CONFIG_MCORE2=y
CONFIG_GENERIC_SMP_IDLE_THREAD=y
CONFIG_ACPI_PROCESSOR_IDLE=y
CONFIG_CPU_IDLE=y
# CONFIG_CPU_IDLE_GOV_LADDER is not set
CONFIG_CPU_IDLE_GOV_MENU=y
# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set
CONFIG_INTEL_IDLE=y

La mia domanda è la seguente:

  • C'è un motivo hardware specifico per il quale i processori Core 2 non sono supportati intel_idle?
  • Esiste un modo più appropriato per configurare un kernel per un supporto inattivo ottimale della CPU per questa famiglia di processori (oltre a disabilitare il supporto per intel_idle)?

Risposte:


28

Durante la ricerca degli stati di alimentazione della CPU Core 2 (" stati C "), in realtà sono riuscito a implementare il supporto per la maggior parte dei processori Intel Core / Core 2 legacy. L'implementazione completa (patch Linux) con tutte le informazioni di base è documentata qui.

Man mano che accumulavo maggiori informazioni su questi processori, è diventato evidente che gli stati C supportati nei modelli Core 2 sono molto più complessi di quelli dei processori precedenti e successivi. Questi sono noti come stati C migliorati (o " CxE "), che coinvolgono il pacchetto, i singoli core e altri componenti sul chipset (ad es. Memoria). Al momento del intel_idlerilascio del driver, il codice non era particolarmente maturo e numerosi processori Core 2 erano stati rilasciati con supporto in stato C in conflitto.

Alcune informazioni convincenti sul supporto dello stato C Core 2 Solo / Duo sono state trovate in questo articolo dal 2006 . Questo è in relazione al supporto su Windows, tuttavia indica il solido supporto hardware C-state su questi processori. Le informazioni relative a Kentsfield sono in conflitto con il numero di modello attuale, quindi credo che in realtà si riferiscano a un Yorkfield di seguito:

... il processore quad-core Intel Core 2 Extreme (Kentsfield) supporta tutte e cinque le tecnologie di prestazioni e risparmio energetico: Intel SpeedStep (EIST), Thermal Monitor 1 (TM1) e Thermal Monitor 2 (TM2) migliorati, vecchio orologio su richiesta Modulazione (ODCM) e Enhanced C States (CxE). Rispetto ai processori Intel Pentium 4 e Pentium D 600, 800 e 900, che sono caratterizzati solo dallo stato Enhanced Halt (C1), questa funzione è stata ampliata nei processori Intel Core 2 (così come i processori Intel Core Solo / Duo) per tutti i possibili stati di inattività di un processore, inclusi Stop Grant (C2), Deep Sleep (C3) e Deeper Sleep (C4).

Questo articolo del 2008 delinea il supporto per stati C per core su processori Intel multi-core, inclusi Core 2 Duo e Core 2 Quad (ulteriori utili letture di base sono state trovate in questo white paper di Dell ):

Uno stato C centrale è uno stato C hardware. Esistono diversi stati di inattività principali, ad esempio CC1 e CC3. Come sappiamo, un moderno processore all'avanguardia ha più core, come i processori mobili Core Duo T5000 / T7000 rilasciati di recente, noti come Penryn in alcuni ambienti. Ciò che eravamo soliti pensare come una CPU / processore, in realtà ha più CPU per scopi generici al suo fianco. L'Intel Core Duo ha 2 core nel chip del processore. Intel Core-2 Quad ha 4 core di questo tipo per chip del processore. Ognuno di questi core ha il suo stato inattivo. Questo ha senso in quanto un core potrebbe essere inattivo mentre un altro è al lavoro su un thread. Quindi uno stato C centrale è lo stato inattivo di uno di quei nuclei.

Ho trovato una presentazione 2010 di Intel che fornisce ulteriori informazioni sul intel_idledriver, ma purtroppo non spiega la mancanza di supporto per Core 2:

Questo driver SPERIMENTALE sostituisce acpi_idle su processori Intel Atom, processori Intel Core i3 / i5 / i7 e processori Intel Xeon associati. Non supporta il processore Intel Core2 o precedente.

La presentazione di cui sopra indica che il intel_idledriver è un'implementazione del regolatore di menu "menu", che ha un impatto sulla configurazione del kernel Linux (cioè, CONFIG_CPU_IDLE_GOV_LADDERvs. CONFIG_CPU_IDLE_GOV_MENU). Le differenze tra i regolatori ladder e menu sono brevemente descritte in questa risposta .

Dell ha un utile articolo che elenca la compatibilità C-state da C0 a C6:

Le modalità da C1 a C3 funzionano sostanzialmente tagliando i segnali di clock utilizzati all'interno della CPU, mentre le modalità da C4 a C6 riducono la tensione della CPU. Le modalità "avanzate" possono fare entrambe le cose contemporaneamente.

Mode   Name                   CPUs
C0     Operating State        All CPUs
C1     Halt                   486DX4 and above
C1E    Enhanced Halt          All socket LGA775 CPUs
C1E    —                      Turion 64, 65-nm Athlon X2 and Phenom CPUs
C2     Stop Grant             486DX4 and above
C2     Stop Clock             Only 486DX4, Pentium, Pentium MMX, K5, K6, K6-2, K6-III
C2E    Extended Stop Grant    Core 2 Duo and above (Intel only)
C3     Sleep                  Pentium II, Athlon and above, but not on Core 2 Duo E4000 and E6000
C3     Deep Sleep             Pentium II and above, but not on Core 2 Duo E4000 and E6000; Turion 64
C3     AltVID                 AMD Turion 64
C4     Deeper Sleep           Pentium M and above, but not on Core 2 Duo E4000 and E6000 series; AMD Turion 64
C4E/C5 Enhanced Deeper Sleep  Core Solo, Core Duo and 45-nm mobile Core 2 Duo only
C6     Deep Power Down        45-nm mobile Core 2 Duo only

Da questa tabella (che in seguito ho scoperto di essere errata in alcuni casi), sembra che ci fossero una varietà di differenze nel supporto dello stato C con i processori Core 2 (Notare che quasi tutti i processori Core 2 sono Socket LGA775, ad eccezione di Core 2 Solo SU3500, che sono processori Socket BGA956 e Merom / Penryn. I processori Solo / Duo "Intel Core" sono uno dei socket PBGA479 o PPGA478).

Un'eccezione aggiuntiva alla tabella è stata trovata in questo articolo :

Il Core 2 Duo E8500 di Intel supporta gli stati C C2 e C4, mentre il Core 2 Extreme QX9650 no.

È interessante notare che il QX9650 è un processore Yorkfield (famiglia Intel 6, modello 23, stepping 6). Per riferimento, il mio Q9550S ​​è la famiglia Intel 6, modello 23 (0x17), stepping 10, che presumibilmente supporta lo stato C C4 (confermato attraverso la sperimentazione). Inoltre, il Core 2 Solo U3500 ha un CPUID identico (famiglia, modello, stepping) al Q9550S ​​ma è disponibile in un socket non LGA775, il che confonde l'interpretazione della tabella sopra.

Chiaramente, il CPUID deve essere usato almeno fino allo stepping per identificare il supporto dello stato C per questo modello di processore, e in alcuni casi che potrebbe essere insufficiente (non determinato in questo momento).

La firma del metodo per l'assegnazione delle informazioni di inattività della CPU è:

#define ICPU(model, cpu) \
{ X86_VENDOR_INTEL, 6, model, X86_FEATURE_ANY, (unsigned long)&cpu }

Dove modelè elencato in asm / intel-family.h . Esaminando questo file di intestazione, vedo che alle CPU Intel sono assegnati identificatori a 8 bit che sembrano corrispondere ai numeri di modello della famiglia Intel 6:

#define INTEL_FAM6_CORE2_PENRYN 0x17

Da quanto sopra, abbiamo Intel Family 6, Modello 23 (0x17) definito come INTEL_FAM6_CORE2_PENRYN. Ciò dovrebbe essere sufficiente per definire gli stati di inattività per la maggior parte dei processori modello 23, ma potrebbe potenzialmente causare problemi con QX9650 come indicato sopra.

Quindi, in minima parte, ciascun gruppo di processori che ha un set di stati C distinto dovrebbe essere definito in questo elenco.

Zagacki e Ponnala, Intel Technology Journal 12 (3): 219-227, 2008 indicano che i processori di Yorkfield supportano effettivamente C2 e C4. Sembrano anche indicare che la specifica ACPI 3.0a supporta solo le transizioni tra gli stati C C0, C1, C2 e C3, che presumo possano anche limitare il acpi_idledriver Linux alle transizioni tra quell'insieme limitato di stati C. Tuttavia, questo articolo indica che potrebbe non essere sempre il caso:

Tieni presente che è lo stato ACPI C, non quello del processore, quindi ACPI C3 potrebbe essere HW C6, ecc.

Da notare anche:

Oltre al processore stesso, poiché C4 è uno sforzo sincronizzato tra i principali componenti di silicio nella piattaforma, il chipset Intel Q45 Express ottiene un miglioramento della potenza del 28 percento.

Il chipset che sto usando è davvero un chipset Intel Q45 Express.

La documentazione Intel sugli stati di MWAIT è concisa ma conferma il comportamento ACPI specifico del BIOS:

Gli stati C specifici del processore definiti nelle estensioni MWAIT possono essere mappati ai tipi di stato C definiti ACPI (C0, C1, C2, C3). La relazione di mappatura dipende dalla definizione di uno stato C per implementazione del processore ed è esposta a OSPM dal BIOS usando la tabella _CST definita da ACPI.

La mia interpretazione della tabella sopra (combinata con una tabella di Wikipedia , asm / intel-family.h e degli articoli precedenti) è:

Modello 9 0x09 ( Pentium M e Celeron M ):

  • Banias: C0, C1, C2, C3, C4

Modello 13 0x0D ( Pentium M e Celeron M ):

  • Dothan, Stealey: C0, C1, C2, C3, C4

Modello 14 0x0E INTEL_FAM6_CORE_YONAH ( Enhanced Pentium M , Enhanced Celeron M o Intel Core ):

  • Yonah ( Core Solo , Core Duo ): C0, C1, C2, C3, C4, C4E / C5

Modello 15 0x0F INTEL_FAM6_CORE2_MEROM (alcuni Core 2 e Pentium Dual-Core ):

  • Kentsfield, Merom, Conroe, Allendale ( E2xxx / E4xxx e Core 2 Duo E6xxx, T7xxxx / T8xxxx , Core 2 Extreme QX6xxx , Core 2 Quad Q6xxx ): C0, C1, C1E, C2, C2E

Modello 23 0x17 INTEL_FAM6_CORE2_PENRYN ( Core 2 ):

  • Merom-L / Penryn-L:?
  • Penryn ( Core 2 Duo 45-nm mobile ): C0, C1, C1E, C2, C2E, C3, C4, C4E / C5, C6
  • Yorkfield ( Core 2 Extreme QX9650 ): C0, C1, C1E, C2E ?, C3
  • Wolfdale / Yorkfield ( Core 2 Quad , C2Q Xeon , Core 2 Duo E5xxx / E7xxx / E8xxx , Pentium Dual-Core E6xxx , Celeron Dual-Core ): C0, C1, C1E, C2, C2E, C3, C4

Dalla quantità di diversità nel supporto dello stato C all'interno della sola linea di processori Core 2, sembra che la mancanza di un supporto coerente per gli stati C possa essere stata la ragione per non tentare di supportarli completamente tramite il intel_idledriver. Vorrei completare completamente l'elenco sopra per l'intera linea Core 2.

Questa non è davvero una risposta soddisfacente, perché mi chiedo quanta energia non necessaria viene utilizzata e il calore in eccesso è stato (ed è tuttora) generato non utilizzando completamente i solidi stati C MWAIT a risparmio energetico su questi processori.

Chattopadhyay et al. 2018, Processori ad alte prestazioni ad alta efficienza energetica: i recenti approcci per la progettazione di Green Performance Performance Computing meritano attenzione per il comportamento specifico che sto cercando nel chipset Q45 Express:

Pacchetto C-state (PC0-PC10) - Quando i domini di calcolo, Core e Graphics (GPU) sono inattivi, il processore ha l'opportunità di ulteriori risparmi energetici a livello di uncore e piattaforma, ad esempio, svuotando il LLC e attivando controller di memoria e DRAM IO, e in alcuni stati, l'intero processore può essere spento mentre il suo stato viene mantenuto su un dominio di alimentazione sempre attivo.

Come test, ho inserito quanto segue in linux / drivers / idle / intel_idle.c linea 127:

static struct cpuidle_state conroe_cstates[] = {
    {
        .name = "C1",
        .desc = "MWAIT 0x00",
        .flags = MWAIT2flg(0x00),
        .exit_latency = 3,
        .target_residency = 6,
        .enter = &intel_idle,
        .enter_s2idle = intel_idle_s2idle, },
    {
        .name = "C1E",
        .desc = "MWAIT 0x01",
        .flags = MWAIT2flg(0x01),
        .exit_latency = 10,
        .target_residency = 20,
        .enter = &intel_idle,
        .enter_s2idle = intel_idle_s2idle, },
//  {
//      .name = "C2",
//      .desc = "MWAIT 0x10",
//      .flags = MWAIT2flg(0x10),
//      .exit_latency = 20,
//      .target_residency = 40,
//      .enter = &intel_idle,
//      .enter_s2idle = intel_idle_s2idle, },
    {
        .name = "C2E",
        .desc = "MWAIT 0x11",
        .flags = MWAIT2flg(0x11),
        .exit_latency = 40,
        .target_residency = 100,
        .enter = &intel_idle,
        .enter_s2idle = intel_idle_s2idle, },
    {
        .enter = NULL }
};

static struct cpuidle_state core2_cstates[] = {
    {
        .name = "C1",
        .desc = "MWAIT 0x00",
        .flags = MWAIT2flg(0x00),
        .exit_latency = 3,
        .target_residency = 6,
        .enter = &intel_idle,
        .enter_s2idle = intel_idle_s2idle, },
    {
        .name = "C1E",
        .desc = "MWAIT 0x01",
        .flags = MWAIT2flg(0x01),
        .exit_latency = 10,
        .target_residency = 20,
        .enter = &intel_idle,
        .enter_s2idle = intel_idle_s2idle, },
    {
        .name = "C2",
        .desc = "MWAIT 0x10",
        .flags = MWAIT2flg(0x10),
        .exit_latency = 20,
        .target_residency = 40,
        .enter = &intel_idle,
        .enter_s2idle = intel_idle_s2idle, },
    {
        .name = "C2E",
        .desc = "MWAIT 0x11",
        .flags = MWAIT2flg(0x11),
        .exit_latency = 40,
        .target_residency = 100,
        .enter = &intel_idle,
        .enter_s2idle = intel_idle_s2idle, },
    {
        .name = "C3",
        .desc = "MWAIT 0x20",
        .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED,
        .exit_latency = 85,
        .target_residency = 200,
        .enter = &intel_idle,
        .enter_s2idle = intel_idle_s2idle, },
    {
        .name = "C4",
        .desc = "MWAIT 0x30",
        .flags = MWAIT2flg(0x30) | CPUIDLE_FLAG_TLB_FLUSHED,
        .exit_latency = 100,
        .target_residency = 400,
        .enter = &intel_idle,
        .enter_s2idle = intel_idle_s2idle, },
    {
        .name = "C4E",
        .desc = "MWAIT 0x31",
        .flags = MWAIT2flg(0x31) | CPUIDLE_FLAG_TLB_FLUSHED,
        .exit_latency = 100,
        .target_residency = 400,
        .enter = &intel_idle,
        .enter_s2idle = intel_idle_s2idle, },
    {
        .name = "C6",
        .desc = "MWAIT 0x40",
        .flags = MWAIT2flg(0x40) | CPUIDLE_FLAG_TLB_FLUSHED,
        .exit_latency = 200,
        .target_residency = 800,
        .enter = &intel_idle,
        .enter_s2idle = intel_idle_s2idle, },
    {
        .enter = NULL }
};

alla intel_idle.clinea 983:

static const struct idle_cpu idle_cpu_conroe = {
    .state_table = conroe_cstates,
    .disable_promotion_to_c1e = false,
};

static const struct idle_cpu idle_cpu_core2 = {
    .state_table = core2_cstates,
    .disable_promotion_to_c1e = false,
};

alla intel_idle.clinea 1073:

ICPU(INTEL_FAM6_CORE2_MEROM,  idle_cpu_conroe),
ICPU(INTEL_FAM6_CORE2_PENRYN, idle_cpu_core2),

Dopo una rapida compilazione e riavvio dei miei nodi PXE, dmesgora mostra:

[    0.019845] cpuidle: using governor menu
[    0.515785] clocksource: acpi_pm: mask: 0xffffff max_cycles: 0xffffff, max_idle_ns: 2085701024 ns
[    0.543404] intel_idle: MWAIT substates: 0x22220
[    0.543405] intel_idle: v0.4.1 model 0x17
[    0.543413] tsc: Marking TSC unstable due to TSC halts in idle states deeper than C2
[    0.543680] intel_idle: lapic_timer_reliable_states 0x2

E ora PowerTOP sta mostrando:

          Package   |            CPU 0
POLL        2.5%    | POLL        0.0%    0.0 ms
C1E         2.9%    | C1E         5.0%   22.4 ms
C2          0.4%    | C2          0.2%    0.2 ms
C3          2.1%    | C3          1.9%    0.5 ms
C4E        89.9%    | C4E        92.6%   66.5 ms

                    |            CPU 1
                    | POLL       10.0%  400.8 ms
                    | C1E         5.1%    6.4 ms
                    | C2          0.3%    0.1 ms
                    | C3          1.4%    0.6 ms
                    | C4E        76.8%   73.6 ms

                    |            CPU 2
                    | POLL        0.0%    0.2 ms
                    | C1E         1.1%    3.7 ms
                    | C2          0.2%    0.2 ms
                    | C3          3.9%    1.3 ms
                    | C4E        93.1%   26.4 ms

                    |            CPU 3
                    | POLL        0.0%    0.7 ms
                    | C1E         0.3%    0.3 ms
                    | C2          1.1%    0.4 ms
                    | C3          1.1%    0.5 ms
                    | C4E        97.0%   45.2 ms

Ho finalmente accesso agli stati C Core 2 avanzati e sembra che ci sia un calo misurabile nel consumo di energia - il mio contatore su 8 nodi sembra avere una media di almeno il 5% inferiore (con un nodo ancora in esecuzione il vecchio kernel) , ma proverò a scambiare nuovamente i kernel come test.

Una nota interessante riguardo al supporto C4E - Il mio processore York95 Q9550S ​​sembra supportarlo (o qualche altro stato secondario del C4), come evidenziato sopra! Questo mi confonde, perché il foglio dati Intel sul processore Core 2 Q9000 (sezione 6.2) menziona solo gli stati C Normale (C0), HALT (C1 = 0x00), Extended HALT (C1E = 0x01), Stop Grant (C2 = 0x10) , Extended Stop Grant (C2E = 0x11), Sleep / Deep Sleep (C3 = 0x20) e Deeper Sleep (C4 = 0x30). Che cos'è questo ulteriore stato 0x31? Se abilito lo stato C2, viene utilizzato C4E anziché C4. Se disabilito lo stato C2 (forza stato C2E), viene utilizzato C4 anziché C4E. Sospetto che ciò possa avere qualcosa a che fare con i flag MWAIT, ma non ho ancora trovato la documentazione per questo comportamento.

Non sono sicuro di cosa pensare: lo stato C1E sembra essere usato al posto di C1, C2 è usato al posto di C2E e C4E è usato al posto di C4. Non sono sicuro se C1 / C1E, C2 / C2E e C4 / C4E possano essere utilizzati insieme intel_idleo se siano ridondanti. Ho trovato una nota in questa presentazione del 2010 di Intel Labs Pittsburgh che indica che le transizioni sono C0 - C1 - C0 - C1E - C0 e afferma inoltre:

C1E viene utilizzato solo quando tutti i core sono in C1E

Credo che debba essere interpretato come lo stato C1E viene inserito su altri componenti (ad es. Memoria) solo quando tutti i core sono nello stato C1E. Prendo anche questo per applicarlo in modo equivalente agli stati C2 / C2E e C4 / C4E (Sebbene C4E sia indicato come "C4E / C5", quindi non sono sicuro se C4E sia un sotto-stato di C4 o se C5 sia un sub- stato di C4E. Il test sembra indicare che C4 / C4E è corretto). Posso forzare l'uso di C2E commentando lo stato C2 - tuttavia, ciò fa sì che venga utilizzato lo stato C4 anziché C4E (potrebbe essere necessario più lavoro qui). Si spera che non ci siano processori modello 15 o modello 23 a cui manca lo stato C2E, poiché tali processori sarebbero limitati a C1 / C1E con il codice sopra riportato.

Inoltre, i valori di flag, latenza e residenza potrebbero probabilmente essere messi a punto, ma il solo fatto di ipotizzare in base ai valori inattivi di Nehalem sembra funzionare bene. Per apportare miglioramenti saranno necessarie ulteriori letture.

Ho provato questo su un Core 2 Duo E2220 ( Allendale ), un Dual Core Pentium E5300 ( Wolfdale ), Core 2 Duo E7400 , Core 2 Duo E8400 ( Wolfdale ), Core 2 Quad Q9550S ( Yorkfield ) e Core 2 Extreme QX9650 e I non sono stati rilevati problemi oltre la suddetta preferenza per lo stato C2 / C2E e C4 / C4E.

Non coperto da questa modifica del driver:

  • I Core Solo / Core Duo originali ( Yonah , non Core 2) sono la famiglia 6, modello 14. Ciò è positivo perché supportavano gli stati C C4E / C5 (Enhanced Deep Sleep) ma non gli stati C1E / C2E e avrebbero bisogno del loro propria definizione inattiva.

Gli unici problemi che mi vengono in mente sono:

  • Core 2 Solo SU3300 / SU3500 (Penryn-L) sono la famiglia 6, modello 23 e saranno rilevati da questo driver. Tuttavia, non sono socket LGA775, pertanto potrebbero non supportare lo stato C Halt Enhanced C1E. Allo stesso modo per il Core 2 Solo ULV U2100 / U2200 ( Merom-L ). Tuttavia, il intel_idledriver sembra scegliere il C1 / C1E appropriato in base al supporto hardware dei sottostati.
  • Secondo quanto riferito, Core 2 Extreme QX9650 (Yorkfield) non supporta C-state C2 o C4. L'ho confermato acquistando un processore Optiplex 780 e QX9650 Extreme usato su eBay. Il processore supporta gli stati C C1 e C1E. Con questa modifica del driver, la CPU è inattiva nello stato C1E anziché C1, quindi si presume che si verifichi un certo risparmio energetico. Mi aspettavo di vedere C-state C3, ma non è presente quando si utilizza questo driver, quindi potrebbe essere necessario esaminare ulteriormente questo.

Sono riuscito a trovare una diapositiva da una presentazione Intel del 2009 sulle transizioni tra gli stati C (ovvero Deep Power Down):

Tecnologia Deep Power Down Ingresso / Uscita

In conclusione, si è scoperto che non vi era alcun motivo reale per la mancanza di supporto Core 2 nel intel_idledriver. Ora è chiaro che il codice originale dello stub per "Core 2 Duo" gestiva solo gli stati C1 e C2, che sarebbero stati molto meno efficienti della acpi_idlefunzione che gestisce anche lo stato C3. Una volta saputo dove cercare, implementare il supporto è stato facile. I commenti utili e le altre risposte sono stati molto apprezzati e se Amazon sta ascoltando, sai dove inviare l'assegno.

Questo aggiornamento è stato affidato a github . Presto invierò una patch via e-mail a LKML.

Aggiornamento : sono anche riuscito a scavare un Socket T / LGA775 Allendale ( Conroe ) Core 2 Duo E2220, che è la famiglia 6, modello 15, quindi ho aggiunto anche il supporto per quello. Questo modello non supporta C-state C4, ma supporta C1 / C1E e C2 / C2E. Questo dovrebbe funzionare anche con altri chip basati su Conroe ( E4xxx / E6xxx ) e possibilmente tutti i processori Kentsfield e Merom (non Merom-L).

Aggiornamento : ho finalmente trovato alcune risorse di ottimizzazione MWAIT. Questa scrittura Power vs. Performance e questo Deeper più profondo e un post di blog sulla latenza aumentata contengono entrambi alcune informazioni utili sull'identificazione delle latenze inattive della CPU. Sfortunatamente, questo riporta solo quelle latenze di uscita codificate nel kernel (ma, cosa interessante, solo quegli stati hardware supportati dal processore):

# cd /sys/devices/system/cpu/cpu0/cpuidle
# for state in `ls -d state*` ; do echo c-$state `cat $state/name` `cat $state/latency` ; done

c-state0/ POLL 0
c-state1/ C1 3
c-state2/ C1E 10
c-state3/ C2 20
c-state4/ C2E 40
c-state5/ C3 20
c-state6/ C4 60
c-state7/ C4E 100

4
È un bel lavoro da investigatore! Avevo dimenticato quanto fossero complessi gli stati C C2D / C2Q. Per quanto riguarda il risparmio energetico non sfruttato, se il tuo firmware è abbastanza buono, dovresti comunque ottenere il vantaggio di almeno alcuni degli stati C via acpi_idle e dei vari regolatori delle prestazioni. Quali stati powertopmostra sul tuo sistema?
Stephen Kitt,

1
Informazioni molto belle, hai mai pensato di proporre la tua patch al kernel Linux upstream?
Lekensteyn,

1
"Lo stato C1E sembra essere usato al posto di C1 ..." Lo stato utilizzato - come mostrato da powertop - è determinato esclusivamente dal kernel, quindi credo che non avrà "a che fare con i flag MWAIT", sarà scelto esclusivamente in base all'ordine degli stati, exit_latency e target_residency. Detto questo, sarei leggermente preoccupato per gli stati di congedo nella tabella se non sembravano essere utilizzati quando testati ... nel caso in cui quegli stati non funzionassero effettivamente come previsto, e c'era qualche altro schema di carico di lavoro che ha portato a vengono utilizzati e il comportamento imprevisto sta accadendo.
sourcejedi,

1
"le transizioni sono C0 - C1 - C0 - C1E - C0" - Non credo sia una buona descrizione di quella diapositiva. Dal kernel / dal powertoppunto di vista, tutte le transizioni sono da C0 a C0. Se non sei in C0, non stai eseguendo alcuna istruzione, quindi il kernel non può né osservare né richiedere alcuna transizione tra stati su quella CPU :-). E come dici tu, il governatore del "menu" del kernel potrebbe ad esempio saltare direttamente in C1E, senza prima passare del tempo in C1.
sourcejedi,

1
"il solo fatto di ipotizzare in base ai valori inattivi di Nehalem sembra funzionare bene" - nota che questo non è un buon modo per far accettare la tua patch a monte :-P, in quanto la latenza di uscita non deve essere sottovalutata, altrimenti penso che lo farai violare PM_QOS_CPU_DMA_LATENCY, che può essere impostato dai driver (o
spazio

6

Sospetto che questo potrebbe essere solo un caso di opportunità e costi. Quando è intel_idlestato aggiunto, sembra che il supporto Core 2 Duo sia stato pianificato, ma non è mai stato completamente implementato - forse quando gli ingegneri Intel ci hanno provato, non ne valeva più la pena. L'equazione è relativamente complessa: intel_idledeve fornire vantaggi sufficienti acpi_idleper far valere la pena supportare qui, su CPU che vedranno il kernel "migliorato" in numero sufficiente ...

Come sourcejedi ‘s risposta , dice, il conducente non esclude tutta la famiglia 6. I intel_idlecontrolli di inizializzazione per le CPU in un elenco di modelli di CPU , che copre praticamente tutte le micro-architetture da Nehalem a Kaby Lago. Yorkfield è più vecchio di così (e significativamente diverso - Nehalem è molto diverso dalle architetture che l'hanno preceduto). Il test della famiglia 6 ha effetto solo sulla stampa del messaggio di errore; il suo effetto è solo che il messaggio di errore verrà visualizzato solo su CPU Intel, non su CPU AMD (la famiglia Intel 6 include tutte le CPU Intel non NetBurst dal Pentium Pro).

Per rispondere alla tua domanda di configurazione, puoi disabilitare completamente intel_idle, ma lasciarlo anche dentro va bene (purché non ti dispiaccia l'avvertimento).


Il messaggio pr_debug () dovrebbe apparire solo se fai qualcosa di molto specifico per abilitare quel messaggio di debug, quindi non devi nemmeno ignorare l'avvertimento
sourcejedi

2
@sourcejedi L'ho detto perché l'OP lo sta vedendo.
Stephen Kitt,

Gotcha. Vi presento un commento semi-serio: dato che ci viene chiesto di una configurazione del kernel sensibile, se viene usata quotidianamente, forse non usare l'opzione che abilita tutti i messaggi di debug? Con l'opzione giusta, possono essere abilitati dinamicamente e selettivamente quando necessario. kernel.org/doc/html/v4.17/admin-guide/dynamic-debug-howto.html Se abiliti tutti i messaggi di debug, probabilmente hai molti messaggi che stai ignorando comunque :).
sourcejedi,

@sourcejedi Non riesco a vedere la pertinenza dei tuoi commenti riguardo alla disabilitazione dei messaggi del kernel. Non vedo questo come costruttivo per la domanda, che affronta in modo specifico il supporto Core 2 per il intel_idledriver.
vallismortis,

@vallismortis è molto tangenziale. Significa che esiste una configurazione valida che puoi utilizzare per Core 2 e versioni successive , che non lo stampa come un fastidioso messaggio di avviso che deve semplicemente essere ignorato e utilizzerà intel_idle se supportato ... ma suppongo che utilizzeresti il ​​caricamento dinamico moduli comunque, quindi forse non vale la pena menzionare.
sourcejedi,

6

Esiste un modo più appropriato per configurare un kernel per un supporto inattivo ottimale della CPU per questa famiglia di processori (oltre a disabilitare il supporto per intel_idle)

Hai ACPI abilitato e hai verificato che acpi_idle sia in uso. Sinceramente dubito che ti sia sfuggita qualsiasi utile opzione di configurazione del kernel. Puoi sempre verificare powertoppossibili suggerimenti, ma probabilmente lo sapevi già.


Questa non è una risposta, ma voglio formattarla :-(.

Guardando il codice sorgente del kernel, l'attuale driver intel_idle contiene un test per escludere specificamente la famiglia Intel 6 dal driver.

No non lo fa :-).

id = x86_match_cpu(intel_idle_ids);
if (!id) {
    if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL &&
        boot_cpu_data.x86 == 6)
        pr_debug(PREFIX "does not run on family %d model %d\n",
            boot_cpu_data.x86, boot_cpu_data.x86_model);
    return -ENODEV;
}

L' ifistruzione non esclude la Famiglia 6. Invece, l' ifistruzione fornisce un messaggio quando il debug è abilitato, che questa specifica moderna CPU Intel non è supportata da intel_idle. In effetti, la mia attuale CPU i5-5300U è la Famiglia 6 e la utilizza intel_idle.

Ciò che esclude la tua CPU è che non c'è corrispondenza nella intel_idle_idstabella.

Ho notato questo commit che ha implementato la tabella. Il codice che rimuove aveva switchinvece un'istruzione. Questo rende facile vedere che il primo modello intel_idle è stato implementato / testato con successo / qualunque sia 0x1A = 26. https://github.com/torvalds/linux/commit/b66b8b9a4a79087dde1b358a016e5c8739ccf186

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.