Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>There are some pictures <a href="http://vger.kernel.org/~davem/tcp_output.html" rel="nofollow noreferrer">http://vger.kernel.org/~davem/tcp_output.html</a> Googled with <code>tcp_transmit_skb()</code> which is a key part of tcp datapath. There are some more interesting thing on his site <a href="http://vger.kernel.org/~davem/" rel="nofollow noreferrer">http://vger.kernel.org/~davem/</a></p> <p>In <code>user - tcp</code> <strong>transmit</strong> part of datapath there is <strong>1 copy</strong> from user to skb with <code>skb_copy_to_page</code> (when sending by <em><code>tcp_sendmsg()</code></em>) and <strong>0 copy</strong> with <code>do_tcp_sendpages</code> (called by <em><code>tcp_sendpage()</code></em>). Copy is needed to keep a backup of data for case of undelivered segment. skb buffers in kernel can be cloned, but their data will stay in first (original) skb. Sendpage can take a page from other kernel part and keep it for backup (i think there is smth like COW)</p> <p>Call paths (manually from lxr). Sending <code>tcp_push_one</code>/<code>__tcp_push_pending_frames</code></p> <pre><code>tcp_sendmsg() &lt;- sock_sendmsg &lt;- sock_readv_writev &lt;- sock_writev &lt;- do_readv_writev tcp_sendpage() &lt;- file_send_actor &lt;- do_sendfile </code></pre> <p>Receive <code>tcp_recv_skb()</code></p> <pre><code>tcp_recvmsg() &lt;- sock_recvmsg &lt;- sock_readv_writev &lt;- sock_readv &lt;- do_readv_writev tcp_read_sock() &lt;- ... spliceread for new kernels.. smth sendfile for older </code></pre> <p>In <strong>receive</strong> there can be <strong>1 copy</strong> from kernel to user <code>skb_copy_datagram_iovec</code> (called from <code>tcp_recvmsg</code>). And for tcp_read_sock() there can be copy. It will call <code>sk_read_actor</code> callback function. If it correspond to file or memory, it may (or may not) copy data from DMA zone. If it is a other network, it has an skb of received packet and can reuse its data inplace.</p> <p>For udp - receive = <strong>1 copy</strong> -- skb_copy_datagram_iovec called from udp_recvmsg. transmit = <strong>1 copy</strong> -- udp_sendmsg -> ip_append_data -> getfrag (seems to be ip_generic_getfrag with 1 copy from user, but may be a smth sendpage/splicelike without page copiing.)</p> <p>Generically speaking there is must be at least 1 copy when sending from/receiving to userspace and 0 copy when using zero-copy (surprise!) with kernel-space source/target buffers for data. All headers are added without moving a packet, DMA-enabled (all modern) network card will take data from any place in DMA-enabled address space. For ancient cards PIO is needed, so there will be one more copy, from kernel space to PCI/ISA/smthelse I/O registers/memory.</p> <p>UPD: In path from NIC (but this is nic-dependent, i checked 8139too) to tcp stack there is <strong>one more copy</strong>: from rx_ring to skb and the same for receive: from skb to tx buffer <strong>+1copy</strong>. You must to fill in ip and tcp header, but does skb contain them or place for them?</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload