3

I am learning UNIX domain sockets and trying out some client server programs. I am using SOCK_DGRAM family of sockets.

My doubt is:

  1. Is using UNIX domain sockets copy buffer from userspace to kernel space buffers while sending and receiving?

So my call:

sendto(send_thread_socket, (void*)argData, sizeof(*argData), 0,
                                        (struct sockaddr *)&dpdkServer, sizeof(struct sockaddr_un))

will it copy the buffer to some kernel space buffer or will it directly be copied to user space buffer of receiving process. Since UNIX sockets work on file system namespaces I thought it shouldn't do a copy of the buffer.

  1. Since I am using SOCK_DGRAM, will a send timeout make any sense?

Lets say I am using the same sendto() call, but the receiving side does not guarantee any timely collection of data, can I have a Send timeout.

RootPhoenix
  • 1,626
  • 1
  • 22
  • 40
  • I had answered a question about userspace/kernelspace buffering - https://stackoverflow.com/questions/21014880/c-streams-copy-data-from-one-stream-to-another-directly-without-using-a-buffer/21016344#21016344. See if it helps you. – sashoalm Jan 13 '16 at 16:58

3 Answers3

2

The function sendto does not wait for the data to be received by the recipient before it returns. So yes, to achieve that, the data will be copied to a buffer owned by the kernel and then copied out again by the recieving process.

Why: If this wasn't the case, then it would be more-or-less impossible for two processes to exchange messages. If process P1 attempts to send a message to process P2, it would not succeed until P2 called read. If P2 is attempting to send a messate to P1 at the time, it cannot succeed until P1 calls read. But P1 is waiting in a blocking call to sendto. The processes will be deadlocked.

Buffering by the kernel is the solution to that problem.

Michael Goldshteyn
  • 71,784
  • 24
  • 131
  • 181
Ben
  • 34,935
  • 6
  • 74
  • 113
1

Well Ben covered the primary aspect really well, but there's something else here too.

Let us say we were going to allow zero-copy over domain sockets, and let us say that we allow sendto() to block until recvfrom() is called to get away from the kernel buffer. I see a headache coming really fast in kernel -- we would have to COW that page into the receiving process (which means it better be a whole page), and well, if everything isn't executed exactly you get copies anyway. The sender can't call free() or re-use the buffer for the obvious reasons as this would force pagefault-copy anyway.

Ugly, just ugly. Nobody's going to bother to write all this for something so hard to use. The only user of unix domain sockets big enough to warrant is X, and X doesn't guarantee the message sizes to allow this.

Joshua
  • 40,822
  • 8
  • 72
  • 132
0

I just want to add that if the data you exchange is big enough and/or frequent enough for optimization than you can create an anonymous file via create_memfd system call and pass the file descriptor with your message. If you use a mmap on this temporary file you can archive zero copy data exchange.

But the setup takes a lot of time, so you should measure it and only do so if you transfer lots of data or you have reasons for low memory consumption. Remember with the naive copy operation you will need three times the memory. Which might hurt more than the performance penalty of copying.

Lothar
  • 12,537
  • 6
  • 72
  • 121