11.0 stuck on high network load
Slawa Olhovchenkov
slw at zxy.spb.ru
Mon Oct 10 17:35:35 UTC 2016
On Mon, Oct 10, 2016 at 05:44:21PM +0200, Julien Charbon wrote:
> >> can check the current other usages of goto findpcb in tcp_input(). The
> >> rational here being:
> >>
> >> - Behavior before the patch: If the inp we found was deleted then goto
> >> findpcb.
> >> - Behavior after the patch: If the inp we found was deleted or dropped
> >> then goto findpcb.
> >>
> >> I just prefer having the same behavior applied everywhere: If
> >> tcp_input() loses the inp lock race and the inp was deleted or dropped
> >> then retry to find a new inpcb to deliver to.
> >>
> >> But you are right dropping the packet here will also fix the issue.
> >>
> >> Then the review process becomes quite helpful because people can argue:
> >> Dropping here is better because "blah", or goto findpcb is better
> >> because "bluh", etc. And at the review end you have a nice final patch.
> >>
> >> https://reviews.freebsd.org/D8211
> >
> > I am not sure, I am see to
> >
> > sys/netinet/in_pcb.h:#define INP_DROPPED 0x04000000 /*
> protocol drop flag */
> >
> > and think this is a flag 'all packets must be droped'
>
> Hm, I believe this flag means "this inp has been dropped by the TCP
> stack, so don't use it anymore". Actually this flag is better described
> in the function that sets it:
>
> "(INP_DROPPED) is used by TCP to mark an inpcb as unused and avoid
> future packet delivery or event notification when a socket remains open
> but TCP has closed."
>
> https://github.com/freebsd/freebsd/blob/release/11.0.0/sys/netinet/in_pcb.c#L1320
>
> /*
> * in_pcbdrop() removes an inpcb from hashed lists, releasing its
> address and
> * port reservation, and preventing it from being returned by inpcb lookups.
> *
> * It is used by TCP to mark an inpcb as unused and avoid future packet
> * delivery or event notification when a socket remains open but TCP has
> * closed. This might occur as a result of a shutdown()-initiated TCP close
> * or a RST on the wire, and allows the port binding to be reused while
> still
> * maintaining the invariant that so_pcb always points to a valid inpcb
> until
> * in_pcbdetach().
> *
> */
> void
> in_pcbdrop(struct inpcb *inp)
> {
> inp->inp_flags |= INP_DROPPED;
> ...
>
> The classical example where "goto findpcb" is useful: You receive a
> new connection request with a TCP SYN packet and this packet is unlucky
> and reached a inp being dropped:
>
> - with "goto findpcb" approach, the next lookup will most likely find
> the LISTEN inp and start the TCP hand-shake as usual
> - with "drop the packet" approach, the TCP client will need to
> re-transmit a TCP SYN packet
>
> It is not because a packet was unlucky once that it deserves to be
> dropped. :)
Thanks for explaining, very helpfull.
In this situation (TCP SYN with same 4-tuple as existing socket)
allocate new PCB is best. But for this we must destroy current PCB. I
am think INP_WUNLOCK(inp) don't destroy it and in_pcblookup_mbuf find
it again (I am think in_pcblookup_mbuf find this PCB on first turn).
I am assume for classical example in_pcbrele_wlocked(inp) free and
destroy current PCB for possibility in_pcblookup_mbuf allocate new
one.
More information about the freebsd-stable
mailing list