2015-07-21 15 views
5

Sono in esecuzione le misurazioni iperf tra due server, collegate tramite collegamento 10Gbit. Sto cercando di correlare la dimensione massima della finestra che osservo con i parametri di configurazione del sistema.Dimensioni della finestra di ricezione TCP superiori a net.core.rmem_max

In particolare, ho osservato che la dimensione massima della finestra è 3 MiB. Tuttavia, non riesco a trovare i valori corrispondenti nei file di sistema.

Eseguendo sysctl -a Ottengo i seguenti valori:

net.ipv4.tcp_rmem = 4096  87380 6291456 
net.core.rmem_max = 212992 

Il primo valore ci dice che la dimensione massima finestra del ricevitore è di 6 MiB. Tuttavia, TCP tende ad allocare il doppio della dimensione richiesta, quindi la dimensione massima della finestra del ricevitore dovrebbe essere 3 MiB, esattamente come l'ho misurata. Da man tcp:

noti che TCP effettivamente alloca due volte la dimensione del buffer richiesto nel setsockopt (2) chiamata, e quindi una getsockopt successivo (2) chiamata non restituirà la stessa dimensione del buffer come richiesto nella setockopt (2) chiamata. TCP utilizza lo spazio aggiuntivo per scopi amministrativi e strutture interne del kernel, ei valori del file/proc riflettono le dimensioni maggiori rispetto alle finestre TCP effettive.

Tuttavia, il secondo valore, net.core.rmem_max, indica che la dimensione massima della finestra del destinatario non può essere superiore a 208 KiB. E questo dovrebbe essere il limite rigido, secondo man tcp:

tcp_rmem max: la dimensione massima del buffer di ricezione utilizzato da ogni socket TCP. Questo valore non sostituisce il numero globale net.core.rmem_max. Questo non viene utilizzato per limitare la dimensione del buffer di ricezione dichiarato utilizzando SO_RCVBUF su un socket.

Quindi, come mai viene visualizzata una dimensione massima della finestra maggiore di quella specificata in net.core.rmem_max?

NB: Ho anche calcolato il prodotto Latenza larghezza banda: window_size = Bandwidth x RTT che è di circa 3 MiB (10 Gbps @ 2 msec RTT), verificando quindi la mia cattura del traffico.

risposta

1

net.ipv4.tcp_rmem ha la precedenza net.core.rmem_max secondo le https://serverfault.com/questions/734920/difference-between-net-core-rmem-max-and-net-ipv4-tcp-rmem:

Sembra che il tcp-impostazione avrà la precedenza sugli l'impostazione


max comune, ma sono d'accordo con quello che dici, questo sembra essere in conflitto con ciò che è scritto in man tcp e posso riprodurre i risultati. Forse la documentazione è sbagliata? Si prega di scoprire e commentare!

+1

ho iniziato una taglia per scoprire se 'man tcp' è veramente sbagliato. – nh2

4

Una rapida ricerca alzato:

https://github.com/torvalds/linux/blob/4e5448a31d73d0e944b7adb9049438a09bc332cb/net/ipv4/tcp_output.c

in void tcp_select_initial_window()

if (wscale_ok) { 
    /* Set window scaling on max possible window 
    * See RFC1323 for an explanation of the limit to 14 
    */ 
    space = max_t(u32, sysctl_tcp_rmem[2], sysctl_rmem_max); 
    space = min_t(u32, space, *window_clamp); 
    while (space > 65535 && (*rcv_wscale) < 14) { 
     space >>= 1; 
     (*rcv_wscale)++; 
    } 
} 

max_t assume il valore più alto degli argomenti. Quindi il valore più grande ha la precedenza qui.

Un altro riferimento a sysctl_rmem_max viene eseguito dove viene utilizzato per limitare l'argomento a SO_RCVBUF (in net/core/sock.c).

Tutti gli altri codici tcp si riferiscono solo a sysctl_tcp_rmem.

Quindi, senza guardare più in profondità il codice è possibile concludere che un più grande net.ipv4.tcp_rmem annulleranno net.core.rmem_max in tutti i casi, tranne quando si imposta SO_RCVBUF (il cui controllo può essere bypassato usando SO_RCVBUFFORCE)

+0

'... si può concludere che un net.ipv4.tcp_rmem più grande sovrascriverà net.core.rmem_max in tutti i casi tranne quando si imposta SO_RCVBUF' - non mi è ancora chiaro se ciò avvenga in tutti i casi: nella funzione che hai postato , 'max_t (u32, sysctl_tcp_rmem [2], sysctl_rmem_max)' determina 'rcv_wscale', che viene quindi utilizzato per impostare le dimensioni della finestra. Quindi il massimo dei due valori dovrebbe essere usato per tutto il tempo. Tuttavia, non posso confermare sperimentalmente che: l'impostazione di 'net.core.rmem_max' molto grande non aumenta la dimensione della finestra oltre il massimo di' tcp_rmem'. – nh2

+0

Non ho detto che l'inverso è vero (!), Preferirei che un grande 'net.core.rmem_max' non abbia molto impatto, come hai osservato, perché tutti gli altri codici si riferiscono solo a' net.ipv4 .tcp_rmem'; il riferimento a 'net.core.rmem_max' è fatto * solo una volta * in una routine chiamata' tcp_select_initial_window'. Ma non ho esaminato tutti gli interni per vedere cosa ha fatto con 'rcv_wscale' dopo aver selezionato la finestra iniziale. Tutto quello che posso dedurre da una scansione di codice superficiale è che 'net.ipv4.tcp_rmem' sarà il valore effettivo in tutti i casi se è più grande di' net.core.rmem_max'. – mvds

+0

Hai ragione, molti posti come [questo] (https://github.com/torvalds/linux/blob/34229b277480f46c1e9a19f027f30b074512e68b/net/ipv4/tcp_input.c#L455) e [qui] (https: // github. it/torvalds/linux/blob/34229b277480f46c1e9a19f027f30b074512e68b/net/ipv4/tcp_input.C# L607) si riferiscono direttamente a 'sysctl_tcp_rmem [2]' invece di 'rcv_wscale'. Dato che è intransparente per entrambi se 'rcv_wscale' è usato da qualche altra parte, ho appena inviato una mail a' linux-man @ vger.kernel.org' e chiesto chiarimenti sulla pagina man. (Continuando con il prossimo commento, in ogni caso, la tua risposta sicuramente colpisce la mia generosità, grazie!) – nh2