CodingBox Q&A Ask question

AFBR-89BDDZ QSFP28: SP/FPGA 인터페이스를 FIFO로 바꾸니 vendor 필드가 0905000000000000으로 나옴

Asked Active Viewed 38 AI translation from English
9

저희 자체 하드웨어의 스위치 관리 펌웨어를 관리하고 있는데, SP/FPGA 인터페이스를 메모리 매핑 버퍼에서 FIFO로 바꾼 뒤로 일부 포트에서 트랜시버 인벤토리가 쓰레기값으로 돌아오고 있어요.

  • QSFP28 광모듈, 전부 같은 배치의 AFBR-89BDDZ
  • 읽기는 서비스 프로세서와 FPGA 경로를 거쳐 모듈 EEPROM까지 감
  • 호스트 쪽 헬퍼 함수는 get_i2c_status_and_read_buffer: 상태 확인, 버퍼 전체 읽기, 상태 재확인

vendor 데이터 대신 나오는 값:

one port, vendor field: 0905000000000000
the next port, vendor field: all ones
on another machine: vendor field all zeros, elsewhere repeated digit characters

지금까지 해본 것:

  • 같은 포트를 연달아 여러 번 다시 읽어봤는데 쓰레기값이 무작위 노이즈가 아니라 포트별로 일정하게 나옴
  • 모듈 전원을 껐다 켜봤는데 차이 없음
  • 섀시 안 모든 모듈이 같은 파트넘버인 걸 확인했으니, 뭔가 특이한 vendor 블록을 저희가 잘못 디코딩하고 있는 건 아님

프로덕션에서 광모듈을 뽑기 시작하기 전에, 이게 모듈 쪽 문제일 가능성이 높을까요, I2C 경로일까요, 아니면 저희 쪽 read 헬퍼일까요?

Comments 7

Accepted answer

이건 딱 read 경로를 가리키고 있고, 원인은 FIFO로 바꾼 거예요. 메모리 매핑 버퍼는 몇 번을 물어봐도 같은 내용을 돌려주는데, FIFO는 바이트마다 딱 한 번만 내주고 그걸로 끝이에요. 물려받으신 get_i2c_status_and_read_buffer 시퀀스, 즉 상태 확인, 버퍼 전체 읽기, 상태 재확인은 뒤에 메모리가 있을 때는 말이 되지만 FIFO에서는 안 맞아요. 모듈의 EEPROM 읽기가 아직 선상에 있는 동안 큐를 비워버리거든요. 그 순간에 거기 있던 값이 뭐든 그게 나오고, 늦게 도착한 바이트는 뒤에 남았다가 다음 읽기에서 튀어나오는 거예요.

그게 딱 설명하신 그 특징이에요. 포트별로 일정한 쓰레기값, 시퀀스를 따라 이동하는 손상, 타이밍이 어떻게 맞아떨어지느냐에 따라 어떤 장비에서는 전부 0, 다른 장비에서는 반복되는 숫자 패턴이 나오는 것까지요. 여기엔 불량 모듈을 요구하는 부분이 하나도 없고, 어차피 스왑 결과로도 광모듈은 이미 배제되셨잖아요.

고치는 방법은 완료 확인 책임을 호출자한테 지우지 않는 거예요. 그 책임을 트랜시버 드라이버 자체의 read 루틴 안으로 옮기세요. I2C 트랜잭션이 완료를 보고할 때까지 기다렸다가 그때서야 버퍼를 건드리게 하면, 구조상 어떤 호출자도 미리 비울 수가 없어요. 호출 지점 하나만 패치하면 레이스가 다른 데로 옮겨갈 뿐이고요.

미리 말씀드리면 이건 몇 년간 검증된 게 아니라 제안하는 수정 형태 정도니까, 인벤토리를 다시 믿기 전에 본인 플랫폼에서 검증해보세요. 그래도 싸게 얻어가실 교훈은, 망가진 vendor 문자열을 보면 모듈 대 포트 테스트부터 해봐야 한다는 거예요. read 순서가 범인인 경우가 광모듈 자체보다 훨씬 많거든요.

5 United Stateslinkeng21US Show original (English) AI translation

이걸 반으로 딱 갈라줄 측정이 하나 있어요: 손상이 모듈을 따라가나요, 포트를 따라가나요? 0905000000000000을 돌려주는 포트에서 모듈을 빼서 정상적으로 읽히는 포트의 모듈이랑 바꿔 끼우고 둘 다 다시 읽어보세요. 이상한 문자열이 물리적 모듈을 따라가면 광모듈 쪽을 들여다봐야 하고요. 포트 번호에 그대로 남아 있거나, 더 나쁘게는 다음에 읽는 모듈로 계속 옮겨가면 모듈은 결백하고 호스트 쪽 read에 문제가 있는 거예요.

그 김에 디코딩된 필드랑 나란히 raw EEPROM 바이트도 덤프해보세요. 디코딩된 vendor 문자열은 쓰레기인데 밑에 깔린 바이트는 멀쩡한 것과, 바이트 자체가 쓰레기인 건 완전히 다른 버그예요.

0 SpainoptictechES Show original (English) AI translation

포트 한 쌍에 그 스왑을 해봤어요. 이상한 데이터는 모듈을 따라가지 않았어요. 0905000000000000을 돌려주던 포트는 다른 모듈을 꽂아도 계속 그 값을 돌려줬고, 빼낸 모듈은 새 슬롯에서 완벽하게 읽혔어요.

거기다 포트를 읽는 순서를 바꿔봤더니 손상이 시퀀스를 따라 옮겨가더라고요. 쓰레기값은 오작동하는 모듈 다음에 읽히는 모듈에 붙어요. 그러니까 이건 물리적 부품이 아니라 read 순서를 따라가는 거예요. raw 바이트도 틀리니까 저희 쪽 디코딩 문제도 아니고요.

2 KazakhstanrackhubKZ Show original (English) AI translation

원인은 다른데 함정은 똑같은, 드라이버 쪽 얘기를 하나 보태자면요. Intel E810-C에 out of tree ice 1.15.4를 쓰는데 QSFP28 광모듈에서 ethtool -m이 틀리고 불완전한 페이지를 내놨어요. page 1이랑 page 3 데이터, threshold랑 레인별 모니터 값이 모듈이 실제로 갖고 있는 값이랑 안 맞았어요. 제대로 된 근본 원인 설명은 결국 못 들었고, 스레드는 별 디테일 없이 해결됨으로 닫혔으니까 이건 정설이 아니라 그냥 사례 정도로 봐주세요.

제가 결국 한 일은 ice 드라이버와 E810 NVM을 nvmupdate64e로 업데이트하고, 다른 호스트의 in kernel ice 드라이버로 읽은 값과 교차 검증하고, 디코딩된 출력을 믿는 대신

ethtool -m <iface> hex on

처럼 오프셋과 길이를 명시해서 특정 페이지를 직접 뽑아낸 것이었어요. 플랫폼에서 raw 덤프가 가능하면 뭘 믿기 전에 raw와 디코딩 값을 먼저 비교해보세요.

1 Italylambdapilot72IT Show original (English) AI translation

레이어 구조를 한번 풀어서 적어둘 만해요, 이런 걸 추적할 때 훨씬 빨라지거든요. Linux에서 ethtool -m은 모듈 EEPROM을 디코딩하고(vendor 이름, OUI, part number, serial, date code, 모듈에 있으면 DDM 값까지), ethtool -e는 raw 바이트를 덤프하고, I2C 버스가 노출된 곳에서는 i2cdump -y 1 0x50이 A0h를, i2cdump -y 1 0x51이 A2h를 읽어요.

A0h에서 vendor 이름은 바이트 20-35에, PN, rev, SN은 40-59에 있어요. 그러니까 vendor 필드는 망가졌는데 그보다 스물몇 바이트 뒤에 있는 part number는 멀쩡하다면, 그것만으로도 EEPROM이 나쁜 게 아니라 read가 타이밍에 좌우된다는 뜻이 되고, 지금 보시는 것도 딱 그거예요.

이거랑 헷갈리면 안 되는 실패 유형이 하나 있는데요: ethtool -m이 Input/output error를 돌려주는 건 보통 그냥 DDM이 없는 모듈이에요. A0h의 바이트 92 비트 6이 A2h가 아예 있는지 없는지 알려주는 플래그인데, 그 체크는 존재하지도 않는 256바이트를 또 요청하러 가지 않게 하려고 예전에 in-kernel ixgbe랑 bnx2x 드라이버에 이미 들어가 있어요.

1 Russiasfpsmith28RU Show original (English) AI translation

SONiC 쪽에서 오신 분들을 위해 덧붙이면, 거기도 같은 종류의 문제가 있어요. sfputil show eeprom이 특정 모듈에 대해 Cannot get Module EEPROM data: Invalid argument라고 하거나, 같은 포트에 대해 show interfaces transceiver eeprom이랑 조용히 다른 값을 내놓기도 해요.

제가 겪어본 바로는 광모듈보다는 대부분 플랫폼이랑 드라이버 쪽 간극이에요. 두 명령이 202012 브랜치에서는 키 이름이 서로 안 맞았고 그건 202205에서 고쳐졌고요, 일부 플랫폼은 전원을 껐다 켜면 드라이버 수정이 들어오기 전까지 sfputil에서 QSFP 모듈이 사라지고, 다른 플랫폼에서는 get_transceiver_info가 아예 구현이 안 돼 있어요. 스크립팅할 때 믿을 만한 게 필요하면 저는 optoe 커널 드라이버로 가서 SFP, QSFP, CMIS EEPROM을 직접 raw로 읽어요. 그래도 본인 플랫폼에서 직접 확인해보세요, 플랫폼마다 동작이 꽤 달라요.

3 IndiagigengIN Show original (English) AI translation

저희 쪽 업데이트예요. 제안하신 대로 완료 확인을 드라이버 read 함수 안으로 옮겼더니, 예전에 서로 쓰레기값을 주고받던 두 포트를 포함해서 수백 번의 인벤토리 통과 동안 모든 포트에서 vendor 문자열이 맞게 나왔어요. raw 바이트도 이제 디코딩된 필드랑 일치하고요.

지금 단계에서는 완전히 끝났다기보다 부분 해결로 부를게요. 저희 트리에는 아직 안 들어간 패치로 들고 있는 상태고, 어디서든 믿기 전에 FPGA 빌드가 다른 플랫폼이 하나 더 있어서 그것도 검증해야 하거든요. 그래도 광모듈은 처음부터 멀쩡했던 거고, 그건 저 혼자였으면 틀렸을 부분이에요.

3 KazakhstanrackhubKZ Show original (English) AI translation
Log in to comment. Log in