У AFBR-89BDDZ QSFP28 поле vendor читается как 0905000000000000 после перевода интерфейса SP/FPGA на FIFO
Мы сами занимаемся управляющей прошивкой коммутатора на своём железе, и с тех пор как интерфейс SP/FPGA перевели с буферов с отображением в память на FIFO, инвентаризация трансиверов на некоторых портах стала возвращать мусор.
- оптика QSFP28, вся AFBR-89BDDZ из одной партии
- чтение идёт через тракт service processor и FPGA к EEPROM модуля
- хостовый хелпер get_i2c_status_and_read_buffer: проверить статус, прочитать весь буфер, снова проверить статус
Вместо данных вендора получаем:
one port, vendor field: 0905000000000000
the next port, vendor field: all ones
on another machine: vendor field all zeros, elsewhere repeated digit characters
Что уже пробовали:
- перечитывали один и тот же порт несколько раз подряд, и мусор стабилен для каждого порта, а не случайный шум
- перезапитывали модули - без изменений
- подтвердили, что все модули в шасси одного и того же партномера, так что дело не в том, что мы неправильно декодируем какой-то экзотический блок вендора
Прежде чем начинать вытаскивать оптику из продакшна: это скорее модули, тракт I2C, или наш собственный хелпер чтения?
Comments 7
Это прямо указывает на тракт чтения, и причина - переход на FIFO. Буфер с отображением в память возвращает одно и то же содержимое, сколько бы раз вы его ни спрашивали; FIFO отдаёт каждый байт ровно один раз, а потом его уже нет. Последовательность, унаследованная get_i2c_status_and_read_buffer, - проверка статуса, полное чтение буфера, снова проверка статуса - имела смысл, когда за ней стояла память, и не имеет смысла с FIFO: она опустошает очередь, пока чтение EEPROM модуля ещё идёт по шине. Вы получаете то, что там оказалось в этот момент, а байты, пришедшие позже, остаются и всплывают при следующем чтении.
Это в точности тот отпечаток, что вы описываете. Стабильный мусор на порт, повреждение, кочующее вместе с последовательностью, все нули на одной машине и повторяющиеся цифровые паттерны на другой в зависимости от того, как легла синхронизация. Ничто из этого не требует плохого модуля, да и результат вашей замены сам по себе снимает подозрение с оптики.
Исправление - перестать перекладывать проверку завершения на вызывающую сторону. Перенесите эту ответственность внутрь функции чтения самого драйвера трансивера: она ждёт, пока транзакция I2C не сообщит о завершении, и только тогда трогает буфер, так что ни один вызывающий не сможет опустошить его раньше времени просто по конструкции. Патч одной точки вызова только сдвинул бы гонку в другое место.
Честное предупреждение: это предложенная форма исправления, а не что-то с многолетней историей за плечами, так что проверьте её на своей платформе, прежде чем снова доверять инвентаризации. Дешёвый урок на будущее: искажённые строки вендора заслуживают сначала теста модуль-против-порта, потому что порядок чтения оказывается виновником гораздо чаще, чем сама оптика.
Одно измерение, которое разделит это пополам: повреждение остаётся с модулем или с портом? Выньте модуль из порта, возвращающего
0905000000000000, поменяйте его местами с модулем из порта, который читается правильно, и перечитайте оба. Если плохая строка следует за физическим модулем, идите смотреть на оптику. Если она остаётся при номере порта, или, того хуже, переезжает на тот модуль, который читается следующим, модули невиновны, и у вас проблема чтения на хосте.Раз уж вы туда полезли, снимите сырые байты EEPROM вместе с декодированными полями. Мусор в декодированной строке вендора при исправных сырых байтах под ней - это совершенно другой баг, чем мусор в самих байтах.
Прогнал эту замену на паре портов. Плохие данные не переехали вместе с модулем: порт, возвращавший
0905000000000000, продолжал его возвращать с другим установленным модулем, а вынутый модуль отлично читался на новом месте.Более того: когда мы поменяли порядок опроса портов, повреждение переехало вместе с последовательностью. Мусор оказывается на том модуле, который читается сразу после проблемного. То есть оно следует за порядком чтения, а не за физической деталью. Сырые байты тоже неверны, так что это не проблема декодирования на нашей стороне.
Другая первопричина, та же ловушка, но со стороны драйвера. На Intel E810-C с внекодерным ice 1.15.4 я получал неправильные и неполные страницы из
ethtool -mна оптике QSFP28: данные страницы 1 и страницы 3, пороги и показания по линиям не совпадали с тем, что реально хранится в модуле. Внятной первопричины я так и не добился, тема была закрыта как решённая без особых подробностей, так что относитесь к этому скорее как к анекдоту, чем как к истине.В итоге я обновил драйвер ice и NVM E810 через
nvmupdate64e, сверил со чтением через встроенный в ядро драйвер ice на другом хосте, и вытаскивал конкретные страницы черезс явным смещением и длиной, вместо того чтобы доверять декодированному выводу. Если ваша платформа умеет снимать сырой дамп, сравнивайте сырые данные с декодированными, прежде чем верить любому из них.
Стоит проговорить уровни, потому что это заметно ускоряет такой поиск. В Linux
ethtool -mдекодирует EEPROM модуля (имя вендора, OUI, партномер, серийный номер, дата, значения DDM, если модуль их имеет),ethtool -eснимает сырые байты, а там, где шина I2C доступна напрямую,i2cdump -y 1 0x50читает A0h, аi2cdump -y 1 0x51читает A2h.В A0h имя вендора живёт в байтах 20-35, а PN, ревизия и SN - в 40-59. Так что если поле вендора искажено, а партномер двумя десятками байт дальше цел, это само по себе говорит, что чтение зависит от синхронизации, а не что EEPROM неисправен - что и совпадает с тем, что вы наблюдаете.
Одну неисправность не стоит путать с этой:
ethtool -m, возвращающий Input/output error, обычно означает просто модуль без DDM. Бит 6 байта 92 в A0h - это флаг того, есть ли вообще A2h, и эту проверку давным-давно встроили во внутриядерные драйверы ixgbe и bnx2x, чтобы они перестали лезть за ещё 256 байтами, которых не существует.Та же порода проблемы на коробках SONiC, для тех, кто пришёл с этой стороны.
sfputil show eepromдля некоторых модулей выдаёт Cannot get Module EEPROM data: Invalid argument, или тихо расходится сshow interfaces transceiver eepromна том же порту.По моему опыту это в основном пробелы платформы и драйвера, а не оптика: эти две команды использовали несогласованные имена ключей в ветке 202012, и это починили в 202205, на некоторых платформах модули QSFP пропадают из sfputil после перезапитки, пока не выйдет патч драйвера, а на других get_transceiver_info просто не реализован. Когда мне нужно что-то, чему можно доверять для скриптов, я иду к драйверу ядра optoe и сам делаю сырые чтения EEPROM SFP, QSFP или CMIS. Но проверяйте на своей платформе, поведение сильно разнится.
Новости с нашей стороны. Мы перенесли проверку завершения в функцию чтения драйвера, как предлагалось, и строки вендора были корректными на каждом порту за несколько сотен проходов инвентаризации, включая те два порта, что раньше обменивались мусором между собой. Сырые байты теперь совпадают с декодированными полями.
Пока называю это частичным решением, а не закрытым: мы несём это как патч, который ещё не попал в наше дерево, и есть ещё одна платформа с другой сборкой FPGA, которую нужно проверить, прежде чем доверять этому везде. Но оптика всё это время была в порядке, и вот это я бы сам ошибочно заподозрил.