Pourquoi certains modèles de processeurs Intel famille 6 (Core 2, Pentium M) ne sont-ils pas pris en charge par intel_idle?


25

J'ai réglé mon noyau Linux pour les processeurs Intel Core 2 Quad (Yorkfield), et j'ai remarqué les messages suivants de 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 affiche uniquement les états C1, C2 et C3 utilisés pour le package et les cœurs individuels:

          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

Curieux, j'ai demandé sysfset constaté que le acpi_idlepilote hérité était en cours d'utilisation (je m'attendais à voir le intel_idlepilote):

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

acpi_idle

En regardant le code source du noyau, le pilote intel_idle actuel contient un message de débogage notant spécifiquement que certains modèles de la famille Intel 6 ne sont pas pris en charge par le pilote:

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

Une version antérieure (22 novembre 2010) de intel_idle.c montre la prise en charge prévue des processeurs Core 2 (le modèle 23 couvre en fait à la fois Core 2 Duo et Quad):

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

Le code ci-dessus a été supprimé lors de la validation de décembre 2010 .

Malheureusement, il n'y a presque aucune documentation dans le code source, il n'y a donc aucune explication concernant le manque de prise en charge de la fonction inactive dans ces CPU.

Ma configuration actuelle du noyau est la suivante:

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

Ma question est la suivante:

  • Y a-t-il une raison matérielle spécifique pour laquelle les processeurs Core 2 ne sont pas pris en charge intel_idle?
  • Existe-t-il un moyen plus approprié de configurer un noyau pour une prise en charge optimale du processeur pour cette famille de processeurs (en plus de désactiver la prise en charge de intel_idle)?

Réponses:


28

Lors de mes recherches sur les états d'alimentation du processeur Core 2 (" états C "), j'ai réussi à implémenter la prise en charge de la plupart des processeurs Intel Core / Core 2 hérités. L'implémentation complète (patch Linux) avec toutes les informations de base est documentée ici.

Alors que j'accumulais plus d'informations sur ces processeurs, il est devenu évident que les états C pris en charge dans les modèles Core 2 sont beaucoup plus complexes que ceux des processeurs précédents et ultérieurs. Celles-ci sont appelées états C améliorés (ou " CxE "), qui impliquent le package, les cœurs individuels et d'autres composants du chipset (par exemple, la mémoire). Au moment où le intel_idlepilote a été publié, le code n'était pas particulièrement mature et plusieurs processeurs Core 2 avaient été libérés avec une prise en charge conflictuelle de l'état C.

Certaines informations convaincantes sur la prise en charge de l'état Core 2 Solo / Duo C ont été trouvées dans cet article de 2006 . Ceci est en relation avec la prise en charge sur Windows, mais cela indique la prise en charge robuste de l'état C matériel sur ces processeurs. Les informations concernant Kentsfield sont en conflit avec le numéro de modèle réel, donc je pense qu'elles se réfèrent en fait à un Yorkfield ci-dessous:

... le processeur quadricœur Intel Core 2 Extreme (Kentsfield) prend en charge les cinq technologies de performances et d'économie d'énergie - Enhanced Intel SpeedStep (EIST), Thermal Monitor 1 (TM1) et Thermal Monitor 2 (TM2), ancienne horloge à la demande Modulation (ODCM), ainsi que les états C améliorés (CxE). Par rapport aux processeurs Intel Pentium 4 et Pentium D 600, 800 et 900, caractérisés uniquement par l'état Enhanced Halt (C1), cette fonction a été étendue aux processeurs Intel Core 2 (ainsi qu'aux processeurs Intel Core Solo / Duo) pour tous les états inactifs possibles d'un processeur, y compris Stop Grant (C2), Deep Sleep (C3) et Deeper Sleep (C4).

Cet article de 2008 décrit la prise en charge des états C par cœur sur les processeurs Intel multicœurs, y compris Core 2 Duo et Core 2 Quad (une lecture supplémentaire utile a été trouvée dans ce livre blanc de Dell ):

Un état C de base est un état C matériel. Il existe plusieurs états inactifs principaux, par exemple CC1 et CC3. Comme nous le savons, un processeur moderne à la pointe de la technologie possède plusieurs cœurs, tels que les processeurs mobiles Core Duo T5000 / T7000 récemment commercialisés, appelés Penryn dans certains cercles. Ce que nous considérions comme un processeur / processeur, a en fait plusieurs processeurs à usage général à côté. L'Intel Core Duo a 2 cœurs dans la puce du processeur. L'Intel Core-2 Quad dispose de 4 cœurs par puce de processeur. Chacun de ces cœurs a son propre état de veille. Cela a du sens, car un noyau peut être inactif tandis qu'un autre travaille dur sur un thread. Un état C de base est donc l'état inactif de l'un de ces cœurs.

J'ai trouvé une présentation d'Intel en 2010 qui fournit des informations supplémentaires sur le intel_idlepilote, mais n'explique malheureusement pas le manque de prise en charge de Core 2:

Ce pilote EXPERIMENTAL remplace acpi_idle sur les processeurs Intel Atom, Intel Core i3 / i5 / i7 et les processeurs Intel Xeon associés. Il ne prend pas en charge le processeur Intel Core2 ou antérieur.

La présentation ci-dessus indique que le intel_idlepilote est une implémentation du gouverneur de CPU "menu", qui a un impact sur la configuration du noyau Linux (c.-à-d. CONFIG_CPU_IDLE_GOV_LADDERVs. CONFIG_CPU_IDLE_GOV_MENU). Les différences entre l'échelle et les gouverneurs de menu sont succinctement décrites dans cette réponse .

Dell a un article utile qui répertorie la compatibilité des états C C0 à C6:

Les modes C1 à C3 fonctionnent en coupant essentiellement les signaux d'horloge utilisés à l'intérieur du CPU, tandis que les modes C4 à C6 fonctionnent en réduisant la tension du CPU. Les modes "améliorés" peuvent faire les deux en même temps.

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

D'après ce tableau (que j'ai constaté par la suite incorrect dans certains cas), il semble qu'il y ait une variété de différences dans la prise en charge de l'état C avec les processeurs Core 2 (Notez que presque tous les processeurs Core 2 sont Socket LGA775, à l'exception de Core 2 Solo SU3500, qui sont des processeurs Socket BGA956 et Merom / Penryn. Les processeurs "Intel Core" Solo / Duo sont l'un des Socket PBGA479 ou PPGA478).

Une exception supplémentaire au tableau a été trouvée dans cet article :

Le Core 2 Duo E8500 d'Intel prend en charge les états C C2 et C4, contrairement au Core 2 Extreme QX9650.

Fait intéressant, le QX9650 est un processeur Yorkfield (famille Intel 6, modèle 23, étape 6). Pour référence, mon Q9550S ​​est la famille Intel 6, modèle 23 (0x17), pas à pas 10, qui prend censément en charge l'état C4 (confirmé par l'expérimentation). De plus, le Core 2 Solo U3500 a un CPUID (famille, modèle, pas à pas) identique au Q9550S ​​mais est disponible dans un socket non LGA775, ce qui confond l'interprétation du tableau ci-dessus.

De toute évidence, le CPUID doit être utilisé au moins jusqu'à l'étape afin d'identifier la prise en charge de l'état C pour ce modèle de processeur, et dans certains cas, cela peut être insuffisant (indéterminé pour le moment).

La signature de méthode pour attribuer des informations inactives au processeur est:

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

modelest énuméré dans asm / intel-family.h . En examinant ce fichier d'en-tête, je constate que les processeurs Intel se voient attribuer des identificateurs 8 bits qui semblent correspondre aux numéros de modèle de la famille Intel 6:

#define INTEL_FAM6_CORE2_PENRYN 0x17

D'après ce qui précède, nous avons Intel Family 6, modèle 23 (0x17) défini comme INTEL_FAM6_CORE2_PENRYN. Cela devrait être suffisant pour définir des états inactifs pour la plupart des processeurs du modèle 23, mais pourrait potentiellement causer des problèmes avec QX9650 comme indiqué ci-dessus.

Ainsi, au minimum, chaque groupe de processeurs qui a un ensemble d'états C distinct devrait être défini dans cette liste.

Zagacki et Ponnala, Intel Technology Journal 12 (3): 219-227, 2008 indiquent que les processeurs Yorkfield prennent effectivement en charge C2 et C4. Ils semblent également indiquer que la spécification ACPI 3.0a prend en charge les transitions uniquement entre les états C C0, C1, C2 et C3, ce qui, je suppose, peut également limiter le acpi_idlepilote Linux aux transitions entre cet ensemble limité d'états C. Cependant, cet article indique que ce n'est pas toujours le cas:

Gardez à l'esprit que c'est l'état ACPI C, pas celui du processeur, donc ACPI C3 peut être HW C6, etc.

A noter également:

Au-delà du processeur lui-même, puisque C4 est un effort synchronisé entre les principaux composants en silicium de la plate-forme, le chipset Intel Q45 Express atteint une amélioration de 28% de la puissance.

Le chipset que j'utilise est en effet un chipset Intel Q45 Express.

La documentation Intel sur les états MWAIT est concise mais confirme le comportement ACPI spécifique au BIOS:

Les états C spécifiques au processeur définis dans les extensions MWAIT peuvent correspondre à des types d'état C définis par ACPI (C0, C1, C2, C3). La relation de mappage dépend de la définition d'un état C par l'implémentation du processeur et est exposée à OSPM par le BIOS à l'aide de la table _CST définie par ACPI.

Mon interprétation du tableau ci-dessus (combiné avec un tableau de Wikipedia , asm / intel-family.h et les articles ci-dessus) est:

Modèle 9 0x09 ( Pentium M et Celeron M ):

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

Modèle 13 0x0D ( Pentium M et Celeron M ):

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

Modèle 14 0x0E INTEL_FAM6_CORE_YONAH ( Enhanced Pentium M , Enhanced Celeron M ou Intel Core ):

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

Modèle 15 0x0F INTEL_FAM6_CORE2_MEROM (certains Core 2 et Pentium Dual-Core ):

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

Modèle 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

Compte tenu de la diversité de la prise en charge des états C au sein de la gamme de processeurs Core 2, il semble qu'un manque de prise en charge cohérente des états C ait pu être la raison pour ne pas tenter de les prendre en charge entièrement via le intel_idlepilote. Je voudrais compléter complètement la liste ci-dessus pour toute la gamme Core 2.

Ce n'est pas vraiment une réponse satisfaisante, car cela me fait me demander combien d'énergie inutile est utilisée et la chaleur excessive a été (et est toujours) générée en n'utilisant pas pleinement les robustes états C MWAIT à économie d' énergie sur ces processeurs.

Chattopadhyay et al. 2018, Processeurs haute performance écoénergétiques: approches récentes pour concevoir un calcul haute performance écologique mérite d'être noté pour le comportement spécifique que je recherche dans le chipset Q45 Express:

Package C-state (PC0-PC10) - Lorsque les domaines de calcul, Core et Graphics (GPU) sont inactifs, le processeur a la possibilité d'économiser davantage d'énergie aux niveaux uncore et plate-forme, par exemple, le rinçage du LLC et la mise sous tension du contrôleur de mémoire et DRAM IO, et à un certain état, le processeur entier peut être éteint pendant que son état est préservé sur un domaine d'alimentation toujours allumé.

Comme test, j'ai inséré ce qui suit sur linux / drivers / idle / intel_idle.c ligne 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 }
};

à la intel_idle.cligne 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,
};

à la intel_idle.cligne 1073:

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

Après une compilation et un redémarrage rapides de mes nœuds PXE, dmesgaffiche maintenant:

[    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

Et maintenant, PowerTOP montre:

          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

J'ai finalement accédé aux états C améliorés du Core 2, et il semble qu'il y ait une baisse mesurable de la consommation d'énergie - mon compteur sur 8 nœuds semble être en moyenne au moins 5% inférieur (avec un nœud exécutant toujours l'ancien noyau) , mais je vais essayer d'échanger à nouveau les noyaux comme test.

Une note intéressante concernant la prise en charge de C4E - Mon processeur Yorktown Q9550S ​​semble la prendre en charge (ou un autre sous-état de C4), comme en témoigne ci-dessus! Cela m'embrouille, car la fiche technique Intel sur le processeur Core 2 Q9000 (section 6.2) ne mentionne que les états C Normal (C0), HALT (C1 = 0x00), HALT étendu (C1E = 0x01), Stop Grant (C2 = 0x10) , Extended Stop Grant (C2E = 0x11), Sleep / Deep Sleep (C3 = 0x20) et Deeper Sleep (C4 = 0x30). Quel est cet état 0x31 supplémentaire? Si j'active l'état C2, alors C4E est utilisé à la place de C4. Si je désactive l'état C2 (forcer l'état C2E), alors C4 est utilisé à la place de C4E. Je soupçonne que cela peut avoir quelque chose à voir avec les indicateurs MWAIT, mais je n'ai pas encore trouvé de documentation pour ce comportement.

Je ne sais pas quoi faire de cela: l'état C1E semble être utilisé à la place de C1, C2 est utilisé à la place de C2E et C4E est utilisé à la place de C4. Je ne sais pas si C1 / C1E, C2 / C2E et C4 / C4E peuvent être utilisés avec intel_idleou s'ils sont redondants. J'ai trouvé une note dans cette présentation 2010 d'Intel Labs Pittsburgh qui indique que les transitions sont C0 - C1 - C0 - C1E - C0, et déclare en outre:

C1E n'est utilisé que lorsque tous les cœurs sont en C1E

Je crois que cela doit être interprété comme l'état C1E est entré sur d'autres composants (par exemple la mémoire) uniquement lorsque tous les cœurs sont dans l'état C1E. Je suppose également que cela s'applique de manière équivalente aux états C2 / C2E et C4 / C4E (bien que C4E soit appelé "C4E / C5", je ne suis donc pas certain que C4E soit un sous-état de C4 ou si C5 est un sous-état). état de C4E. Les tests semblent indiquer que C4 / C4E est correct). Je peux forcer l'utilisation de C2E en commentant l'état C2 - cependant, cela entraîne l'utilisation de l'état C4 au lieu de C4E (plus de travail peut être nécessaire ici). Espérons qu'il n'y ait aucun processeur de modèle 15 ou 23 qui ne possède pas l'état C2E, car ces processeurs seraient limités à C1 / C1E avec le code ci-dessus.

En outre, les valeurs des drapeaux, de la latence et de la résidence pourraient probablement être affinées, mais simplement prendre des suppositions éclairées basées sur les valeurs de ralenti de Nehalem semble fonctionner correctement. Plus de lecture sera nécessaire pour apporter des améliorations.

J'ai testé cela sur 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 ) et Core 2 Extreme QX9650 , et I n'ont trouvé aucun problème au-delà de la préférence susmentionnée pour les états C2 / C2E et C4 / C4E.

Non couvert par cette modification de pilote:

  • Les Core Solo / Core Duo d'origine ( Yonah , non Core 2) sont de la famille 6, modèle 14. C'est bien parce qu'ils supportaient les états C C4E / C5 (Enhanced Deep Sleep) mais pas les états C1E / C2E et auraient besoin de leur propre définition inactive.

Les seuls problèmes auxquels je peux penser sont:

  • Les Core 2 Solo SU3300 / SU3500 (Penryn-L) sont de la famille 6, modèle 23 et seront détectés par ce pilote. Cependant, ils ne sont pas Socket LGA775, ils ne peuvent donc pas prendre en charge l'état C C1E Enhanced Halt. De même pour le Core 2 Solo ULV U2100 / U2200 ( Merom-L ). Cependant, le intel_idlepilote semble choisir le C1 / C1E approprié en fonction de la prise en charge matérielle des sous-états.
  • Le Core 2 Extreme QX9650 (Yorkfield) ne prendrait pas en charge les états C C2 ou C4. J'ai confirmé cela en achetant un processeur Optiplex 780 et QX9650 Extreme d'occasion sur eBay. Le processeur prend en charge les états C C1 et C1E. Avec cette modification de pilote, le processeur est inactif dans l'état C1E au lieu de C1, il y a donc probablement des économies d'énergie. Je m'attendais à voir l'état C C3, mais il n'est pas présent lors de l'utilisation de ce pilote, je devrai peut-être approfondir cela.

J'ai réussi à trouver une diapositive à partir d'une présentation Intel 2009 sur les transitions entre les états C (c.-à-d. Deep Power Down):

Entrée / sortie de la technologie Deep Power Down

En conclusion, il s'avère qu'il n'y avait aucune raison réelle pour le manque de support Core 2 dans le intel_idlepilote. Il est clair maintenant que le code de remplacement d'origine pour "Core 2 Duo" ne traitait que les états C C1 et C2, ce qui aurait été beaucoup moins efficace que la acpi_idlefonction qui gère également l'état C C3. Une fois que je savais où chercher, la mise en œuvre du support était facile. Les commentaires utiles et autres réponses ont été très appréciés, et si Amazon écoute, vous savez où envoyer le chèque.

Cette mise à jour a été validée pour github . Je vais bientôt envoyer un patch au LKML.

Mise à jour : J'ai également réussi à déterrer un Socket T / LGA775 Allendale ( Conroe ) Core 2 Duo E2220, qui est de la famille 6, modèle 15, j'ai donc ajouté un support pour cela également. Ce modèle ne prend pas en charge l'état C4 C, mais prend en charge C1 / C1E et C2 / C2E. Cela devrait également fonctionner pour d'autres puces basées sur Conroe ( E4xxx / E6xxx ) et éventuellement tous les processeurs Kentsfield et Merom (non Merom-L).

Mise à jour : j'ai finalement trouvé des ressources de réglage MWAIT. Cet article Power vs Performance et ces états Deeper C et blog de latence accrue contiennent tous les deux des informations utiles sur l'identification des latences inactives du processeur. Malheureusement, cela ne signale que les latences de sortie qui ont été codées dans le noyau (mais, fait intéressant, seuls les états matériels pris en charge par le processeur):

# 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
C'est un beau travail de détective! J'avais oublié la complexité des états C C2D / C2Q. En ce qui concerne les économies d'énergie inexploitées, si votre micrologiciel est suffisamment bon, vous devriez toujours bénéficier d'au moins certains des états C via acpi_idle et des divers gouverneurs de performances. Quels états powertopapparaissent sur votre système?
Stephen Kitt

1
Très belle information, avez-vous envisagé de proposer votre patch au noyau Linux amont?
Lekensteyn

1
"L'état C1E semble être utilisé à la place de C1 ..." Quel état est utilisé - comme le montre powertop - est déterminé uniquement par le noyau, donc je pense qu'il n'aura "rien à voir avec les drapeaux MWAIT", il sera choisi uniquement en fonction de l'ordre des états et de exit_latency et target_residency. Cela dit, je serais légèrement préoccupé par le fait de laisser les États dans le tableau s'ils ne semblent pas être utilisés lors des tests ... au cas où ces États ne fonctionneraient pas comme prévu, et qu'il y avait un autre modèle de charge de travail qui a conduit à leur utilisation et le comportement inattendu qui se produit.
sourcejedi

1
"les transitions sont C0 - C1 - C0 - C1E - C0" - Je ne pense pas que ce soit une bonne description de cette diapositive. Du powertoppoint de vue du noyau / point de vue, toutes les transitions sont soit de C0, soit à C0. Si vous n'êtes pas en C0, vous n'exécutez aucune instruction, donc le noyau ne peut ni observer ni demander de transition entre les états sur ce processeur :-). Et comme vous le dites, le gouverneur du "menu" du noyau peut par exemple sauter directement en C1E, sans passer de temps en C1 en premier.
sourcejedi

1
"il suffit de prendre des suppositions éclairées basées sur les valeurs de ralenti de Nehalem" - notez que ce n'est pas un bon moyen de faire accepter votre patch en amont :-P, en ce que la latence de sortie ne doit pas être sous-estimée, sinon je pense que vous le ferez violer PM_QOS_CPU_DMA_LATENCY, qui peut être défini par les pilotes (ou l'espace utilisateur?)
sourcejedi

6

Je soupçonne que cela pourrait simplement être une affaire d'opportunité et de coût. Quand il a intel_idleété ajouté, il semble que le support Core 2 Duo ait été prévu, mais il n'a jamais été entièrement mis en œuvre - peut-être au moment où les ingénieurs d'Intel s'y sont mis, cela n'en valait plus la peine. L'équation est relativement complexe: intel_idledoit fournir des avantages suffisants acpi_idlepour qu'elle soit prise en charge ici, sur les processeurs qui verront le noyau «amélioré» en nombre suffisant ...

Comme le dit la réponse de sourcejedi , le pilote n’exclut pas la totalité de la famille 6. L’ initialisation vérifie les CPU dans une liste de modèles de CPU , couvrant essentiellement toutes les micro-architectures de Nehalem à Kaby Lake. Yorkfield est plus ancien que cela (et très différent - Nehalem est très différent des architectures qui l'ont précédé). Le test de la famille 6 affecte uniquement si le message d'erreur est imprimé; son effet est seulement que le message d'erreur ne s'affichera que sur les processeurs Intel, pas sur les processeurs AMD (la famille Intel 6 inclut tous les processeurs Intel non NetBurst depuis le Pentium Pro).intel_idle

Pour répondre à votre question de configuration, vous pouvez désactiver complètement intel_idle, mais le laisser est très bien aussi (tant que vous ne vous occupez pas de l'avertissement).


Le message pr_debug () ne devrait apparaître que si vous faites quelque chose de très spécifique pour activer ce message de débogage, vous n'avez donc même pas à ignorer l'avertissement
sourcejedi

2
@sourcejedi Je l'ai mentionné parce que le PO le voit.
Stephen Kitt

je t'ai eu. Je présente un commentaire à moitié sérieux: puisque nous sommes interrogés sur une configuration sensible du noyau, si elle est utilisée au jour le jour, peut-être ne pas utiliser l'option qui active tous les messages de débogage? Avec la bonne option, ils peuvent être activés dynamiquement et sélectivement si nécessaire. kernel.org/doc/html/v4.17/admin-guide/dynamic-debug-howto.html Si vous activez tous les messages de débogage, vous avez probablement beaucoup de messages que vous ignorez de toute façon :).
sourcejedi

@sourcejedi Je ne vois pas la pertinence de vos commentaires concernant la désactivation des messages du noyau. Je ne vois pas cela comme étant constructif pour la question, qui traite spécifiquement du support Core 2 pour le intel_idlepilote.
vallismortis

@vallismortis c'est très tangentiel. Cela signifie qu'il existe une configuration valide que vous pouvez utiliser pour Core 2 et supérieur , qui n'imprime pas cela comme un message d'avertissement ennuyeux qui doit simplement être ignoré, et utilisera intel_idle s'il est pris en charge ... mais je suppose que vous utiliseriez chargé dynamiquement modules de toute façon, donc peut-être pas la peine de mentionner.
sourcejedi

6

Existe-t-il un moyen plus approprié de configurer un noyau pour une prise en charge optimale de l'inactivité du processeur pour cette famille de processeurs (à part la désactivation de la prise en charge pour intel_idle)

ACPI est activé et vous avez vérifié que acpi_idle est en cours d'utilisation. Je doute sincèrement que vous ayez manqué une option de configuration du noyau utile. Vous pouvez toujours vérifier powertoples suggestions possibles, mais vous le saviez probablement déjà.


Ce n'est pas une réponse, mais je veux le formater :-(.

En regardant le code source du noyau, le pilote intel_idle actuel contient un test pour exclure spécifiquement la famille Intel 6 du pilote.

Non, ce n'est pas le cas :-).

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' ifinstruction n'exclut pas la famille 6. Au lieu de cela, l' ifinstruction fournit un message lorsque le débogage est activé, que ce processeur Intel moderne spécifique n'est pas pris en charge par intel_idle. En fait, mon processeur i5-5300U actuel est la famille 6 et il utilise intel_idle.

Ce qui exclut votre CPU, c'est qu'il n'y a pas de correspondance dans le intel_idle_idstableau.

J'ai remarqué ce commit qui a implémenté la table. Le code qu'il supprime avait une switchinstruction à la place. Cela permet de voir facilement que le premier modèle intel_idle a été implémenté / testé avec succès / quel que soit 0x1A = 26. https://github.com/torvalds/linux/commit/b66b8b9a4a79087dde1b358a016e5c8739ccf186

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.