From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail190.messagelabs.com (mail190.messagelabs.com [216.82.249.51]) by kanga.kvack.org (Postfix) with SMTP id 3C5B16B004D for ; Tue, 1 Sep 2009 02:59:23 -0400 (EDT) From: "Xin, Xiaohui" Date: Tue, 1 Sep 2009 14:58:19 +0800 Subject: [RFC] Virtual Machine Device Queues(VMDq) support on KVM Message-ID: Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Sender: owner-linux-mm@kvack.org To: "mst@redhat.com" , "netdev@vger.kernel.org" , "virtualization@lists.linux-foundation.org" , "kvm@vger.kernel.org" , "linux-kernel@vger.kernel.org" , "mingo@elte.hu" , "linux-mm@kvack.org" , "akpm@linux-foundation.org" , "hpa@zytor.com" , "gregory.haskins@gmail.com" List-ID: [RFC] Virtual Machine Device Queues (VMDq) support on KVM Network adapter with VMDq technology presents multiple pairs of tx/rx queue= s, and renders network L2 sorting mechanism based on MAC addresses and VLAN ta= gs for each tx/rx queue pair. Here we present a generic framework, in which ne= twork traffic to/from a tx/rx queue pair can be directed from/to a KVM guest with= out any software copy. Actually this framework can apply to traditional network adapters which hav= e just one tx/rx queue pair. And applications using the same user/kernel inte= rface can utilize this framework to send/receive network traffic directly thru a = tx/rx queue pair in a network adapter. We use virtio-net architecture to illustrate the framework. |--------------------| pop add_buf |----------------| | Qemu process | <--------- TX <---------- | Guest Kernel | | | ---------> ----------> | | | Virtio-net | push get_buf | | | (Backend service) | ---------> RX ----------> | Virtio-net | | | <--------- <---------- | driver | | | push get_buf | | |--------------------| |----------------| | | | AIO (read & write) combined with Direct I/O | (which substitute synced file operations) |-----------------------------------------------------------------------| | Host kernel | read: copy-less with directly mapped user | | | space to kernel, payload directly DMAed | | | into user space | | | write: copy-less with directly mapped user | | | space to kernel, payload directly hooked | | | to a skb | | | | | (a likely | | | queue pair | | | instance) | | | | | | | NIC driver <--> TUN/TAP driver | |-----------------------------------------------------------------------| | | traditional adapter or a tx/rx queue pair The basic idea is to utilize the kernel Asynchronous I/O combined with Dire= ct I/O to implements copy-less TUN/TAP device. AIO and Direct I/O is not new t= o kernel, we still can see it in SCSI tape driver. With traditional file operations, a copying of payload contents from/to the kernel DMA address to/from a user buffer is needed. That's what the copying= we want to save. The proposed framework is like this: A TUN/TAP device is bound to a traditional NIC adapter or a tx/rx queue pai= r in host side. KVM virto-net Backend service, the user space program submits asynchronous read/write I/O requests to the host kernel through TUN/TAP dev= ice. The requests are corresponding to the vqueue elements include both transmis= sion & receive. They can be queued in one AIO request and later, the completion = will be notified through the underlying packets tx/rx processing of the rx/tx qu= eue pair. Detailed path: To guest Virtio-net driver, packets receive corresponding to asynchronous r= ead I/O requests of Backend service. 1) Guest Virtio-net driver provides header and payload address through the receive vqueue to Virtio-net backend service. 2) Virtio-net backend service encapsulates multiple vqueue elements into multiple AIO control blocks and composes them into one AIO read request. 3) Virtio-net backend service uses io_submit() syscall to pass the request = to the TUN/TAP device. 4) Virtio-net backend service uses io_getevents() syscall to check the completion of the request. 5) The TUN/TAP driver receives packets from the queue pair of NIC, and prep= ares for Direct I/O. A modified NIC driver may render a skb which header is allocated in host kernel, but the payload buffer is directly mapped from user space buffer wh= ich are rendered through the AIO request by the Backend service. get_user_pages= () may do this. For one AIO read request, the TUN/TAP driver maintains a list = for the directly mapped buffers, and a NIC driver tries to get the buffers as payload buffer to compose the new skbs. Of course, if getting the buffers fails, then kernel allocated buffers are used. 6) Modern NIC cards now mostly have the header split feature. The NIC queue pair then may directly DMA the payload into the user spaces mapped payload buffers. Thus a zero-copy for payload is implemented in packet receiving. 7) The TUN/TAP driver manually copy the host header to space user mapped. 8) aio_complete() to notify the Virtio-net backend service for io_getevents= (). To guest Virtio-net driver, packets send corresponding to asynchronous writ= e I/O requests of backend. The path is similar to packet receive. 1) Guest Virtio-net driver provides header and payload address filled with contents through the transmit vqueue to Virtio-net backed service. 2) Virtio-net backend service encapsulates the vqueue elements into multipl= e AIO control blocks and composes them into one AIO write request. 3) Virtio-net backend service uses the io_submit() syscall to pass the requests to the TUN/TAP device. 4) Virtio-net backend service uses io_getevents() syscall to check the requ= est completion. 5) The TUN/TAP driver gets the write requests and allocates skbs for it. Th= e header contents are copied into the skb header. The directly mapped user sp= ace buffer is easily hooked into skb. Thus a zero copy for payload is implement= ed in packet sending. 6) aio_complete() to notify the Virtio-net backend service for io_getevents= (). The proposed framework is described as above. Consider the modifications to the kernel and qemu: To kernel: 1) The TUN/TAP driver may be modified a lot to implement AIO device operati= ons and to implement directly user space mapping into kernel. Code to maintain = the directly mapped user buffers should be in. It's just a modification for dri= ver. 2) The NIC driver may be modified to compose skb differently and slightly d= ata structure change to add user directly mapped buffer pointer. Here, maybe it's better for a NIC driver to present an interface for an rx/= tx queue pair instance which will also apply to traditional hardware, the kern= el interface should not be changed to make the other components happy. The abstraction is useful, though it is not needed immediately here. 3) The skb shared info structure may be modified a little to contain the us= er directly mapped info. To Qemu: 1) The Virtio-net backend service may be modified to handle AIO read/write requests from the vqueues. 2) Maybe a separate pthread to handle the AIO request triggering is needed. Any comments are appreciated here. Thanks Xiaohui -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: email@kvack.org