AMD CPU hibába botlott Matthew Dillon?

Címkék

Matthew Dillon, a Dragonfly BSD projekt alapítója és vezetője egy érdekes probléma leírását és lehetséges megkerülését tette közzé karácsony első napján. Mint azt levelében írja, jóval több mint egy éve küzd ezzel a problémával és az elmúlt két hónapban keményen dolgozott azon, hogy a végére járjon.

A probléma kizárólag a gcc 4.4.7-ben található cc1-gyel jött elő és kizárólag AMD processzoron. Ugyanaz a kód ugyanazon az operációs rendszer környezetben Intel hardveren nem okoz hibát. Mivel a kód ugyanazon paraméterekkel történő ismételt futtatásával nem sikerült a hibát reprodukálni konzisztensen, Dillon azt feltételezte, hogy a hiba nem magában a cc1-ben van.

A hibát három különböző, AMD processzoros hardveren sikerült Dillon-nak megvizsgálnia. Ezt a hibát Intel processzoros hardveren soha nem sikerült reprodukálni. A hibát egyrészt azért volt nehéz megfogni, mert a reprodukálásához kezdetben körülbelül 2 napi folyamatos buildworld tesztre volt szükség. Dillon addig ügyeskedett, amíg sikerült egy olyan tesztkörnyezetet összeállítania, amellyel a bug 60 másodperc alatt reprodukálhatóvá vált.

A bug egyszerűen reprodukálható bugos AMD processzoron DragonFly alatt egy make -j 20 buildword-del, vagy hasonló, ciklusban futtatott buildword-del.

Dillon próbálta a problémát BIOS frissítésekkel stb. megoldani, de nem járt sikerrel. A legfrissebb BIOS-okkal is előjött a probléma.

Dillon mielőtt a hardvert nevezte volna meg a probléma okaként, próbált kernelhibát keresni, hátha az okozza a gondot. Nem talált ilyen problémát. Dillon most azt hiszi, hogy a probléma forrásának CPU bugnak kell lennie.

Az érdekes levél elolvasható itt.

Hozzászólások

Karácsonyi AMD bug! :-)

>Dillon próbálta mielőtt a hardvert nevezte volna meg a probléma okaként, próbált kernelhibát keresni
Vagy kimaradt pár szó a mondatból vagy rossz a mondatrészek sorrendje.

nem gyenge. idejét sem tudom már, mikor volt utoljára amd/intel procibug

waaa, vegre itt a karacsonyi kikapcs, es kiderithetem, mert nem megy AMD-n az a szar... hehe :)

Ez nem olyan dolog, hogy kijön egy új microcode, s le van tudva a bug?

tr [:lower:] [:upper:] <<<locsemege
LOCSEMEGE

Amikor én ilyen szöveggel előállok a főnöknek, visszaküld dolgozni, hogy rendes hibaleírást akar, nem rizsát.

Melyik CPU utasítások, milyen feltételek esetén,...

Az, hogy nem melegedett túl a számítógép, meg Mancika sem klikkelt félre, akkor biztos AMD CPU hiba, nem elfogadható.

Utána kiderül, hogy az egésznek semmi köze az AMD, Intel CPU-hoz és totál beégés, meg még egy kártérítési pert is kapnak a nyakukba valótlan állításáért.

Kivancsi lennek, hogy mondjuk orajel csokentesnek van -e hatasa a reprodukalhatosagra.

Amit nem lehet megirni assemblyben, azt nem lehet megirni.

Mivel Matt szerint két teljesen eltérő CPU-n egyformán reprodukálható (12 magos Opteron talán 1,9 GHz, Phenom X4 asszem 3 GHz - a pontos típusok le vannak írva az eredeti levélben) ezért nem tartom esélyesnek. Nem jelterjedési hazárdnak tűnik, inkább valami ravasz corner-case.
---
Internet Memetikai Tanszék

Hu de kar volt beleneznem az assemblybe. Mar el is felejtettem milyen tragya az x86 (es sajna meg mindig ez a legnepszerubb asztali gepen). :(

Tudod, hogy kis 8 bites CPU-n hogyan emulálják a thread-eket?
(lefoglalnak előre X helyet a stacken, utána össze-vissza állítják előre-hátra a stack pointert)

Ez annyira természetes viselkedés, hogy még a valgrind sem jelez problémát.


#include <setjmp.h>
#include <stdio.h>

jmp_buf mainTask, childTask;

void thread1(void);
void thread2_init(void);
void thread2(void);

int main(void) {
  if (!setjmp(mainTask)) {
    thread2_init(); /* child never returns */ /* yield */
  } /* execution resumes after this "}" after first time that child yields */
  thread1();
}

void thread1(void) {
  for (;;) {
    printf("Parent\n");
    if (!setjmp(mainTask)) {
      longjmp(childTask, 1); /* yield - note that this is undefined under C99 */
    }
  }
}

void thread2_init (void) {
  char space[1000]; /* Reserve enough space for main to run */
  space[999] = 1; /* Do not optimize array out of existence */
  thread2();
}

void thread2 (void) {
  for (;;) {
    printf("Child loop begin\n");
    if (!setjmp(childTask)) longjmp(mainTask, 1); /* yield - invalidates childTask in C99 */

    printf("Child loop end\n");
    if (!setjmp(childTask)) longjmp(mainTask, 1); /* yield - invalidates childTask in C99 */
  }
  /* Don't return. Instead we should set a flag to indicate that main()
    should stop yielding to us and then longjmp(mainTask, 1) */
}