msg_zerocopy.rst 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. ============
  2. MSG_ZEROCOPY
  3. ============
  4. Intro
  5. =====
  6. The MSG_ZEROCOPY flag enables copy avoidance for socket send calls.
  7. The feature is currently implemented for TCP, UDP and VSOCK (with
  8. virtio transport) sockets.
  9. Opportunity and Caveats
  10. -----------------------
  11. Copying large buffers between user process and kernel can be
  12. expensive. Linux supports various interfaces that eschew copying,
  13. such as sendfile and splice. The MSG_ZEROCOPY flag extends the
  14. underlying copy avoidance mechanism to common socket send calls.
  15. Copy avoidance is not a free lunch. As implemented, with page pinning,
  16. it replaces per byte copy cost with page accounting and completion
  17. notification overhead. As a result, MSG_ZEROCOPY is generally only
  18. effective at writes over around 10 KB.
  19. Page pinning also changes system call semantics. It temporarily shares
  20. the buffer between process and network stack. Unlike with copying, the
  21. process cannot immediately overwrite the buffer after system call
  22. return without possibly modifying the data in flight. Kernel integrity
  23. is not affected, but a buggy program can possibly corrupt its own data
  24. stream.
  25. The kernel returns a notification when it is safe to modify data.
  26. Converting an existing application to MSG_ZEROCOPY is not always as
  27. trivial as just passing the flag, then.
  28. More Info
  29. ---------
  30. Much of this document was derived from a longer paper presented at
  31. netdev 2.1. For more in-depth information see that paper and talk,
  32. the excellent reporting over at LWN.net or read the original code.
  33. paper, slides, video
  34. https://netdevconf.org/2.1/session.html?debruijn
  35. LWN article
  36. https://lwn.net/Articles/726917/
  37. patchset
  38. [PATCH net-next v4 0/9] socket sendmsg MSG_ZEROCOPY
  39. https://lore.kernel.org/netdev/20170803202945.70750-1-willemdebruijn.kernel@gmail.com
  40. Interface
  41. =========
  42. Passing the MSG_ZEROCOPY flag is the most obvious step to enable copy
  43. avoidance, but not the only one.
  44. Socket Setup
  45. ------------
  46. The kernel is permissive when applications pass undefined flags to the
  47. send system call. By default it simply ignores these. To avoid enabling
  48. copy avoidance mode for legacy processes that accidentally already pass
  49. this flag, a process must first signal intent by setting a socket option:
  50. ::
  51. if (setsockopt(fd, SOL_SOCKET, SO_ZEROCOPY, &one, sizeof(one)))
  52. error(1, errno, "setsockopt zerocopy");
  53. Transmission
  54. ------------
  55. The change to send (or sendto, sendmsg, sendmmsg) itself is trivial.
  56. Pass the new flag.
  57. ::
  58. ret = send(fd, buf, sizeof(buf), MSG_ZEROCOPY);
  59. A zerocopy failure will return -1 with errno ENOBUFS. This happens if
  60. the socket exceeds its optmem limit or the user exceeds their ulimit on
  61. locked pages.
  62. Mixing copy avoidance and copying
  63. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  64. Many workloads have a mixture of large and small buffers. Because copy
  65. avoidance is more expensive than copying for small packets, the
  66. feature is implemented as a flag. It is safe to mix calls with the flag
  67. with those without.
  68. Notifications
  69. -------------
  70. The kernel has to notify the process when it is safe to reuse a
  71. previously passed buffer. It queues completion notifications on the
  72. socket error queue, akin to the transmit timestamping interface.
  73. The notification itself is a simple scalar value. Each socket
  74. maintains an internal unsigned 32-bit counter. Each send call with
  75. MSG_ZEROCOPY that successfully sends data increments the counter. The
  76. counter is not incremented on failure or if called with length zero.
  77. The counter counts system call invocations, not bytes. It wraps after
  78. UINT_MAX calls.
  79. Notification Reception
  80. ~~~~~~~~~~~~~~~~~~~~~~
  81. The below snippet demonstrates the API. In the simplest case, each
  82. send syscall is followed by a poll and recvmsg on the error queue.
  83. Reading from the error queue is always a non-blocking operation. The
  84. poll call is there to block until an error is outstanding. It will set
  85. POLLERR in its output flags. That flag does not have to be set in the
  86. events field. Errors are signaled unconditionally.
  87. ::
  88. pfd.fd = fd;
  89. pfd.events = 0;
  90. if (poll(&pfd, 1, -1) != 1 || pfd.revents & POLLERR == 0)
  91. error(1, errno, "poll");
  92. ret = recvmsg(fd, &msg, MSG_ERRQUEUE);
  93. if (ret == -1)
  94. error(1, errno, "recvmsg");
  95. read_notification(msg);
  96. The example is for demonstration purpose only. In practice, it is more
  97. efficient to not wait for notifications, but read without blocking
  98. every couple of send calls.
  99. Notifications can be processed out of order with other operations on
  100. the socket. A socket that has an error queued would normally block
  101. other operations until the error is read. Zerocopy notifications have
  102. a zero error code, however, to not block send and recv calls.
  103. Notification Batching
  104. ~~~~~~~~~~~~~~~~~~~~~
  105. Multiple outstanding packets can be read at once using the recvmmsg
  106. call. This is often not needed. In each message the kernel returns not
  107. a single value, but a range. It coalesces consecutive notifications
  108. while one is outstanding for reception on the error queue.
  109. When a new notification is about to be queued, it checks whether the
  110. new value extends the range of the notification at the tail of the
  111. queue. If so, it drops the new notification packet and instead increases
  112. the range upper value of the outstanding notification.
  113. For protocols that acknowledge data in-order, like TCP, each
  114. notification can be squashed into the previous one, so that no more
  115. than one notification is outstanding at any one point.
  116. Ordered delivery is the common case, but not guaranteed. Notifications
  117. may arrive out of order on retransmission and socket teardown.
  118. Notification Parsing
  119. ~~~~~~~~~~~~~~~~~~~~
  120. The below snippet demonstrates how to parse the control message: the
  121. read_notification() call in the previous snippet. A notification
  122. is encoded in the standard error format, sock_extended_err.
  123. The level and type fields in the control data are protocol family
  124. specific, IP_RECVERR or IPV6_RECVERR (for TCP or UDP socket).
  125. For VSOCK socket, cmsg_level will be SOL_VSOCK and cmsg_type will be
  126. VSOCK_RECVERR.
  127. Error origin is the new type SO_EE_ORIGIN_ZEROCOPY. ee_errno is zero,
  128. as explained before, to avoid blocking read and write system calls on
  129. the socket.
  130. The 32-bit notification range is encoded as [ee_info, ee_data]. This
  131. range is inclusive. Other fields in the struct must be treated as
  132. undefined, bar for ee_code, as discussed below.
  133. ::
  134. struct sock_extended_err *serr;
  135. struct cmsghdr *cm;
  136. cm = CMSG_FIRSTHDR(msg);
  137. if (cm->cmsg_level != SOL_IP &&
  138. cm->cmsg_type != IP_RECVERR)
  139. error(1, 0, "cmsg");
  140. serr = (void *) CMSG_DATA(cm);
  141. if (serr->ee_errno != 0 ||
  142. serr->ee_origin != SO_EE_ORIGIN_ZEROCOPY)
  143. error(1, 0, "serr");
  144. printf("completed: %u..%u\n", serr->ee_info, serr->ee_data);
  145. Deferred copies
  146. ~~~~~~~~~~~~~~~
  147. Passing flag MSG_ZEROCOPY is a hint to the kernel to apply copy
  148. avoidance, and a contract that the kernel will queue a completion
  149. notification. It is not a guarantee that the copy is elided.
  150. Copy avoidance is not always feasible. Devices that do not support
  151. scatter-gather I/O cannot send packets made up of kernel generated
  152. protocol headers plus zerocopy user data. A packet may need to be
  153. converted to a private copy of data deep in the stack, say to compute
  154. a checksum.
  155. In all these cases, the kernel returns a completion notification when
  156. it releases its hold on the shared pages. That notification may arrive
  157. before the (copied) data is fully transmitted. A zerocopy completion
  158. notification is not a transmit completion notification, therefore.
  159. Deferred copies can be more expensive than a copy immediately in the
  160. system call, if the data is no longer warm in the cache. The process
  161. also incurs notification processing cost for no benefit. For this
  162. reason, the kernel signals if data was completed with a copy, by
  163. setting flag SO_EE_CODE_ZEROCOPY_COPIED in field ee_code on return.
  164. A process may use this signal to stop passing flag MSG_ZEROCOPY on
  165. subsequent requests on the same socket.
  166. Implementation
  167. ==============
  168. Loopback
  169. --------
  170. For TCP and UDP:
  171. Data sent to local sockets can be queued indefinitely if the receive
  172. process does not read its socket. Unbound notification latency is not
  173. acceptable. For this reason all packets generated with MSG_ZEROCOPY
  174. that are looped to a local socket will incur a deferred copy. This
  175. includes looping onto packet sockets (e.g., tcpdump) and tun devices.
  176. For VSOCK:
  177. Data path sent to local sockets is the same as for non-local sockets.
  178. Testing
  179. =======
  180. More realistic example code can be found in the kernel source under
  181. tools/testing/selftests/net/msg_zerocopy.c.
  182. Be cognizant of the loopback constraint. The test can be run between
  183. a pair of hosts. But if run between a local pair of processes, for
  184. instance when run with msg_zerocopy.sh between a veth pair across
  185. namespaces, the test will not show any improvement. For testing, the
  186. loopback restriction can be temporarily relaxed by making
  187. skb_orphan_frags_rx identical to skb_orphan_frags.
  188. For VSOCK type of socket example can be found in
  189. tools/testing/vsock/vsock_test_zerocopy.c.