SP/FPGA interface के FIFO में shift होने के बाद AFBR-89BDDZ QSFP28 का vendor field 0905000000000000 दिखाता है
हम अपने ही hardware पर switch management firmware देखते हैं, और जब से SP/FPGA interface को memory mapped buffers से बदलकर FIFO किया गया है, कुछ ports पर transceiver inventory कचरा बनकर वापस आ रही है।
- QSFP28 optics, सभी AFBR-89BDDZ, एक ही batch से
- reads service processor और FPGA वाले path से होते हुए module EEPROM तक जाते हैं
- host side वाला helper get_i2c_status_and_read_buffer है: status check करो, पूरा buffer पढ़ो, status फिर check करो
vendor data की जगह हमें यह मिलता है:
one port, vendor field: 0905000000000000
the next port, vendor field: all ones
on another machine: vendor field all zeros, elsewhere repeated digit characters
अब तक जो try किया:
- एक ही port को लगातार कई बार फिर से पढ़ा, और कचरा random noise की बजाय per-port stable रहता है
- modules को power cycle किया, कोई फर्क नहीं
- confirm किया कि chassis का हर module same part number है, तो यह हमारा किसी exotic vendor block को गलत decode करना नहीं है
production से optics निकालना शुरू करने से पहले, इसके modules होने, I2C path होने, या हमारे अपने read helper होने में से क्या ज्यादा संभावित है?
Comments 7
यह सीधे read path की तरफ इशारा करता है, और FIFO वाला बदलाव ही वजह है। memory mapped buffer आप चाहे जितनी बार पूछें, वही content लौटाता है; FIFO हर byte ठीक एक बार देता है और फिर वह चला जाता है। get_i2c_status_and_read_buffer को जो sequence विरासत में मिला, status check, पूरा buffer read, फिर status check, वह memory के पीछे होने पर समझ आता था और FIFO के साथ नहीं आता: यह queue को खाली कर देता है जबकि module का EEPROM read अभी भी wire पर होता है। आपको वही मिलता है जो उस पल वहां बैठा था, और जो bytes देर से पहुंचते हैं वे पीछे रह जाते हैं और अगले read में सामने आते हैं।
यह बिल्कुल वही fingerprint है जो आप describe कर रहे हैं। per-port stable कचरा, sequence के साथ-साथ चलता corruption, timing कैसे गिरती है इस पर निर्भर करते हुए एक machine पर सारे zeros और दूसरी पर repeated digit patterns। इसमें से किसी के लिए भी खराब module चाहिए नहीं, और आपका swap result वैसे भी optics को rule out कर देता है।
fix यह है कि caller को completion check के लिए ज़िम्मेदार बनाना बंद किया जाए। उस ज़िम्मेदारी को transceiver driver की खुद की read routine के अंदर ले जाइए: यह तब तक wait करे जब तक I2C transaction done report न करे, और तभी buffer को छुए, तो construction से ही कोई caller उसे जल्दी drain नहीं कर पाएगा। किसी एक call site को patch करना race को बस कहीं और धकेल देगा।
साफ चेतावनी दे दूं कि यह fix का proposed shape है, कोई ऐसी चीज़ नहीं जिसके पीछे सालों का अनुभव हो, तो inventory पर दोबारा भरोसा करने से पहले इसे अपने platform पर validate कीजिए। फिर भी ले जाने लायक सस्ता सबक: बिगड़ी हुई vendor strings को पहले module-बनाम-port test चाहिए, क्योंकि optics से कहीं ज्यादा बार असली culprit read order निकलता है।
एक measurement जो इसे बीच से बांट देता है: क्या corruption module के साथ रहता है या port के साथ? जो port
0905000000000000लौटा रहा है उससे module निकालिए, उसे किसी सही पढ़ने वाले port के module से swap कीजिए, और दोनों को फिर पढ़िए। अगर bad string physical module के साथ चलती है, तो जाकर optics देखिए। अगर यह port number पर ही रहती है, या इससे भी बुरा, अगले पढ़े जाने वाले जो भी module हो उसके साथ आगे बढ़ जाती है, तो modules बेकसूर हैं और आपके पास host read की problem है।वहां हैं तो raw EEPROM bytes को decoded fields के साथ dump कीजिए। एक decoded vendor string में कचरा जिसके नीचे sane bytes हों, वह बिल्कुल अलग bug है खुद bytes में कचरे से।
ports की एक जोड़ी पर वह swap करके देखा। bad data module के साथ नहीं गई: जो port
0905000000000000लौटा रहा था वह दूसरा module बैठाने पर भी वही लौटाता रहा, और जो module हमने निकाला वह अपने नए slot में बिल्कुल ठीक पढ़ा।इससे भी बेहतर, जब हमने ports पढ़े जाने का order बदला, तो corruption sequence के साथ move हो गया। कचरा उसी module पर आकर बैठता है जो misbehave करने वाले module के बाद पढ़ा जाता है। यानी यह read order को track करता है, physical part को नहीं। Raw bytes भी गलत हैं, तो यह हमारी तरफ की decode problem नहीं है।
अलग root cause, वही trap, बस driver वाले side से। एक Intel E810-C पर, out of tree ice 1.15.4 के साथ, मुझे QSFP28 optics पर
ethtool -mसे गलत और अधूरे pages मिले: page 1 और page 3 का data, thresholds और per lane monitors, module असल में जो रखता था उससे match नहीं करते थे। मुझे इसका कोई ठीक root cause statement कभी नहीं मिला, thread बिना ज्यादा detail के solved मानकर बंद कर दिया गया था, तो इसे गॉस्पेल की बजाय anecdote समझिए।आखिर में मैंने जो किया वह था ice driver और E810 NVM को
nvmupdate64eसे update करना, दूसरे host पर in-kernel ice driver से मिले read के साथ cross-check करना, और decoded output पर भरोसा करने की बजायके साथ specific pages निकालना, साथ में explicit offset और length। अगर आपका platform raw dump कर सकता है, तो किसी एक पर भरोसा करने से पहले raw को decoded से compare कीजिए।
layering को खोलकर बताना ज़रूरी है, क्योंकि इससे इस तरह की खोज काफी छोटी हो जाती है। Linux पर
ethtool -mmodule EEPROM decode करता है (vendor name, OUI, part number, serial, date code, और जब module के पास हों तो DDM values),ethtool -eraw bytes dump करता है, और जहां I2C bus exposed है वहांi2cdump -y 1 0x50A0h पढ़ता है जबकिi2cdump -y 1 0x51A2h पढ़ता है।A0h में vendor name bytes 20-35 में रहता है और PN, rev और SN 40-59 में। तो अगर vendor field बिगड़ा हुआ है और उससे दो दर्जन bytes आगे part number ठीक-ठाक है, तो यह अकेले ही बताता है कि read timing पर निर्भर है, EEPROM खराब होने की बजाय, जो आप जो देख रहे हैं उससे मेल खाता है।
एक failure जिसे इसके साथ भ्रमित न करें:
ethtool -mका Input/output error लौटाना आमतौर पर बस एक ऐसा module है जिसमें DDM नहीं है। A0h का byte 92 bit 6 यह flag है कि A2h मौजूद है भी या नहीं, और वह test in-kernel ixgbe और bnx2x drivers में बहुत पहले डाला गया था ताकि वे ऐसे 256 और bytes के लिए हाथ बढ़ाना बंद कर दें जो मौजूद ही नहीं हैं।SONiC boxes पर वही genre की problem, अगर कोई उस side से यहां पहुंचे।
sfputil show eepromकुछ modules के लिए Cannot get Module EEPROM data: Invalid argument कहता है, या उसी port पर चुपचापshow interfaces transceiver eepromसे असहमत हो जाता है।मुझे जो मिला है उससे यह ज्यादातर optics की बजाय platform और driver के gaps हैं: दोनों commands ने 202012 branch में असंगत key names इस्तेमाल कीं और वह 202205 में ठीक हुआ, कुछ platforms driver fix आने तक power cycle के बाद sfputil से QSFP modules खो देते हैं, और दूसरों पर get_transceiver_info बस implement ही नहीं है। जब मुझे scripting के लिए भरोसे लायक कुछ चाहिए होता है तो मैं optoe kernel driver पर जाता हूं और SFP, QSFP या CMIS EEPROM की raw reads खुद करता हूं। फिर भी अपने platform पर check कर लीजिए, व्यवहार इनके बीच काफी अलग होता है।
हमारी तरफ से update। जैसा सुझाया गया था वैसे हमने completion check को driver read function के अंदर ले गए, और कुछ सौ inventory passes में हर port पर vendor strings सही रही हैं, उन दो ports समेत जो पहले आपस में कचरा अदला-बदली करते थे। Raw bytes अब decoded fields से match करते हैं।
फिलहाल मैं इसे closed की बजाय partial कह रहा हूं: हम इसे एक ऐसे patch के तौर पर ले जा रहे हैं जो अभी हमारे tree में नहीं पहुंचा, और हर जगह इस पर भरोसा करने से पहले एक और platform बाकी है जिसमें अलग FPGA build है, उसे verify करना है। पर optics शुरू से ठीक थीं, यही वह हिस्सा है जिसे मैं अपने आप गलत समझ बैठता।