All of lore.kernel.org
 help / color / mirror / Atom feed
* recvmmsg() behaviour with MSG_PEEK flag
@ 2022-07-15 11:03 Alexander Babayants
  2022-07-15 11:21 ` Eric Dumazet
  2022-07-15 14:23 ` Jann Horn
  0 siblings, 2 replies; 5+ messages in thread
From: Alexander Babayants @ 2022-07-15 11:03 UTC (permalink / raw)
  To: linux-api; +Cc: davem, edumazet, kuba, pabeni, mtk.manpages

Hello!

The behaviour of recvmmsg() with MSG_PEEK flag confuses me. I'd expect
it to peek multiple messages at once, but it seems to peek only the
first one, filling each of the provided struct msghdr with a copy of
the first message. I do not see if it is documented anywhere, is it a
bug or intended design?

What I want to achieve is to first peek into the socket, get the size
of each message, then allocate appropriate buffers and read the
messages with the second recvmmsg() call. This seems to be a
relatively common pattern for reading single messages via recvmsg(),
and I naively expected it to work with recvmmsg() too.

-- 
Regards,
Alexander Babayants.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: recvmmsg() behaviour with MSG_PEEK flag
  2022-07-15 11:03 recvmmsg() behaviour with MSG_PEEK flag Alexander Babayants
@ 2022-07-15 11:21 ` Eric Dumazet
  2022-07-15 12:17   ` Alexander Babayants
  2022-07-15 14:23 ` Jann Horn
  1 sibling, 1 reply; 5+ messages in thread
From: Eric Dumazet @ 2022-07-15 11:21 UTC (permalink / raw)
  To: Alexander Babayants
  Cc: Linux API, David Miller, Jakub Kicinski, Paolo Abeni, mtk.manpages

On Fri, Jul 15, 2022 at 1:03 PM Alexander Babayants
<babayants.alexander@gmail.com> wrote:
>
> Hello!
>
> The behaviour of recvmmsg() with MSG_PEEK flag confuses me. I'd expect
> it to peek multiple messages at once, but it seems to peek only the
> first one, filling each of the provided struct msghdr with a copy of
> the first message. I do not see if it is documented anywhere, is it a
> bug or intended design?
>
> What I want to achieve is to first peek into the socket, get the size
> of each message, then allocate appropriate buffers and read the
> messages with the second recvmmsg() call. This seems to be a
> relatively common pattern for reading single messages via recvmsg(),
> and I naively expected it to work with recvmmsg() too.
>

MSG_PEEK is a mistake really, it considerably increases the cost of
receiving packets,
because you need twice more system calls.

It also increases costs in the kernel, having to deal with it, even if
not used by fast applications.

Adding proper MSG_PEEK support to recvmmsg() is tricky, do_recvmmsg()
would probably have
to be completely reimplemented to not call ___sys_recvmsg(), or risk
some quadratic behavior
if each ___sys_recvmsg() has to skip over N datagrams

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: recvmmsg() behaviour with MSG_PEEK flag
  2022-07-15 11:21 ` Eric Dumazet
@ 2022-07-15 12:17   ` Alexander Babayants
  0 siblings, 0 replies; 5+ messages in thread
From: Alexander Babayants @ 2022-07-15 12:17 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: Linux API, David Miller, Jakub Kicinski, Paolo Abeni, mtk.manpages

Thanks for the prompt reply!

On Fri, Jul 15, 2022 at 14:21, Eric Dumazet <edumazet@google.com>:
>
...
> MSG_PEEK is a mistake really, it considerably increases the cost of
> receiving packets,
> because you need twice more system calls.

Sure, but I don't know the size of packets in advance, and I don't
control the sending side. So for me it's the choice between multiple
bad options -- either allocate some reasonable sized buffers and
truncate/drop packets that do not fit, or allocate 64k buffer for each
packet (UDP max packet size), or do two syscalls at a time. I thought
I could compensate for the cost of doing two syscalls by reading
multiple packets by syscall, but it seems that it's not possible with
the current implementation. Maybe I'm missing something and there are
other options?

> It also increases costs in the kernel, having to deal with it, even if
> not used by fast applications.
>
> Adding proper MSG_PEEK support to recvmmsg() is tricky, do_recvmmsg()
> would probably have
> to be completely reimplemented to not call ___sys_recvmsg(), or risk
> some quadratic behavior
> if each ___sys_recvmsg() has to skip over N datagrams

If there is no intention to fix the current behaviour, will it be OK
to submit a patch to man-pages with a note about it to the BUGS
section?

-- 
Regards,
Alexander Babayants.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: recvmmsg() behaviour with MSG_PEEK flag
  2022-07-15 11:03 recvmmsg() behaviour with MSG_PEEK flag Alexander Babayants
  2022-07-15 11:21 ` Eric Dumazet
@ 2022-07-15 14:23 ` Jann Horn
  1 sibling, 0 replies; 5+ messages in thread
From: Jann Horn @ 2022-07-15 14:23 UTC (permalink / raw)
  To: Alexander Babayants
  Cc: linux-api, davem, edumazet, kuba, pabeni, mtk.manpages

On Fri, Jul 15, 2022 at 1:03 PM Alexander Babayants
<babayants.alexander@gmail.com> wrote:
> The behaviour of recvmmsg() with MSG_PEEK flag confuses me. I'd expect
> it to peek multiple messages at once, but it seems to peek only the
> first one, filling each of the provided struct msghdr with a copy of
> the first message. I do not see if it is documented anywhere, is it a
> bug or intended design?
>
> What I want to achieve is to first peek into the socket, get the size
> of each message, then allocate appropriate buffers and read the
> messages with the second recvmmsg() call. This seems to be a
> relatively common pattern for reading single messages via recvmsg(),
> and I naively expected it to work with recvmmsg() too.

You might want to look at SO_PEEK_OFF in the socket.7 manpage. (Or
even better, as suggested before in the thread, rework your code to
not peek at all.)

^ permalink raw reply	[flat|nested] 5+ messages in thread

* recvmmsg() behaviour with MSG_PEEK flag
@ 2022-07-14 22:11 Alexander Babayants
  0 siblings, 0 replies; 5+ messages in thread
From: Alexander Babayants @ 2022-07-14 22:11 UTC (permalink / raw)
  To: netdev

(sorry in advance - I'm not sure it is the right mailing list for the
question, if it is not, feel free to redirect me)

The behaviour of recvmmsg() with MSG_PEEK flag confuses me. I'd expect
it to peek multiple messages at once, but it seems to peek only the
first one, filling each of the provided struct msghdr with a copy of
the first message. I do not see if it is documented anywhere, is it a
bug or intended design?

What I want to achieve is to first peek into the socket, get the size
of each message, then allocate appropriate buffers and read the
messages with the second recvmmsg() call. This seems to be a
relatively common pattern for reading single messages via recvmsg(),
and I naively expected it to work with recvmmsg() too.

-- 
Regards,
Alexander Babayants.

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2022-07-15 14:24 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-07-15 11:03 recvmmsg() behaviour with MSG_PEEK flag Alexander Babayants
2022-07-15 11:21 ` Eric Dumazet
2022-07-15 12:17   ` Alexander Babayants
2022-07-15 14:23 ` Jann Horn
  -- strict thread matches above, loose matches on Subject: below --
2022-07-14 22:11 Alexander Babayants

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.