Dlaczego niektóre modele procesorów z rodziny Intel 6 (Core 2, Pentium M) nie są obsługiwane przez intel_idle?

25

Dostroiłem jądro Linuksa do procesorów Intel Core 2 Quad (Yorkfield) i zauważyłem następujące komunikaty od 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 pokazuje tylko stany C1, C2 i C3 używane dla pakietu i poszczególnych rdzeni:

          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

Ciekawe, zapytałem sysfsi odkryłem, że starszy acpi_idlesterownik był w użyciu (spodziewałem się zobaczyć intel_idlesterownik):

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

acpi_idle

Patrząc na kod źródłowy jądra, obecny sterownik intel_idle zawiera komunikat debugowania , w którym zauważono , że niektóre modele rodziny Intel 6 nie są obsługiwane przez sterownik:

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);

Wcześniejsze rozwidlenie (22 listopada 2010 r.) Pliku intel_idle.c pokazuje oczekiwane wsparcie dla procesorów Core 2 (model 23 faktycznie obejmuje zarówno Core 2 Duo, jak i Quad):

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

Powyższy kod został usunięty w zatwierdzeniu w grudniu 2010 roku .

Niestety w kodzie źródłowym prawie nie ma dokumentacji, więc nie ma wyjaśnienia dotyczącego braku obsługi funkcji bezczynności w tych procesorach.

Moja obecna konfiguracja jądra wygląda następująco:

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

Moje pytanie jest następujące:

  • Czy istnieje konkretny sprzętowy powód, dla którego nie są obsługiwane procesory Core 2 intel_idle?
  • Czy istnieje bardziej odpowiedni sposób skonfigurowania jądra dla optymalnej obsługi bezczynności procesora dla tej rodziny procesorów (oprócz wyłączenia obsługi intel_idle)?
vallismortis
źródło

Odpowiedzi:

28

Badając stany zasilania procesora Core 2 („ stany C ”), faktycznie udało mi się wdrożyć obsługę większości starszych procesorów Intel Core / Core 2. Pełna implementacja (łatka na system Linux) ze wszystkimi informacjami w tle jest tutaj udokumentowana.

Gdy zgromadziłem więcej informacji o tych procesorach, stało się jasne, że stany C obsługiwane w modelach Core 2 są znacznie bardziej złożone niż w przypadku wcześniejszych i późniejszych procesorów. Są one znane jako ulepszone stany C (lub „ CxE ”), które obejmują pakiet, poszczególne rdzenie i inne elementy mikroukładu (np. Pamięć). W momencie wydania intel_idlesterownika kod nie był szczególnie dojrzały i zostało wydanych kilka procesorów Core 2, które obsługiwały konflikt w stanie C.

W tym artykule z 2006 r . Znaleziono kilka istotnych informacji na temat obsługi stanu C Core 2 Solo / Duo . Jest to związane ze wsparciem w systemie Windows, jednak wskazuje na solidną sprzętową obsługę stanu C na tych procesorach. Informacje dotyczące Kentsfield są w konflikcie z faktycznym numerem modelu, więc uważam, że w rzeczywistości odnoszą się do Yorkfield poniżej:

... czterordzeniowy procesor Intel Core 2 Extreme (Kentsfield) obsługuje wszystkie pięć technologii wydajności i oszczędzania energii - Enhanced Intel SpeedStep (EIST), Thermal Monitor 1 (TM1) i Thermal Monitor 2 (TM2), stary zegar na żądanie Modulacja (ODCM), a także Enhanced C States (CxE). W porównaniu do procesorów Intel Pentium 4 i Pentium D 600, 800 i 900, które charakteryzują się tylko stanem Enhanced Halt (C1), funkcja ta została rozszerzona o procesory Intel Core 2 (jak również procesory Intel Core Solo / Duo) dla wszystkie możliwe stany bezczynności procesora, w tym Stop Grant (C2), Deep Sleep (C3) i Deeper Sleep (C4).

W tym artykule z 2008 r. Opisano obsługę stanów C na rdzeń w wielordzeniowych procesorach Intel, w tym Core 2 Duo i Core 2 Quad (dodatkowe pomocne informacje w tle można znaleźć w niniejszym dokumencie firmy Dell ):

Podstawowy stan C jest sprzętowym stanem C. Istnieje kilka podstawowych stanów bezczynności, np. CC1 i CC3. Jak wiemy, nowoczesny procesor ma wiele rdzeni, takich jak niedawno wydane mobilne procesory Core Duo T5000 / T7000, w niektórych kręgach znane jako Penryn. To, co kiedyś uważaliśmy za procesor / procesor, ma w rzeczywistości wiele procesorów ogólnego przeznaczenia. Intel Core Duo ma 2 rdzenie w układzie procesora. Intel Core-2 Quad ma 4 takie rdzenie na procesor. Każdy z tych rdzeni ma swój własny stan bezczynności. Ma to sens, ponieważ jeden rdzeń może być bezczynny, a drugi ciężko pracuje nad wątkiem. Tak więc rdzeniem C jest stan bezczynności jednego z tych rdzeni.

Znalazłem prezentację Intela z 2010 roku, która zawiera dodatkowe informacje na temat intel_idlesterownika, ale niestety nie wyjaśnia braku wsparcia dla Core 2:

Ten EKSPERYMENTALNY sterownik zastępuje acpi_idle w procesorach Intel Atom, Intel Core i3 / i5 / i7 i powiązanych procesorach Intel Xeon. Nie obsługuje procesora Intel Core2 lub wcześniejszego.

Powyższa prezentacja wskazuje, że intel_idlesterownik jest implementacją „menu” regulatora procesora, co ma wpływ na konfigurację jądra Linux (tj. CONFIG_CPU_IDLE_GOV_LADDERVs. CONFIG_CPU_IDLE_GOV_MENU). Różnice między drabiną a osobami zarządzającymi menu są zwięźle opisane w tej odpowiedzi .

Dell zawiera pomocny artykuł, w którym wymieniono stan C od C0 do C6:

Tryby C1 do C3 działają w zasadzie odcinając sygnały zegarowe stosowane w procesorze, podczas gdy tryby C4 do C6 działają poprzez zmniejszenie napięcia procesora. Tryby „Ulepszone” mogą działać jednocześnie.

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

Z tej tabeli (która później okazała się niepoprawna w niektórych przypadkach), wydaje się, że istniały różne różnice w obsłudze stanu C w procesorach Core 2 (zauważ, że prawie wszystkie procesory Core 2 są Socket LGA775, z wyjątkiem Core 2 Solo SU3500, czyli procesory Socket BGA956 i Merom / Penryn. Procesory „Intel Core” Solo / Duo to jeden z Socket PBGA479 lub PPGA478).

W tym artykule znaleziono dodatkowy wyjątek od tabeli :

Intel Core 2 Duo E8500 obsługuje stany C C2 i C4, podczas gdy Core 2 Extreme QX9650 nie.

Co ciekawe, QX9650 to procesor Yorkfield (rodzina Intel 6, model 23, stepping 6). Dla porównania, moja Q9550S ​​to rodzina Intel 6, model 23 (0x17), z krokiem 10, która podobno obsługuje stan C C4 (potwierdzony eksperymentalnie). Ponadto Core 2 Solo U3500 ma identyczny CPUID (rodzina, model, stopniowanie) co Q9550S, ale jest dostępny w gnieździe innym niż LGA775, co jest sprzeczne z interpretacją powyższej tabeli.

Oczywiście, identyfikator CPUID należy zastosować przynajmniej do stopniowania, aby zidentyfikować obsługę stanu C dla tego modelu procesora, aw niektórych przypadkach może to być niewystarczające (obecnie nieokreślone).

Podpis metody przypisywania informacji o bezczynności procesora to:

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

Gdzie modeljest wymienione w asm / intel-family.h . Analizując ten plik nagłówka, widzę, że procesorom Intel przypisano 8-bitowe identyfikatory, które wydają się pasować do numerów modeli rodziny Intel 6:

#define INTEL_FAM6_CORE2_PENRYN 0x17

Z powyższego mamy Intel Family 6, Model 23 (0x17) zdefiniowany jako INTEL_FAM6_CORE2_PENRYN. Powinno to wystarczyć do zdefiniowania stanów bezczynności dla większości procesorów Modelu 23, ale może potencjalnie powodować problemy z QX9650, jak wspomniano powyżej.

Tak więc minimalnie każda grupa procesorów, która ma odrębny zestaw stanów C, musiałaby zostać zdefiniowana na tej liście.

Zagacki i Ponnala, Intel Technology Journal 12 (3): 219–227, 2008 wskazują, że procesory Yorkfield rzeczywiście obsługują C2 i C4. Wydają się również wskazywać, że specyfikacja ACPI 3.0a obsługuje przejścia tylko między stanami C C0, C1, C2 i C3, co, jak zakładam, może również ograniczać acpi_idlesterownik Linuksa do przejść między tym ograniczonym zestawem stanów C. Jednak ten artykuł wskazuje, że nie zawsze tak jest:

Pamiętaj, że jest to stan ACPI C, a nie procesorowy, więc ACPI C3 może być HW C6 itp.

Uwaga:

Oprócz samego procesora, ponieważ C4 jest zsynchronizowanym wysiłkiem między głównymi komponentami krzemowymi na platformie, chipset Intel Q45 Express osiąga 28-procentową poprawę mocy.

Chipset, którego używam, jest rzeczywiście chipsetem Intel Q45 Express.

Dokumentacja Intela dotycząca stanów MWAIT jest zwięzła, ale potwierdza zachowanie ACPI specyficzne dla BIOS-u:

Specyficzne dla procesora stany C zdefiniowane w rozszerzeniach MWAIT mogą być mapowane na typy C określone przez ACPI (C0, C1, C2, C3). Relacja odwzorowania zależy od definicji stanu C według implementacji procesora i jest wystawiona na OSPM przez BIOS przy użyciu tabeli _CST zdefiniowanej przez ACPI.

Moja interpretacja powyższej tabeli (w połączeniu z tabelą z Wikipedii , asm / intel-family.h oraz powyższymi artykułami) brzmi:

Model 9 0x09 ( Pentium M i Celeron M ):

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

Model 13 0x0D ( Pentium M i Celeron M ):

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

Model 14 0x0E INTEL_FAM6_CORE_YONAH ( Enhanced Pentium M , Enhanced Celeron M lub Intel Core ):

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

Model 15 0x0F INTEL_FAM6_CORE2_MEROM (niektóre Core 2 i Pentium Dual-Core ):

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

Model 23 0x17 INTEL_FAM6_CORE2_PENRYN ( rdzeń 2 ):

  • Merom-L / Penryn-L:?
  • Penryn ( telefon komórkowy Core 2 Duo 45 nm ): 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

Biorąc pod uwagę różnorodność obsługi stanu C w samej linii procesorów Core 2, wydaje się, że brak spójnego wsparcia dla stanów C mógł być przyczyną nie podjęcia próby pełnego wsparcia ich przez intel_idlesterownik. Chciałbym w pełni uzupełnić powyższą listę dla całej linii Core 2.

To nie jest naprawdę satysfakcjonująca odpowiedź, ponieważ zastanawiam się, ile zużyto niepotrzebnej mocy, a nadmiar ciepła został (i nadal jest) generowany przez nie pełne wykorzystanie solidnych, energooszczędnych stanów MWAIT C na tych procesorach.

Chattopadhyay i in. 2018, Wydajne energetycznie wysokowydajne procesory: najnowsze podejścia do projektowania zielonych wysokowydajnych obliczeń warto zwrócić uwagę na szczególne zachowanie, którego szukam w chipsecie Q45 Express:

Pakiet stanu C (PC0-PC10) - Gdy domeny obliczeniowe, rdzeń i grafika (GPU) są bezczynne, procesor ma szansę na dodatkowe oszczędności energii na poziomie uncore i na poziomie platformy, na przykład poprzez spłukanie LLC i bramkowanie mocy kontroler pamięci i DRAM IO, aw pewnym stanie cały procesor można wyłączyć, a jego stan jest zachowany na zawsze włączonej domenie mocy.

W ramach testu umieściłem w linux / drivers / idle / intel_idle.c wiersz 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 }
};

w intel_idle.clinii 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,
};

w intel_idle.clinii 1073:

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

Po szybkiej kompilacji i ponownym uruchomieniu moich węzłów PXE, dmesgteraz pokazuje:

[    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

A teraz PowerTOP pokazuje:

          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

W końcu uzyskałem dostęp do stanów C Enhanced Core 2 i wygląda na to, że istnieje mierzalny spadek zużycia energii - mój miernik na 8 węzłach wydaje się być średnio co najmniej o 5% niższy (przy jednym węźle wciąż działającym starym jądrem) , ale spróbuję ponownie wymienić jądra jako test.

Ciekawa uwaga dotycząca obsługi C4E - wydaje się, że procesor My Yorktown Q9550S ​​ją obsługuje (lub inny inny stan podrzędny C4), jak wykazano powyżej! To mnie myli, ponieważ arkusz danych Intela na procesorze Core 2 Q9000 (sekcja 6.2) wspomina tylko o stanach C Normalny (C0), HALT (C1 = 0x00), Rozszerzony HALT (C1E = 0x01), Stop Grant (C2 = 0x10) , Extended Stop Grant (C2E = 0x11), Sleep / Deep Sleep (C3 = 0x20) i Deeper Sleep (C4 = 0x30). Co to za dodatkowy stan 0x31? Jeśli włączę stan C2, wówczas zamiast C4 zostanie użyte C4E. Jeśli wyłączę stan C2 (stan wymuszenia C2E), wówczas zamiast C4E zostanie użyte C4. Podejrzewam, że może to mieć coś wspólnego z flagami MWAIT, ale nie znalazłem jeszcze dokumentacji tego zachowania.

Nie jestem pewien, co z tym zrobić: wydaje się, że stan C1E jest używany zamiast C1, C2 zamiast C2E, a C4E zamiast C4. Nie jestem pewien, czy C1 / C1E, C2 / C2E i C4 / C4E mogą być używane razem z nimi, intel_idleczy też są nadmiarowe. Znalazłem notatkę w tej prezentacji Intel Labs Pittsburgh 2010, która wskazuje, że przejścia to C0 - C1 - C0 - C1E - C0, a ponadto stwierdza:

C1E jest używane tylko wtedy, gdy wszystkie rdzenie znajdują się w C1E

Uważam, że należy to interpretować, ponieważ stan C1E jest wprowadzany w innych komponentach (np. Pamięci) tylko wtedy, gdy wszystkie rdzenie są w stanie C1E. Przyjmuję to również w odniesieniu do stanów C2 / C2E i C4 / C4E (chociaż C4E jest określane jako „C4E / C5”, więc nie jestem pewien, czy C4E jest stanem podrzędnym C4, czy też C5 jest stanem podrzędnym stan C4E. Testowanie wydaje się wskazywać, że C4 / C4E jest poprawny). Mogę zmusić do użycia C2E, komentując stan C2 - jednak powoduje to użycie stanu C4 zamiast C4E (tutaj może być wymagana więcej pracy). Mamy nadzieję, że nie ma żadnych procesorów model 15 lub model 23, które nie mają stanu C2E, ponieważ te procesory byłyby ograniczone do C1 / C1E z powyższym kodem.

Również flagi, opóźnienia i wartości rezydencji mogą prawdopodobnie być dostrajane, ale przyjmowanie wykształconych domysłów w oparciu o wartości bezczynności Nehalem wydaje się działać dobrze. Aby dokonać ulepszeń, konieczne będzie więcej lektur.

Testowałem to na Core 2 Duo E2220 ( Allendale ), Dual Core Pentium E5300 ( Wolfdale ), Core 2 Duo E7400 , Core 2 Duo E8400 ( Wolfdale ), Core 2 Quad Q9550S ( Yorkfield ) i Core 2 Extreme QX9650 , i I nie znalazłem żadnych problemów poza wyżej wymienionymi preferencjami dla stanów C2 / C2E i C4 / C4E.

Ta modyfikacja sterownika nie obejmuje:

  • Oryginalny Core Solo / Core Duo ( Yonah , nie Core 2) to rodzina 6, model 14. To dobrze, ponieważ wspierały stany C C4E / C5 (Enhanced Deep Sleep), ale nie stany C1E / C2E i potrzebowałyby ich własna definicja bezczynności.

Jedyne kwestie, o których mogę myśleć to:

  • Core 2 Solo SU3300 / SU3500 (Penryn-L) należą do rodziny 6, model 23 i zostaną wykryte przez ten sterownik. Nie są one jednak gniazdami LGA775, więc mogą nie obsługiwać stanu C ulepszonego zatrzymania C1E. Podobnie jest w przypadku Core 2 Solo ULV U2100 / U2200 ( Merom-L ). Jednak intel_idlewydaje się , że sterownik wybiera odpowiedni C1 / C1E w oparciu o sprzętową obsługę podstan.
  • Rdzeń 2 Extreme QX9650 (Yorkfield) podobno nie obsługuje stanu C C2 lub C4. Potwierdziłem to, kupując na eBayu używany procesor Optiplex 780 i QX9650 Extreme. Procesor obsługuje stany C C1 i C1E. Dzięki tej modyfikacji sterownika procesor pracuje na biegu jałowym w stanie C1E zamiast C1, więc prawdopodobnie istnieje pewna oszczędność energii. Spodziewałem się zobaczyć stan C C3, ale nie jest on obecny podczas używania tego sterownika, więc być może będę musiał przyjrzeć się temu dalej.

Udało mi się znaleźć slajd z prezentacji Intela z 2009 roku na temat przejścia między stanami C (tj. Deep Power Down):

Wejście / wyjście z technologii Deep Power Down

Podsumowując, okazuje się, że nie było prawdziwego powodu braku wsparcia dla Core 2 w intel_idlesterowniku. Jest teraz jasne, że oryginalny kod pośredniczący dla „Core 2 Duo” obsługiwał tylko stany C C1 i C2, co byłoby znacznie mniej wydajne niż acpi_idlefunkcja, która również obsługuje stan C C3. Kiedy już wiedziałem, gdzie szukać, wdrożenie wsparcia było łatwe. Pomocne komentarze i inne odpowiedzi były bardzo mile widziane, a jeśli Amazon nasłuchuje, wiesz, gdzie wysłać czek.

Ta aktualizacja została przypisana do github . Wkrótce wyślę e-mailem łatkę do LKML.

Aktualizacja : Udało mi się również wykopać Socket T / LGA775 Allendale ( Conroe ) Core 2 Duo E2220, który jest rodziną 6, model 15, więc dodałem także obsługę tego. Ten model nie obsługuje stanu C C4, ale obsługuje C1 / C1E i C2 / C2E. Powinno to również działać w przypadku innych układów opartych na Conroe ( E4xxx / E6xxx ) i prawdopodobnie wszystkich procesorów Kentsfield i Merom (nie Merom-L).

Aktualizacja : W końcu znalazłem zasoby do tuningu MWAIT. Ten zapis Power vs. Performance oraz ten głębszy stan C i post na blogu o zwiększonym opóźnieniu zawierają przydatne informacje na temat identyfikowania opóźnień bezczynności procesora. Niestety raportuje tylko te opóźnienia wyjścia, które zostały zakodowane w jądrze (ale, co ciekawe, tylko te stany sprzętowe obsługiwane przez procesor):

# 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
vallismortis
źródło
4
To niezła robota detektywistyczna! Zapomniałem, jak skomplikowane były stany C C2D / C2Q. Ponownie niewykorzystane oszczędności energii, jeśli oprogramowanie układowe jest wystarczająco dobre, powinieneś nadal korzystać z przynajmniej niektórych stanów C za pośrednictwem acpi_idle różnych regulatorów wydajności. Jakie stany są powertopwyświetlane w twoim systemie?
Stephen Kitt
1
Bardzo fajna informacja, czy zastanawiałeś się nad zaproponowaniem łatki do jądra Linuksa?
Lekensteyn
1
„Stan C1E wydaje się być używany zamiast C1 ...” Który stan jest używany - jak pokazuje powertop - jest określany wyłącznie przez jądro, dlatego uważam, że nie będzie to miało „związku z flagami MWAIT”, zostanie wybrany wyłącznie na podstawie kolejności stanów oraz parametru exit_latency i target_residency. To powiedziawszy, byłbym nieco zaniepokojony stanami urlopu w tabeli, gdyby nie wydawały się przyzwyczaić podczas testowania ... na wypadek, gdyby te stany faktycznie nie działały zgodnie z oczekiwaniami, i był jakiś inny wzór obciążenia są używane i dzieje się nieoczekiwane zachowanie.
sourcejedi
1
„przejścia to C0 - C1 - C0 - C1E - C0” - Nie sądzę, żeby to był dobry opis tego slajdu. Z jądra / powertoppunktu widzenia wszystkie przejścia są z C0 lub do C0. Jeśli nie jesteś w C0, nie uruchamiasz żadnych instrukcji, dlatego jądro nie może ani obserwować, ani żądać przejścia między stanami na tym procesorze :-). I, jak mówisz, gubernator „menu” jądra może np. Przejść bezpośrednio do C1E, nie spędzając najpierw czasu w C1.
sourcejedi
1
„po prostu przyjmowanie wyuczonych przypuszczeń na podstawie bezczynnych wartości Nehalem wydaje się działać dobrze” - zauważ, że nie jest to dobry sposób na zaakceptowanie łatki w górę :-P, ponieważ opóźnienie wyjścia nie może być niedoceniane, w przeciwnym razie myślę, że to zrobisz naruszają PM_QOS_CPU_DMA_LATENCY, które mogą być ustawione przez sterowniki (lub przestrzeń użytkownika?)
sourcejedi
6

Podejrzewam, że może to być tylko okazja i koszt. Po intel_idledodaniu wydaje się, że planowano obsługę Core 2 Duo, ale nigdy nie została w pełni wdrożona - być może do czasu, gdy inżynierowie Intela się do tego przyzwyczaili, nie było to już warte. Równanie jest stosunkowo złożone: intel_idlemusi zapewnić wystarczające korzyści, acpi_idleaby było warte wsparcia tutaj, na procesorach, które zobaczą „ulepszone” jądro w wystarczającej liczbie ...

Jak sourcejedi „s odpowiedź mówi, kierowca nie wyklucza wszystkie rodziny 6. intel_idleKontrole inicjalizacji dla procesorów z listą modeli procesorów , obejmujące w zasadzie wszystkie mikro-architekturę Nehalem do Kaby od jeziora. Yorkfield jest starszy (i znacznie inny - Nehalem bardzo różni się od architektur, które były przed nim). Test rodziny 6 wpływa tylko na to, czy drukowany jest komunikat o błędzie; jego efektem jest tylko to, że komunikat o błędzie będzie wyświetlany tylko na procesorach Intel, a nie na procesorach AMD (rodzina Intel 6 obejmuje wszystkie procesory Intel inne niż NetBurst od czasu Pentium Pro).

Aby odpowiedzieć na pytanie konfiguracyjne, możesz całkowicie je wyłączyć intel_idle, ale pozostawienie go również jest w porządku (o ile nie przeszkadza ci ostrzeżenie).

Stephen Kitt
źródło
Komunikat pr_debug () powinien pojawić się tylko wtedy, gdy zrobisz coś bardzo specyficznego, aby włączyć ten komunikat debugowania, więc nie musisz nawet ignorować ostrzeżenia
sourcejedi
2
@sourcejedi Wspomniałem o tym, ponieważ OP to widzi.
Stephen Kitt
gotcha. Przedstawiam półpoważny komentarz: skoro jesteśmy pytani o rozsądną konfigurację jądra, jeśli jest ona używana na co dzień, być może nie należy używać opcji, która włącza wszystkie komunikaty debugowania? Z odpowiednią opcją można je włączyć dynamicznie i selektywnie w razie potrzeby. kernel.org/doc/html/v4.17/admin-guide/dynamic-debug-howto.html Jeśli włączysz wszystkie wiadomości debugowania, prawdopodobnie i tak masz wiele wiadomości, które i tak ignorujesz :).
sourcejedi
@sourcejedi Nie widzę znaczenia twoich komentarzy dotyczących wyłączania komunikatów jądra. Nie uważam tego za konstruktywne pytanie, które konkretnie dotyczy obsługi Core 2 dla intel_idlesterownika.
vallismortis
@vallismortis jest bardzo styczna. Oznacza to, że istnieje poprawna konfiguracja, której można użyć dla Core 2 i wyższych , która nie drukuje tego jako irytującego komunikatu ostrzegawczego, który należy po prostu zignorować i użyje intel_idle, jeśli jest obsługiwany ... ale wtedy przypuszczam, że użyłbyś dynamicznie ładowanego moduły i tak, więc może nie warto o tym wspominać.
sourcejedi
6

Czy istnieje bardziej odpowiedni sposób skonfigurowania jądra dla optymalnej obsługi bezczynności procesora dla tej rodziny procesorów (oprócz wyłączenia obsługi intel_idle)

Włączyłeś ACPI i sprawdziłeś, czy acpi_idle jest w użyciu. Szczerze wątpię, że przegapiłeś jakąkolwiek przydatną opcję konfiguracji jądra. Zawsze możesz sprawdzić powertopmożliwe sugestie, ale prawdopodobnie już to wiedziałeś.


To nie jest odpowiedź, ale chcę ją sformatować :-(.

Patrząc na kod źródłowy jądra, obecny sterownik intel_idle zawiera test, który konkretnie wyklucza rodzinę Intel 6 ze sterownika.

Nie, nie robi tego :-).

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;
}

ifStwierdzenie nie wyklucza Rodzina 6. Zamiast tego, ifsprawozdanie dostarcza wiadomość, gdy debugowanie jest włączone, że ten specyficzny nowoczesny procesor Intel nie jest obsługiwany przez intel_idle. W rzeczywistości mój obecny procesor i5-5300U to rodzina 6 i używa intel_idle.

Wykluczeniem twojego procesora jest to, że w intel_idle_idstabeli nie ma zgodności .

Zauważyłem to zatwierdzenie, które implementowało tabelę. switchZamiast tego usunięty kod zawierał instrukcję. Ułatwia to dostrzeżenie, że najwcześniejszy model intel_idle został wdrożony / pomyślnie przetestowany / cokolwiek to jest 0x1A = 26. https://github.com/torvalds/linux/commit/b66b8b9a4a79087dde1b358a016e5c8739ccf186

sourcejedi
źródło