Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 15 Jun 2011 09:44:33 +0300
From:      Mikolaj Golub <trociny@freebsd.org>
To:        Kostik Belousov <kostikbel@gmail.com>
Cc:        freebsd-net@freebsd.org, Pawel Jakub Dawidek <pjd@freebsd.org>
Subject:   Re: Scenario to make recv(MSG_WAITALL) stuck
Message-ID:  <86k4cntwz2.fsf@in138.ua3>
In-Reply-To: <20110614092303.GG48734@deviant.kiev.zoral.com.ua> (Kostik Belousov's message of "Tue, 14 Jun 2011 12:23:03 %2B0300")
References:  <86pqmhn1pf.fsf@kopusha.home.net> <20110614092303.GG48734@deviant.kiev.zoral.com.ua>

next in thread | previous in thread | raw e-mail | index | archive | help

On Tue, 14 Jun 2011 12:23:03 +0300 Kostik Belousov wrote:

 KB> I do not understand what then happens for the recvfrom(2) call ?
 KB> Would it get some error, or 0 as return and no data, or something else ?

It will wait for data below in another loop ("Now continue to read any data
mbufs off of the head...").

Elaborating, I would split soreceive_generic on three logical parts.

In the first (restart) part we block until some data are received and also
(without the patch) in the case of MSG_WAITALL if the buffer is big enough we
block until all MSG_WAITALL request is received (actually it will spin in
"goto restart" loop until some condition becomes invalid).

The second part is some processing of received data and the third part is a
"while" loop where data is copied to userspace and in the case of MSG_WAITALL
request if not all data is received to satisfy the request it also waits for
this data.

My patch removes the condition in the first part in the case of MSG_WAITALL to
wait for all data if buffer is big enough. We always will wait for the rest of
data in the third part. It might be not so effective, and this is my first
concern about the patch (although not big :-).

 KB> Also, what is the MT_CONTROL chunk about ?

When I removed the condition to skip blocking in the first part I started to
observe panic on KASSERT(m->m_type == MT_DATA) for the following scenario
(produced by HAST):

sender:

send(4 bytes); /* send protocol name */
sendmsg();     /* send descriptor (normal data is empty, descriptor in control data) */

receiver:

recv(127 bytes, MSG_WAITALL);   /* recive protocol name */
recvmsg();                      /* recive descriptor */

Although the recv() has MSG_WAITALL, it exits after receiving 4 bytes because
the next received data is of different (MT_CONTROL) type. An it panicked when
got control data.

It is unclear for me why it is not expected to have MT_CONTROL data in that
part. We do have processing of MT_CONTROL above (in the second part) in the
code but I still a have feeling that it is possible to create some scenario to
break this assert without my patch too, but I have failed so far. And this is
my second concern about my patch, big enough, because for now I am not sure
that this is correct. Although I have not observed issues with it so far...

Also, I am not sure if there is sense to bother with soreceive_generic() at
all. May be it is more perspective to spend time on "maturing"
soreceive_stream(). As I see it is going to be a replacement for
soreceive_generic() for stream sockets.

-- 
Mikolaj Golub



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?86k4cntwz2.fsf>