Campo vendor do AFBR-89BDDZ QSFP28 lê 0905000000000000 depois que a interface SP/FPGA passou para FIFO
A gente cuida do firmware de gerenciamento do switch no nosso próprio hardware, e desde que a interface SP/FPGA mudou de buffers mapeados em memória para uma FIFO, o inventário de transceivers vem voltando como lixo em algumas portas.
- óptica QSFP28, todas AFBR-89BDDZ do mesmo lote
- as leituras passam pelo caminho do service processor e da FPGA até a EEPROM do módulo
- o helper do lado host é get_i2c_status_and_read_buffer: checa status, lê o buffer inteiro, checa status de novo
O que a gente recebe no lugar dos dados de vendor:
one port, vendor field: 0905000000000000
the next port, vendor field: all ones
on another machine: vendor field all zeros, elsewhere repeated digit characters
O que já tentamos até agora:
- reler a mesma porta várias vezes seguidas, e o lixo é estável por porta em vez de ruído aleatório
- ciclamos a energia dos módulos, sem diferença
- confirmamos que todo módulo no chassi é o mesmo part number, então não é a gente decodificando errado algum bloco de vendor exótico
Antes de começar a tirar óptica de produção, é mais provável que seja os módulos, o caminho I2C, ou o nosso próprio helper de leitura?
Comments 7
Isso aponta direto para o caminho de leitura, e a mudança para FIFO é o motivo. Um buffer mapeado em memória devolve o mesmo conteúdo não importa quantas vezes você pergunte; uma FIFO entrega cada byte exatamente uma vez e depois ele se foi. A sequência que o get_i2c_status_and_read_buffer herdou, checar status, ler o buffer inteiro, checar status de novo, fazia sentido com memória por trás e não faz com uma FIFO: ela esvazia a fila enquanto a leitura da EEPROM do módulo ainda está no fio. Você pega o que estava ali naquele instante, e os bytes que chegam atrasados ficam para trás e aparecem na próxima leitura.
Essa é exatamente a impressão digital que você descreve. Lixo estável por porta, corrupção andando junto com a sequência, tudo zero numa máquina e padrões de dígito repetidos em outra dependendo de como o timing cai. Nada disso exige um módulo ruim, e o resultado da sua troca já descarta a óptica de qualquer jeito.
O conserto é parar de deixar quem chama responsável pela checagem de conclusão. Mova essa responsabilidade para dentro da própria rotina de leitura do driver do transceiver: ela espera até a transação I2C reportar concluído e só então toca o buffer, então nenhum chamador consegue esvaziar ela cedo demais por construção. Remendar um único ponto de chamada só empurraria a corrida para outro lugar.
Aviso justo que essa é a forma proposta do conserto e não algo com anos de uso, então valide no seu próprio hardware antes de confiar de novo no inventário. Mas fica a lição barata: strings de vendor bagunçadas merecem primeiro um teste módulo-contra-porta, porque a ordem de leitura acaba sendo a culpada bem mais vezes que a óptica.
A medida que divide isso ao meio: a corrupção fica com o módulo ou com a porta? Tire o módulo da porta que retorna
0905000000000000, troque ele por um módulo de uma porta que lê certo, e releia as duas. Se a string ruim segue o módulo físico, vá olhar a óptica. Se ela fica no número da porta, ou pior, se move junto para qualquer módulo que for lido em seguida, os módulos estão inocentes e você tem um problema de leitura no host.Já que está nisso, tire um dump dos bytes crus da EEPROM junto com os campos decodificados. Lixo numa string de vendor decodificada com bytes sãos por baixo é um bug completamente diferente de lixo nos próprios bytes.
Rodei essa troca num par de portas. O dado ruim não se moveu com o módulo: a porta que retornava
0905000000000000continuou retornando isso com um módulo diferente encaixado, e o módulo que tiramos leu perfeitamente no novo slot dele.Melhor ainda, quando mudamos a ordem em que as portas são lidas, a corrupção se moveu junto com a sequência. O lixo cai em cima de qualquer módulo que seja lido depois daquele que se comporta mal. Então ela segue a ordem de leitura, não a peça física. Os bytes crus também estão errados, então não é um problema de decodificação do nosso lado.
Causa raiz diferente, mesma armadilha, do lado do driver. Num Intel E810-C com o ice 1.15.4 fora da árvore, eu recebia páginas erradas e incompletas do
ethtool -mem óptica QSFP28: os dados das páginas 1 e 3, thresholds e monitores por lane, não batiam com o que o módulo realmente guarda. Nunca consegui tirar disso uma causa raiz de verdade, a thread foi fechada como resolvida sem muito detalhe, então trate isso como anedota e não como verdade absoluta.O que acabei fazendo foi atualizar o driver ice e a NVM da E810 com
nvmupdate64e, conferir cruzado com uma leitura do driver ice do próprio kernel em outro host, e puxar páginas específicas commais offset e tamanho explícitos, em vez de confiar na saída decodificada. Se a sua plataforma consegue fazer um dump cru, compare o cru contra o decodificado antes de acreditar em qualquer um dos dois.
Vale detalhar as camadas, porque isso encurta bastante esse tipo de caçada. No Linux o
ethtool -mdecodifica a EEPROM do módulo (nome do vendor, OUI, part number, serial, date code, e valores de DDM quando o módulo tem), oethtool -edespeja os bytes crus, e onde o barramento I2C está exposto oi2cdump -y 1 0x50lê o A0h enquanto oi2cdump -y 1 0x51lê o A2h.No A0h o nome do vendor mora nos bytes 20-35 e PN, rev e SN nos 40-59. Então se o campo de vendor está bagunçado e o part number duas dúzias de bytes à frente está intacto, isso sozinho já diz que a leitura depende de timing em vez de a EEPROM estar ruim, o que bate com o que você está vendo.
Uma falha para não confundir com essa: o
ethtool -mretornando Input/output error normalmente é só um módulo sem DDM. O byte 92 bit 6 do A0h é a flag para se o A2h existe ou não, e esse teste foi colocado nos drivers ixgbe e bnx2x do próprio kernel há muito tempo para eles pararem de buscar mais 256 bytes que não existem.Mesmo gênero de problema em caixas SONiC, para quem estiver chegando desse lado. O
sfputil show eepromdiz Cannot get Module EEPROM data: Invalid argument para certos módulos, ou discorda discretamente doshow interfaces transceiver eepromna mesma porta.Pelo que já vi, isso é principalmente lacuna de plataforma e driver e não da óptica: os dois comandos usavam nomes de chave inconsistentes na branch 202012 e isso foi corrigido na 202205, algumas plataformas perdem os módulos QSFP do sfputil depois de um power cycle até um fix de driver chegar, e em outras o get_transceiver_info simplesmente não está implementado. Quando preciso de algo em que confiar para scripting, vou no driver de kernel optoe e faço eu mesmo leituras cruas da EEPROM SFP, QSFP ou CMIS. Mas confira na sua própria plataforma, o comportamento varia bastante entre elas.
Atualização do nosso lado. Movemos a checagem de conclusão para dentro da função de leitura do driver como sugerido, e as strings de vendor têm saído corretas em toda porta ao longo de umas centenas de passadas de inventário, incluindo as duas portas que antes trocavam lixo entre si. Os bytes crus batem com os campos decodificados agora.
Por enquanto estou chamando isso de parcial e não de fechado: estamos carregando como um patch que ainda não entrou na nossa árvore, e falta verificar em mais uma plataforma com uma build de FPGA diferente antes de confiar nisso em tudo. Mas a óptica estava certa o tempo todo, que é a parte que eu teria errado sozinho.