[{"data":1,"prerenderedAt":1776},["ShallowReactive",2],{"post-nanopi-r76s-router-2-5gbps-performance-speed-boost":3,"related-nanopi-r76s-router-2-5gbps-performance-speed-boost":1775},{"id":4,"title":5,"body":6,"categories":1755,"coverImage":1759,"date":1760,"description":1761,"extension":1762,"meta":1763,"navigation":377,"path":1764,"seo":1765,"stem":1766,"sticky":1767,"tags":1768,"__hash__":1774},"articles/nanopi-r76s-router-2-5gbps-performance-speed-boost.md","Ottimizzare le prestazioni del router NanoPi R76S con OpenWrt: da 600 Mbps a oltre 2 Gbps",{"type":7,"value":8,"toc":1735},"minimark",[9,37,42,57,68,79,83,90,95,131,150,153,157,164,167,197,201,204,233,238,265,271,273,277,288,292,300,303,329,336,339,454,456,460,467,480,782,788,804,806,810,816,829,1321,1325,1339,1341,1348,1355,1358,1442,1446,1460,1462,1466,1473,1476,1498,1500,1504,1515,1525,1566,1568,1572,1575,1625,1628,1636,1638,1642,1645,1698,1702,1708,1716,1731],[10,11,12,13,17,18,21,22,25,26,29,30,33,34,29],"p",{},"Questa settimana ho sostituito il mio amatissimo ",[14,15,16],"strong",{},"EdgeRouter X SFP"," (un router a mio avviso ottimo per qualità/prezzo ma purtroppo limitato a 1gbps)\ncon un ",[14,19,20],{},"NanoPi R76S",", un piccolo router ARMv8 basato su ",[14,23,24],{},"Rockchip RK3576",", pubblicizzato con porte ",[14,27,28],{},"2.5GbE",".",[31,32],"br",{},"\nSulla carta, doveva essere perfetto ma nella pratica… ",[14,35,36],{},"non lo era affatto",[38,39,41],"h2",{"id":40},"perché-ho-scelto-il-friendlyelec-nanopi-r76s","Perché ho scelto il FriendlyELEC NanoPi R76S",[10,43,44,45,48,49,52,53,56],{},"Quando ho deciso di sostituire il mio vecchio EdgeRouter X SFP, cercavo qualcosa di compatto, silenzioso e moderno, ma soprattutto ",[14,46,47],{},"abbastanza potente da gestire la mia nuova connessione 2.5gbps FTTH"," senza sudare troppo.\nDopo un po’ di ricerche mi sono imbattuto nel ",[14,50,51],{},"FriendlyELEC NanoPi R76S"," — un piccolo router con un look quasi da mini NUC, ma costruito attorno a un ",[14,54,55],{},"SoC Rockchip RK3576"," con ben otto core ARM (quattro Cortex-A76 e quattro Cortex-A55) e due porte Ethernet 2.5 GbE basate su chip Realtek RTL8125B.",[10,58,59,60,63,64,67],{},"Oltre alla potenza, mi ha convinto anche la forma fisica: ",[14,61,62],{},"il case in alluminio anodizzato nero",", le ",[14,65,66],{},"dimensioni davvero ridotte"," e il fatto che si alimenti tramite USB-C.\nNel mio piccolo armadietto server domestico — dove ogni centimetro e ogni alimentatore contano — questo dettaglio ha fatto la differenza.\nFinalmente niente più brick da 12 V con spinotto, ma un semplice cavo USB-C come quello di uno smartphone.",[10,69,70,71,74,75,78],{},"A bordo c’è ",[14,72,73],{},"FriendlyWrt",", la versione personalizzata di ",[14,76,77],{},"OpenWrt"," mantenuta da FriendlyELEC, che di base è già un ottimo punto di partenza.",[38,80,82],{"id":81},"la-delusione","La delusione",[10,84,85,86,89],{},"Dopo l’installazione pulita di ",[14,87,88],{},"FriendlyWrt 24.10 (OpenWrt 24.10)",", entusiasta di poter finalemnte testare la nuova conenssione multi-gigabit\nho eseguito i primi test con la CLI di Ookla (speedtest) pregustando già la soddisfazione di vedere schizzare la banda.",[10,91,92],{},[14,93,94],{},"I risultati sono stati deludenti:",[96,97,98,114],"table",{},[99,100,101],"thead",{},[102,103,104,108,111],"tr",{},[105,106,107],"th",{},"Test",[105,109,110],{},"Download",[105,112,113],{},"Upload",[115,116,117],"tbody",{},[102,118,119,125,128],{},[120,121,122],"td",{},[14,123,124],{},"Before tuning",[120,126,127],{},"606 Mbps",[120,129,130],{},"771 Mbps",[10,132,133,134,138,139,141,142,145,146,149],{},"Ho iniziato a fare dei test più approfonditi, ",[135,136,137],"code",{},"htop"," alla mano, e il collo di bottiglia era evidente: la CPU si saturava su un solo core durante i test, mentre gli altri restavano praticamente inattivi.",[31,140],{},"\nNonostante il ",[135,143,144],{},"flow_offloading"," fosse attivo nel firewall, ",[14,147,148],{},"il kernel non stava distribuendo correttamente gli interrupt (IRQ)"," delle interfacce di rete sui vari core.",[151,152],"hr",{},[38,154,156],{"id":155},"diagnosi-irq-rps-xps-e-cpu-governor","Diagnosi: IRQ, RPS, XPS e CPU governor",[10,158,159,160,163],{},"Il SoC ",[14,161,162],{},"RK3576"," supporta 8 core, ma senza una corretta gestione delle code e delle interrupt mask, OpenWrt tende ad assegnare tutto a un singolo core (con esattezza lo 0).",[10,165,166],{},"Ho quindi individuato tre aree di intervento:",[168,169,170,185,191],"ol",{},[171,172,173,176,177,180,181,184],"li",{},[14,174,175],{},"Distribuire gli IRQ"," delle interfacce di rete (",[135,178,179],{},"eth0",", ",[135,182,183],{},"eth1",") su più core CPU",[171,186,187,190],{},[14,188,189],{},"Abilitare e ottimizzare RPS/XPS"," (Receive/Transmit Packet Steering)",[171,192,193,196],{},[14,194,195],{},"Forzare la CPU in modalità “performance”"," per evitare scaling aggressivo della frequenza",[38,198,200],{"id":199},"️-tuning-v1-rpsxps-e-sysctl-base","⚙️ Tuning v1 — RPS/XPS e Sysctl base",[10,202,203],{},"La prima iterazione ha incluso:",[205,206,207,213,220,226],"ul",{},[171,208,209,210],{},"Abilitazione di ",[135,211,212],{},"net.core.rps_sock_flow_entries=65536",[171,214,215,216,219],{},"Configurazione di RPS e XPS su tutti i core (",[135,217,218],{},"0xff",")",[171,221,222,223],{},"Applicazione permanente via ",[135,224,225],{},"/etc/hotplug.d/net/99-optimize-network",[171,227,228,229,232],{},"Disattivazione di ",[135,230,231],{},"irqbalance"," per gestire manualmente le CPU affinity",[234,235,237],"h3",{"id":236},"risultato","Risultato",[96,239,240,250],{},[99,241,242],{},[102,243,244,246,248],{},[105,245,107],{},[105,247,110],{},[105,249,113],{},[115,251,252],{},[102,253,254,259,262],{},[120,255,256],{},[14,257,258],{},"Tuning v1",[120,260,261],{},"706 Mbps",[120,263,264],{},"928 Mbps",[10,266,267,268,270],{},"Il miglioramento è stato tangibile (almeno lato upload), ma non risolutivo.",[31,269],{},"\nLa saturazione CPU era distribuita meglio, ma ancora incompleta: i pacchetti non sfruttavano tutti i core disponibili.",[151,272],{},[38,274,276],{"id":275},"tuning-finale-irq-affinity-cpu-performance-mode","🔥 Tuning finale — IRQ affinity + CPU performance mode",[10,278,279,280,283,284,287],{},"Il tuning finale che porta ai ~2 Gbps stabili il ",[14,281,282],{},"NanoPi R76S (RK3576)"," con ",[14,285,286],{},"FriendlyWrt/OpenWrt 24.10"," richiede l'introduzione di diversi parametri finalizzati prevalentemente a distribuire il carico sui (tanti) core disponibili e distribuire i flussi di rete coerentemente.",[234,289,291],{"id":290},"_1️⃣-sysctl-tuning-del-network-stack","🧩 1️⃣  Sysctl – Tuning del network stack",[10,293,294,295],{},"📄 ",[14,296,297],{},[135,298,299],{},"/etc/sysctl.d/60-rps.conf",[10,301,302],{},"→ imposta le entry per i flussi RPS (Receive Packet Steering)",[304,305,310],"pre",{"className":306,"code":307,"language":308,"meta":309,"style":309},"language-bash shiki shiki-themes github-light github-dark","net.core.rps_sock_flow_entries = 65536\n","bash","",[135,311,312],{"__ignoreMap":309},[313,314,317,321,325],"span",{"class":315,"line":316},"line",1,[313,318,320],{"class":319},"sScJk","net.core.rps_sock_flow_entries",[313,322,324],{"class":323},"sZZnC"," =",[313,326,328],{"class":327},"sj4cs"," 65536\n",[10,330,294,331],{},[14,332,333],{},[135,334,335],{},"/etc/sysctl.d/99-network-tune.conf",[10,337,338],{},"→ parametri generali di rete + TCP tuning (coerenti con BBR)",[304,340,342],{"className":306,"code":341,"language":308,"meta":309,"style":309},"# Fair Queueing + congestion control\nnet.core.default_qdisc = fq\nnet.ipv4.tcp_congestion_control = bbr\n\n# TCP tuning generali\nnet.ipv4.tcp_fastopen = 3\nnet.ipv4.tcp_tw_reuse = 2\nnet.ipv4.ip_local_port_range = 10000 65535\nnet.ipv4.tcp_fin_timeout = 30\n\n# Gestione traffico burst\nnet.core.netdev_max_backlog = 250000\n",[135,343,344,350,361,372,379,385,396,407,421,432,437,443],{"__ignoreMap":309},[313,345,346],{"class":315,"line":316},[313,347,349],{"class":348},"sJ8bj","# Fair Queueing + congestion control\n",[313,351,353,356,358],{"class":315,"line":352},2,[313,354,355],{"class":319},"net.core.default_qdisc",[313,357,324],{"class":323},[313,359,360],{"class":323}," fq\n",[313,362,364,367,369],{"class":315,"line":363},3,[313,365,366],{"class":319},"net.ipv4.tcp_congestion_control",[313,368,324],{"class":323},[313,370,371],{"class":323}," bbr\n",[313,373,375],{"class":315,"line":374},4,[313,376,378],{"emptyLinePlaceholder":377},true,"\n",[313,380,382],{"class":315,"line":381},5,[313,383,384],{"class":348},"# TCP tuning generali\n",[313,386,388,391,393],{"class":315,"line":387},6,[313,389,390],{"class":319},"net.ipv4.tcp_fastopen",[313,392,324],{"class":323},[313,394,395],{"class":327}," 3\n",[313,397,399,402,404],{"class":315,"line":398},7,[313,400,401],{"class":319},"net.ipv4.tcp_tw_reuse",[313,403,324],{"class":323},[313,405,406],{"class":327}," 2\n",[313,408,410,413,415,418],{"class":315,"line":409},8,[313,411,412],{"class":319},"net.ipv4.ip_local_port_range",[313,414,324],{"class":323},[313,416,417],{"class":327}," 10000",[313,419,420],{"class":327}," 65535\n",[313,422,424,427,429],{"class":315,"line":423},9,[313,425,426],{"class":319},"net.ipv4.tcp_fin_timeout",[313,428,324],{"class":323},[313,430,431],{"class":327}," 30\n",[313,433,435],{"class":315,"line":434},10,[313,436,378],{"emptyLinePlaceholder":377},[313,438,440],{"class":315,"line":439},11,[313,441,442],{"class":348},"# Gestione traffico burst\n",[313,444,446,449,451],{"class":315,"line":445},12,[313,447,448],{"class":319},"net.core.netdev_max_backlog",[313,450,324],{"class":323},[313,452,453],{"class":327}," 250000\n",[151,455],{},[234,457,459],{"id":458},"️-2️⃣-script-principale-applica-rpsxps-manualmente","⚙️ 2️⃣  Script principale – Applica RPS/XPS manualmente",[10,461,294,462],{},[14,463,464],{},[135,465,466],{},"/usr/local/sbin/apply-rpsxps.sh",[10,468,469,470,473,474,476,477,479],{},"→ comando indipendente che puoi eseguire a mano o al boot\n(applica ",[135,471,472],{},"MASK=ff"," su ",[135,475,179],{}," e ",[135,478,183],{},", e imposta i flussi globali)",[304,481,483],{"className":306,"code":482,"language":308,"meta":309,"style":309},"#!/bin/sh\nMASK_HEX=ff\nFLOW_ENTRIES=65536\nDEVS=\"eth0 eth1\"\nlogger -t rpsxps \"start apply (devs: $DEVS)\"\n\nsysctl -q -w net.core.rps_sock_flow_entries=\"$FLOW_ENTRIES\"\n\nfor IF in $DEVS; do\n  for RX in /sys/class/net/$IF/queues/rx-*; do\n    [ -d \"$RX\" ] || continue\n    echo \"$MASK_HEX\" > \"$RX/rps_cpus\"\n    echo 32768 > \"$RX/rps_flow_cnt\" 2>/dev/null\n  done\n  for TX in /sys/class/net/$IF/queues/tx-*; do\n    [ -d \"$TX\" ] || continue\n    echo \"$MASK_HEX\" > \"$TX/xps_cpus\"\n  done\ndone\nlogger -t rpsxps \"done apply (mask=$MASK_HEX, flows=$FLOW_ENTRIES)\"\n",[135,484,485,490,503,513,523,543,547,567,571,588,612,638,660,683,689,710,730,750,755,761],{"__ignoreMap":309},[313,486,487],{"class":315,"line":316},[313,488,489],{"class":348},"#!/bin/sh\n",[313,491,492,496,500],{"class":315,"line":352},[313,493,495],{"class":494},"sVt8B","MASK_HEX",[313,497,499],{"class":498},"szBVR","=",[313,501,502],{"class":323},"ff\n",[313,504,505,508,510],{"class":315,"line":363},[313,506,507],{"class":494},"FLOW_ENTRIES",[313,509,499],{"class":498},[313,511,512],{"class":323},"65536\n",[313,514,515,518,520],{"class":315,"line":374},[313,516,517],{"class":494},"DEVS",[313,519,499],{"class":498},[313,521,522],{"class":323},"\"eth0 eth1\"\n",[313,524,525,528,531,534,537,540],{"class":315,"line":381},[313,526,527],{"class":319},"logger",[313,529,530],{"class":327}," -t",[313,532,533],{"class":323}," rpsxps",[313,535,536],{"class":323}," \"start apply (devs: ",[313,538,539],{"class":494},"$DEVS",[313,541,542],{"class":323},")\"\n",[313,544,545],{"class":315,"line":387},[313,546,378],{"emptyLinePlaceholder":377},[313,548,549,552,555,558,561,564],{"class":315,"line":398},[313,550,551],{"class":319},"sysctl",[313,553,554],{"class":327}," -q",[313,556,557],{"class":327}," -w",[313,559,560],{"class":323}," net.core.rps_sock_flow_entries=\"",[313,562,563],{"class":494},"$FLOW_ENTRIES",[313,565,566],{"class":323},"\"\n",[313,568,569],{"class":315,"line":409},[313,570,378],{"emptyLinePlaceholder":377},[313,572,573,576,579,582,585],{"class":315,"line":423},[313,574,575],{"class":498},"for",[313,577,578],{"class":494}," IF ",[313,580,581],{"class":498},"in",[313,583,584],{"class":494}," $DEVS; ",[313,586,587],{"class":498},"do\n",[313,589,590,593,596,598,601,604,607,610],{"class":315,"line":434},[313,591,592],{"class":498},"  for",[313,594,595],{"class":494}," RX ",[313,597,581],{"class":498},[313,599,600],{"class":323}," /sys/class/net/",[313,602,603],{"class":494},"$IF",[313,605,606],{"class":323},"/queues/rx-*",[313,608,609],{"class":494},"; ",[313,611,587],{"class":498},[313,613,614,617,620,623,626,629,632,635],{"class":315,"line":439},[313,615,616],{"class":494},"    [ ",[313,618,619],{"class":498},"-d",[313,621,622],{"class":323}," \"",[313,624,625],{"class":494},"$RX",[313,627,628],{"class":323},"\"",[313,630,631],{"class":494}," ] ",[313,633,634],{"class":498},"||",[313,636,637],{"class":498}," continue\n",[313,639,640,643,645,648,650,653,655,657],{"class":315,"line":445},[313,641,642],{"class":327},"    echo",[313,644,622],{"class":323},[313,646,647],{"class":494},"$MASK_HEX",[313,649,628],{"class":323},[313,651,652],{"class":498}," >",[313,654,622],{"class":323},[313,656,625],{"class":494},[313,658,659],{"class":323},"/rps_cpus\"\n",[313,661,663,665,668,670,672,674,677,680],{"class":315,"line":662},13,[313,664,642],{"class":327},[313,666,667],{"class":327}," 32768",[313,669,652],{"class":498},[313,671,622],{"class":323},[313,673,625],{"class":494},[313,675,676],{"class":323},"/rps_flow_cnt\"",[313,678,679],{"class":498}," 2>",[313,681,682],{"class":323},"/dev/null\n",[313,684,686],{"class":315,"line":685},14,[313,687,688],{"class":498},"  done\n",[313,690,692,694,697,699,701,703,706,708],{"class":315,"line":691},15,[313,693,592],{"class":498},[313,695,696],{"class":494}," TX ",[313,698,581],{"class":498},[313,700,600],{"class":323},[313,702,603],{"class":494},[313,704,705],{"class":323},"/queues/tx-*",[313,707,609],{"class":494},[313,709,587],{"class":498},[313,711,713,715,717,719,722,724,726,728],{"class":315,"line":712},16,[313,714,616],{"class":494},[313,716,619],{"class":498},[313,718,622],{"class":323},[313,720,721],{"class":494},"$TX",[313,723,628],{"class":323},[313,725,631],{"class":494},[313,727,634],{"class":498},[313,729,637],{"class":498},[313,731,733,735,737,739,741,743,745,747],{"class":315,"line":732},17,[313,734,642],{"class":327},[313,736,622],{"class":323},[313,738,647],{"class":494},[313,740,628],{"class":323},[313,742,652],{"class":498},[313,744,622],{"class":323},[313,746,721],{"class":494},[313,748,749],{"class":323},"/xps_cpus\"\n",[313,751,753],{"class":315,"line":752},18,[313,754,688],{"class":498},[313,756,758],{"class":315,"line":757},19,[313,759,760],{"class":498},"done\n",[313,762,764,766,768,770,773,775,778,780],{"class":315,"line":763},20,[313,765,527],{"class":319},[313,767,530],{"class":327},[313,769,533],{"class":323},[313,771,772],{"class":323}," \"done apply (mask=",[313,774,647],{"class":494},[313,776,777],{"class":323},", flows=",[313,779,563],{"class":494},[313,781,542],{"class":323},[10,783,784,785],{},"📌  ",[14,786,787],{},"Permessi:",[304,789,791],{"className":306,"code":790,"language":308,"meta":309,"style":309},"chmod +x /usr/local/sbin/apply-rpsxps.sh\n",[135,792,793],{"__ignoreMap":309},[313,794,795,798,801],{"class":315,"line":316},[313,796,797],{"class":319},"chmod",[313,799,800],{"class":323}," +x",[313,802,803],{"class":323}," /usr/local/sbin/apply-rpsxps.sh\n",[151,805],{},[234,807,809],{"id":808},"_3️⃣-hook-net-rpsxps-automatico-su-ogni-interfaccia","🔁 3️⃣  Hook NET – RPS/XPS automatico su ogni interfaccia",[10,811,294,812],{},[14,813,814],{},[135,815,225],{},[10,817,818,819,476,822,825,826,29],{},"Si attiva ogni volta che nasce una nuova interfaccia (eth*, VLAN, PPPoE).\nGarantisce che anche ",[135,820,821],{},"eth0.835",[135,823,824],{},"pppoe-wan"," ricevano ",[135,827,828],{},"rps_cpus=ff",[304,830,832],{"className":306,"code":831,"language":308,"meta":309,"style":309},"#!/bin/sh\n[ \"$ACTION\" = \"add\" ] || exit 0\ncase \"$DEVICENAME\" in eth*|pppoe-*) : ;; *) exit 0 ;; esac\n\nMASK_HEX=ff\nFLOW_ENTRIES=65536\nlogger -t rpsxps \"net hook: $DEVICENAME ACTION=$ACTION (mask=$MASK_HEX flows=$FLOW_ENTRIES)\"\nsysctl -q -w net.core.rps_sock_flow_entries=\"$FLOW_ENTRIES\"\n\nPARENT=\"$(basename \"$(readlink -f /sys/class/net/$DEVICENAME/lower_* 2>/dev/null || true)\")\"\n[ -n \"$PARENT\" ] || PARENT=\"$DEVICENAME\"\n\napply_one() {\n  IF=\"$1\"\n  for i in 1 2 3 4 5; do\n    [ -e \"/sys/class/net/$IF/queues/rx-0/rps_cpus\" ] && break\n    sleep 1\n  done\n  for RX in /sys/class/net/\"$IF\"/queues/rx-*; do\n    [ -e \"$RX/rps_cpus\" ] || continue\n    echo \"$MASK_HEX\" > \"$RX/rps_cpus\"\n    echo 32768 > \"$RX/rps_flow_cnt\" 2>/dev/null\n  done\n  for TX in /sys/class/net/\"$IF\"/queues/tx-*; do\n    [ -e \"$TX/xps_cpus\" ] || continue\n    echo \"$MASK_HEX\" > \"$TX/xps_cpus\"\n  done\n}\n\napply_one \"$PARENT\"\napply_one \"$DEVICENAME\"\n",[135,833,834,838,865,914,918,926,934,964,978,982,1026,1055,1059,1067,1081,1109,1130,1138,1142,1162,1181,1200,1219,1224,1244,1264,1283,1288,1294,1299,1310],{"__ignoreMap":309},[313,835,836],{"class":315,"line":316},[313,837,489],{"class":348},[313,839,840,843,845,848,850,852,855,857,859,862],{"class":315,"line":352},[313,841,842],{"class":494},"[ ",[313,844,628],{"class":323},[313,846,847],{"class":494},"$ACTION",[313,849,628],{"class":323},[313,851,324],{"class":498},[313,853,854],{"class":323}," \"add\"",[313,856,631],{"class":494},[313,858,634],{"class":498},[313,860,861],{"class":327}," exit",[313,863,864],{"class":327}," 0\n",[313,866,867,870,872,875,877,880,884,887,890,893,895,898,901,904,906,909,911],{"class":315,"line":363},[313,868,869],{"class":498},"case",[313,871,622],{"class":323},[313,873,874],{"class":494},"$DEVICENAME",[313,876,628],{"class":323},[313,878,879],{"class":498}," in",[313,881,883],{"class":882},"sA_wV"," eth",[313,885,886],{"class":498},"*|",[313,888,889],{"class":882},"pppoe-",[313,891,892],{"class":498},"*",[313,894,219],{"class":498},[313,896,897],{"class":327}," :",[313,899,900],{"class":494}," ;; ",[313,902,903],{"class":498},"*)",[313,905,861],{"class":327},[313,907,908],{"class":327}," 0",[313,910,900],{"class":494},[313,912,913],{"class":498},"esac\n",[313,915,916],{"class":315,"line":374},[313,917,378],{"emptyLinePlaceholder":377},[313,919,920,922,924],{"class":315,"line":381},[313,921,495],{"class":494},[313,923,499],{"class":498},[313,925,502],{"class":323},[313,927,928,930,932],{"class":315,"line":387},[313,929,507],{"class":494},[313,931,499],{"class":498},[313,933,512],{"class":323},[313,935,936,938,940,942,945,947,950,952,955,957,960,962],{"class":315,"line":398},[313,937,527],{"class":319},[313,939,530],{"class":327},[313,941,533],{"class":323},[313,943,944],{"class":323}," \"net hook: ",[313,946,874],{"class":494},[313,948,949],{"class":323}," ACTION=",[313,951,847],{"class":494},[313,953,954],{"class":323}," (mask=",[313,956,647],{"class":494},[313,958,959],{"class":323}," flows=",[313,961,563],{"class":494},[313,963,542],{"class":323},[313,965,966,968,970,972,974,976],{"class":315,"line":409},[313,967,551],{"class":319},[313,969,554],{"class":327},[313,971,557],{"class":327},[313,973,560],{"class":323},[313,975,563],{"class":494},[313,977,566],{"class":323},[313,979,980],{"class":315,"line":423},[313,981,378],{"emptyLinePlaceholder":377},[313,983,984,987,989,992,995,998,1001,1004,1006,1008,1011,1013,1015,1018,1020,1023],{"class":315,"line":434},[313,985,986],{"class":494},"PARENT",[313,988,499],{"class":498},[313,990,991],{"class":323},"\"$(",[313,993,994],{"class":319},"basename",[313,996,997],{"class":323}," \"$(",[313,999,1000],{"class":319},"readlink",[313,1002,1003],{"class":327}," -f",[313,1005,600],{"class":323},[313,1007,874],{"class":494},[313,1009,1010],{"class":323},"/lower_",[313,1012,892],{"class":327},[313,1014,679],{"class":498},[313,1016,1017],{"class":323},"/dev/null ",[313,1019,634],{"class":498},[313,1021,1022],{"class":327}," true",[313,1024,1025],{"class":323},")\")\"\n",[313,1027,1028,1030,1033,1035,1038,1040,1042,1044,1047,1049,1051,1053],{"class":315,"line":439},[313,1029,842],{"class":494},[313,1031,1032],{"class":498},"-n",[313,1034,622],{"class":323},[313,1036,1037],{"class":494},"$PARENT",[313,1039,628],{"class":323},[313,1041,631],{"class":494},[313,1043,634],{"class":498},[313,1045,1046],{"class":494}," PARENT",[313,1048,499],{"class":498},[313,1050,628],{"class":323},[313,1052,874],{"class":494},[313,1054,566],{"class":323},[313,1056,1057],{"class":315,"line":445},[313,1058,378],{"emptyLinePlaceholder":377},[313,1060,1061,1064],{"class":315,"line":662},[313,1062,1063],{"class":319},"apply_one",[313,1065,1066],{"class":494},"() {\n",[313,1068,1069,1072,1074,1076,1079],{"class":315,"line":685},[313,1070,1071],{"class":494},"  IF",[313,1073,499],{"class":498},[313,1075,628],{"class":323},[313,1077,1078],{"class":327},"$1",[313,1080,566],{"class":323},[313,1082,1083,1085,1088,1090,1093,1096,1099,1102,1105,1107],{"class":315,"line":691},[313,1084,592],{"class":498},[313,1086,1087],{"class":494}," i ",[313,1089,581],{"class":498},[313,1091,1092],{"class":323}," 1",[313,1094,1095],{"class":323}," 2",[313,1097,1098],{"class":323}," 3",[313,1100,1101],{"class":323}," 4",[313,1103,1104],{"class":323}," 5",[313,1106,609],{"class":494},[313,1108,587],{"class":498},[313,1110,1111,1113,1116,1119,1121,1124,1127],{"class":315,"line":712},[313,1112,616],{"class":494},[313,1114,1115],{"class":498},"-e",[313,1117,1118],{"class":323}," \"/sys/class/net/",[313,1120,603],{"class":494},[313,1122,1123],{"class":323},"/queues/rx-0/rps_cpus\"",[313,1125,1126],{"class":494}," ] && ",[313,1128,1129],{"class":498},"break\n",[313,1131,1132,1135],{"class":315,"line":732},[313,1133,1134],{"class":319},"    sleep",[313,1136,1137],{"class":327}," 1\n",[313,1139,1140],{"class":315,"line":752},[313,1141,688],{"class":498},[313,1143,1144,1146,1148,1150,1153,1155,1158,1160],{"class":315,"line":757},[313,1145,592],{"class":498},[313,1147,595],{"class":494},[313,1149,581],{"class":498},[313,1151,1152],{"class":323}," /sys/class/net/\"",[313,1154,603],{"class":494},[313,1156,1157],{"class":323},"\"/queues/rx-*",[313,1159,609],{"class":494},[313,1161,587],{"class":498},[313,1163,1164,1166,1168,1170,1172,1175,1177,1179],{"class":315,"line":763},[313,1165,616],{"class":494},[313,1167,1115],{"class":498},[313,1169,622],{"class":323},[313,1171,625],{"class":494},[313,1173,1174],{"class":323},"/rps_cpus\"",[313,1176,631],{"class":494},[313,1178,634],{"class":498},[313,1180,637],{"class":498},[313,1182,1184,1186,1188,1190,1192,1194,1196,1198],{"class":315,"line":1183},21,[313,1185,642],{"class":327},[313,1187,622],{"class":323},[313,1189,647],{"class":494},[313,1191,628],{"class":323},[313,1193,652],{"class":498},[313,1195,622],{"class":323},[313,1197,625],{"class":494},[313,1199,659],{"class":323},[313,1201,1203,1205,1207,1209,1211,1213,1215,1217],{"class":315,"line":1202},22,[313,1204,642],{"class":327},[313,1206,667],{"class":327},[313,1208,652],{"class":498},[313,1210,622],{"class":323},[313,1212,625],{"class":494},[313,1214,676],{"class":323},[313,1216,679],{"class":498},[313,1218,682],{"class":323},[313,1220,1222],{"class":315,"line":1221},23,[313,1223,688],{"class":498},[313,1225,1227,1229,1231,1233,1235,1237,1240,1242],{"class":315,"line":1226},24,[313,1228,592],{"class":498},[313,1230,696],{"class":494},[313,1232,581],{"class":498},[313,1234,1152],{"class":323},[313,1236,603],{"class":494},[313,1238,1239],{"class":323},"\"/queues/tx-*",[313,1241,609],{"class":494},[313,1243,587],{"class":498},[313,1245,1247,1249,1251,1253,1255,1258,1260,1262],{"class":315,"line":1246},25,[313,1248,616],{"class":494},[313,1250,1115],{"class":498},[313,1252,622],{"class":323},[313,1254,721],{"class":494},[313,1256,1257],{"class":323},"/xps_cpus\"",[313,1259,631],{"class":494},[313,1261,634],{"class":498},[313,1263,637],{"class":498},[313,1265,1267,1269,1271,1273,1275,1277,1279,1281],{"class":315,"line":1266},26,[313,1268,642],{"class":327},[313,1270,622],{"class":323},[313,1272,647],{"class":494},[313,1274,628],{"class":323},[313,1276,652],{"class":498},[313,1278,622],{"class":323},[313,1280,721],{"class":494},[313,1282,749],{"class":323},[313,1284,1286],{"class":315,"line":1285},27,[313,1287,688],{"class":498},[313,1289,1291],{"class":315,"line":1290},28,[313,1292,1293],{"class":494},"}\n",[313,1295,1297],{"class":315,"line":1296},29,[313,1298,378],{"emptyLinePlaceholder":377},[313,1300,1302,1304,1306,1308],{"class":315,"line":1301},30,[313,1303,1063],{"class":319},[313,1305,622],{"class":323},[313,1307,1037],{"class":494},[313,1309,566],{"class":323},[313,1311,1313,1315,1317,1319],{"class":315,"line":1312},31,[313,1314,1063],{"class":319},[313,1316,622],{"class":323},[313,1318,874],{"class":494},[313,1320,566],{"class":323},[10,1322,784,1323],{},[14,1324,787],{},[304,1326,1328],{"className":306,"code":1327,"language":308,"meta":309,"style":309},"chmod +x /etc/hotplug.d/net/99-optimize-network\n",[135,1329,1330],{"__ignoreMap":309},[313,1331,1332,1334,1336],{"class":315,"line":316},[313,1333,797],{"class":319},[313,1335,800],{"class":323},[313,1337,1338],{"class":323}," /etc/hotplug.d/net/99-optimize-network\n",[151,1340],{},[234,1342,1344,1345],{"id":1343},"_4️⃣-hook-iface-fallback-su-evento-ifup","🪝 4️⃣  Hook IFACE – Fallback su evento ",[135,1346,1347],{},"ifup",[10,1349,294,1350],{},[14,1351,1352],{},[135,1353,1354],{},"/etc/hotplug.d/iface/99-rpsxps",[10,1356,1357],{},"Serve come “cintura di sicurezza” in caso di ricreazione PPPoE o WAN da script esterni (es. DDNS)",[304,1359,1361],{"className":306,"code":1360,"language":308,"meta":309,"style":309},"#!/bin/sh\n[ \"$ACTION\" = \"ifup\" ] || exit 0\n\ncase \"$INTERFACE\" in\n  wan|lan)\n    /bin/sh -c \"sleep 1; /usr/local/sbin/apply-rpsxps.sh\"\n    ;;\nesac\n",[135,1362,1363,1367,1390,1394,1408,1422,1433,1438],{"__ignoreMap":309},[313,1364,1365],{"class":315,"line":316},[313,1366,489],{"class":348},[313,1368,1369,1371,1373,1375,1377,1379,1382,1384,1386,1388],{"class":315,"line":352},[313,1370,842],{"class":494},[313,1372,628],{"class":323},[313,1374,847],{"class":494},[313,1376,628],{"class":323},[313,1378,324],{"class":498},[313,1380,1381],{"class":323}," \"ifup\"",[313,1383,631],{"class":494},[313,1385,634],{"class":498},[313,1387,861],{"class":327},[313,1389,864],{"class":327},[313,1391,1392],{"class":315,"line":363},[313,1393,378],{"emptyLinePlaceholder":377},[313,1395,1396,1398,1400,1403,1405],{"class":315,"line":374},[313,1397,869],{"class":498},[313,1399,622],{"class":323},[313,1401,1402],{"class":494},"$INTERFACE",[313,1404,628],{"class":323},[313,1406,1407],{"class":498}," in\n",[313,1409,1410,1413,1416,1419],{"class":315,"line":381},[313,1411,1412],{"class":882},"  wan",[313,1414,1415],{"class":498},"|",[313,1417,1418],{"class":882},"lan",[313,1420,1421],{"class":498},")\n",[313,1423,1424,1427,1430],{"class":315,"line":387},[313,1425,1426],{"class":319},"    /bin/sh",[313,1428,1429],{"class":327}," -c",[313,1431,1432],{"class":323}," \"sleep 1; /usr/local/sbin/apply-rpsxps.sh\"\n",[313,1434,1435],{"class":315,"line":398},[313,1436,1437],{"class":494},"    ;;\n",[313,1439,1440],{"class":315,"line":409},[313,1441,913],{"class":498},[10,1443,784,1444],{},[14,1445,787],{},[304,1447,1449],{"className":306,"code":1448,"language":308,"meta":309,"style":309},"chmod +x /etc/hotplug.d/iface/99-rpsxps\n",[135,1450,1451],{"__ignoreMap":309},[313,1452,1453,1455,1457],{"class":315,"line":316},[313,1454,797],{"class":319},[313,1456,800],{"class":323},[313,1458,1459],{"class":323}," /etc/hotplug.d/iface/99-rpsxps\n",[151,1461],{},[234,1463,1465],{"id":1464},"_5️⃣-esecuzione-al-boot-failsafe","🚀 5️⃣  Esecuzione al boot (failsafe)",[10,1467,294,1468],{},[14,1469,1470],{},[135,1471,1472],{},"/etc/rc.local",[10,1474,1475],{},"Garantisce che lo script venga lanciato anche all’avvio completo del sistema (dopo init)",[304,1477,1479],{"className":306,"code":1478,"language":308,"meta":309,"style":309},"/usr/local/sbin/apply-rpsxps.sh || true\nexit 0\n",[135,1480,1481,1491],{"__ignoreMap":309},[313,1482,1483,1485,1488],{"class":315,"line":316},[313,1484,466],{"class":319},[313,1486,1487],{"class":498}," ||",[313,1489,1490],{"class":327}," true\n",[313,1492,1493,1496],{"class":315,"line":352},[313,1494,1495],{"class":327},"exit",[313,1497,864],{"class":327},[151,1499],{},[234,1501,1503],{"id":1502},"_6️⃣-opzionale-cpu-governor","🧠 6️⃣  (Opzionale) CPU governor",[10,1505,1506,1507,1510,1511,1514],{},"Se vuoi forzare il governor ",[14,1508,1509],{},"conservative"," o ",[14,1512,1513],{},"performance"," all’avvio:",[10,1516,294,1517,1521,1522,219],{},[14,1518,1519],{},[135,1520,1472],{}," (appendi sotto la riga ",[135,1523,1524],{},"apply-rpsxps.sh",[304,1526,1528],{"className":306,"code":1527,"language":308,"meta":309,"style":309},"for g in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor; do\n    echo conservative > \"$g\"\ndone\n",[135,1529,1530,1546,1562],{"__ignoreMap":309},[313,1531,1532,1534,1537,1539,1542,1544],{"class":315,"line":316},[313,1533,575],{"class":498},[313,1535,1536],{"class":494}," g ",[313,1538,581],{"class":498},[313,1540,1541],{"class":323}," /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor",[313,1543,609],{"class":494},[313,1545,587],{"class":498},[313,1547,1548,1550,1553,1555,1557,1560],{"class":315,"line":352},[313,1549,642],{"class":327},[313,1551,1552],{"class":323}," conservative",[313,1554,652],{"class":498},[313,1556,622],{"class":323},[313,1558,1559],{"class":494},"$g",[313,1561,566],{"class":323},[313,1563,1564],{"class":315,"line":363},[313,1565,760],{"class":498},[151,1567],{},[234,1569,1571],{"id":1570},"_7️⃣-verifica-post-boot","🧾 7️⃣  Verifica post-boot",[10,1573,1574],{},"Comandi di controllo:",[304,1576,1578],{"className":306,"code":1577,"language":308,"meta":309,"style":309},"logread -e rpsxps | tail -n 20\ngrep . /sys/class/net/eth{0,1}/queues/{rx,tx}-*/rps_cpus\nsysctl net.core.rps_sock_flow_entries\n",[135,1579,1580,1602,1618],{"__ignoreMap":309},[313,1581,1582,1585,1588,1590,1593,1596,1599],{"class":315,"line":316},[313,1583,1584],{"class":319},"logread",[313,1586,1587],{"class":327}," -e",[313,1589,533],{"class":323},[313,1591,1592],{"class":498}," |",[313,1594,1595],{"class":319}," tail",[313,1597,1598],{"class":327}," -n",[313,1600,1601],{"class":327}," 20\n",[313,1603,1604,1607,1610,1613,1615],{"class":315,"line":352},[313,1605,1606],{"class":319},"grep",[313,1608,1609],{"class":323}," .",[313,1611,1612],{"class":323}," /sys/class/net/eth{0,1}/queues/{rx,tx}-",[313,1614,892],{"class":327},[313,1616,1617],{"class":323},"/rps_cpus\n",[313,1619,1620,1622],{"class":315,"line":363},[313,1621,551],{"class":319},[313,1623,1624],{"class":323}," net.core.rps_sock_flow_entries\n",[10,1626,1627],{},"Output atteso:",[304,1629,1634],{"className":1630,"code":1632,"language":1633},[1631],"language-text","rpsxps: net hook: eth0.835 ACTION=add ...\nrpsxps: net hook: pppoe-wan ACTION=add ...\n...\n/sys/class/net/eth0.835/queues/rx-0/rps_cpus: ff\n/sys/class/net/eth0/queues/tx-0/xps_cpus: ff\n/sys/class/net/eth1/queues/tx-0/xps_cpus: ff\nnet.core.rps_sock_flow_entries = 65536\n","text",[135,1635,1632],{"__ignoreMap":309},[151,1637],{},[38,1639,1641],{"id":1640},"risultati-finali","🚀 Risultati finali",[10,1643,1644],{},"Dopo il reboot e una verifica completa dei parametri, il risultato è stato spettacolare:",[96,1646,1647,1657],{},[99,1648,1649],{},[102,1650,1651,1653,1655],{},[105,1652,107],{},[105,1654,110],{},[105,1656,113],{},[115,1658,1659,1670,1680],{},[102,1660,1661,1666,1668],{},[120,1662,1663],{},[14,1664,1665],{},"Before",[120,1667,127],{},[120,1669,130],{},[102,1671,1672,1676,1678],{},[120,1673,1674],{},[14,1675,258],{},[120,1677,261],{},[120,1679,264],{},[102,1681,1682,1687,1693],{},[120,1683,1684],{},[14,1685,1686],{},"Tuning finale",[120,1688,1689,1690],{},"🟢 ",[14,1691,1692],{},"2162 Mbps",[120,1694,1689,1695],{},[14,1696,1697],{},"1038 Mbps",[38,1699,1701],{"id":1700},"conclusioni","Conclusioni",[10,1703,1704,1705,1707],{},"Il ",[14,1706,20],{}," è un hardware eccezionale, ma per sfruttarlo al massimo serve una configurazione mirata.\nDi default, OpenWrt/FriendlyWrt non imposta:",[205,1709,1710,1713],{},[171,1711,1712],{},"IRQ affinity efficiente",[171,1714,1715],{},"RPS/XPS su tutti i core",[10,1717,1718,1719,1722,1723,1726,1727,29],{},"Con pochi accorgimenti, questo piccolo router passa da ",[14,1720,1721],{},"midrange"," a ",[14,1724,1725],{},"full 2.5 Gbps router",". In barba a cosa si possa pensare dei ",[1728,1729,1730],"em",{},"soft router",[1732,1733,1734],"style",{},"html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sA_wV, html code.shiki .sA_wV{--shiki-default:#032F62;--shiki-dark:#DBEDFF}",{"title":309,"searchDepth":352,"depth":352,"links":1736},[1737,1738,1739,1740,1743,1753,1754],{"id":40,"depth":352,"text":41},{"id":81,"depth":352,"text":82},{"id":155,"depth":352,"text":156},{"id":199,"depth":352,"text":200,"children":1741},[1742],{"id":236,"depth":363,"text":237},{"id":275,"depth":352,"text":276,"children":1744},[1745,1746,1747,1748,1750,1751,1752],{"id":290,"depth":363,"text":291},{"id":458,"depth":363,"text":459},{"id":808,"depth":363,"text":809},{"id":1343,"depth":363,"text":1749},"🪝 4️⃣  Hook IFACE – Fallback su evento ifup",{"id":1464,"depth":363,"text":1465},{"id":1502,"depth":363,"text":1503},{"id":1570,"depth":363,"text":1571},{"id":1640,"depth":352,"text":1641},{"id":1700,"depth":352,"text":1701},[1756,1757,1758],"networking","devops","hardware","https://i2.wp.com/enricodeleo.s3.eu-south-1.amazonaws.com/images/nanopi-r76s-performance.png","2025-10-05T09:00:00.000Z","Come ho ottimizzato il NanoPi R76S con OpenWrt per passare da 600 Mbps a oltre 2 Gbps reali, sistemando IRQ, RPS/XPS e CPU governor per sfruttare al massimo il SoC Rockchip RK3576.","md",{},"/nanopi-r76s-router-2-5gbps-performance-speed-boost",{"title":5,"description":1761},"nanopi-r76s-router-2-5gbps-performance-speed-boost",false,[1769,1770,1771,1772,1513,1773],"openwrt","nanopi","router","linux","tuning","RdJAYi52JTNcgoaJqjoKg-oDyw808HqOn6zwZojyAG8",[],1782776287907]