tcp_v4_rcv
[0] chama sk_add_backlog
e, se falhar, incrementa TCPBacklogDrop
2014 } else if (unlikely(sk_add_backlog(sk, skb,
2015 sk->sk_rcvbuf + sk->sk_sndbuf))) {
2016 bh_unlock_sock(sk);
2017 NET_INC_STATS_BH(net, LINUX_MIB_TCPBACKLOGDROP);
2018 goto discard_and_relse;
2019 }
sk_add_backlog
falha apenas se sk_rcvqueues_full
[1]:
801 /* The per-socket spinlock must be held here. */
802 static inline __must_check int sk_add_backlog(struct sock *sk, struct sk_buff *skb,
803 unsigned int limit)
804 {
805 if (sk_rcvqueues_full(sk, skb, limit))
806 return -ENOBUFS;
807
808 __sk_add_backlog(sk, skb);
809 sk->sk_backlog.len += skb->truesize;
810 return 0;
811 }
A função subjacente __sk_add_backlog
foi recentemente [2] para permitir que pelo menos um pacote passasse:
+ * Do not take into account this skb truesize,
+ * to allow even a single big packet to come.
Suponho que aplicar esse patch ao seu kernel deve corrigir o problema. Além disso, você pode tentar aumentar o tamanho padrão do buffer de rcv no sistema operacional e no aplicativo ( setsockopt
SO_RCVBUF
)
E sua segunda pergunta sobre RcvPruned
- Linux incrementa essa estatística dentro de tcp_prune_queue
[3]. Essa função geralmente é chamada quando o soquete ultrapassa seus limites de rcv. Então, mais uma vez, você pode aumentar seu rmem
/ SO_RCVBUF
e / ou ajustar seu aplicativo para fazer chamadas read () com mais freqüência (suponho que suas quedas estejam intimamente correlacionadas com as pausas do Java Stop-The-World GC. seu GC).