JustKernel

Ray Of Hope

QEMU Networking Vhost-user & Transport Infiniband – series 3, vring implementation

This description and understanding is based on the vhost-user implementation and the vapp sample application shared by the VirtualOpenSystems.

vhost_client.c new_vhost_client()
{
vhost_client = new client(); //create a new clietn.
vhost_client->page_size = VHOST_CLIENT_PAGE_SIZE;
vhost_client->memory.nregions = VHOST_CLIENT_VRING_NUM; 2 : 1 for tx and 1 for Rx.
each region is backed by the socket and mapped to each individual client and server address space.
for each nregion
{
create a shared memory. sdm = init_shm(“vhost.sock”, page_size, idx//0 and 1 for each nregion)
init_shm(char * path, size, idx)
{
path = concatenate vhost.sock and idx //path = vhost.sock0 and vhost.sock1 for each nregion.
fd = shm_open()
init_shm_from_fd(fd, size)
} //for init_shm

init_shm_from_fd
{
void * mmaped_memory = mmap(size, fd, 0); map the shared memory to clinet address space.
} // for init_shm_from_fd

vhost_client->memory.regions[idx].guest_phys_addr = (uintptr_t) shm;
vhost_client->memory.regions[idx].memory_size = vhost_client->page_size;
vhost_client->memory.regions[idx].userspace_addr = (uintptr_t) shm;

// init vrings on the shm(throung memory regions)
vring_table_from_memory_region(vhost_client->vring_table_shm, VHOST_CLIENT_VRING_NUM, &vhost_client->memory)
} //for for loop
}//for new_vhost_clietn

vring_table_from_memory_Region(struct vhost_vring * vring_table[], size_t vring_table_num, VhostUserMemory *memory)
{
for i < 2 vring = new_vring(memory->regions[i].guesT_phys_address);
}

new_vring(void * vring_base)
{
struct vhost_vring * (struct vhost_vring*) vring_base)
uintptr_t ptr = (uintptr_t) ((char*)vring + sizeof(struct vhost_vring));

// Layout the descriptor table
for (i = 0; i < VHOST_VRING_SIZE; i++) { // align the pointer ptr = ALIGN(ptr, BUFFER_ALIGNMENT); vring->desc[i].addr = ptr;
vring->desc[i].len = BUFFER_SIZE;
vring->desc[i].flags = VIRTIO_DESC_F_WRITE;
vring->desc[i].next = i+1;

ptr += vring->desc[i].len;
}

}

vhost_client.c init_vhost_client()
{
/* copies the fds of the shared areas. Shared areas contain vrings.
share the fds with server so that server can also open these shared area and map to its own address spac.e
vhost_ioctl(vhost_client->client, VHOST_USER_SET_MEM_TABLE, &vhost_client->memory);

vhost_user_send_fds(client->sock, &msg, fds, fd_num) // this function calls sendmsg to sed messages to the server. message contains fds.
}

server.c recv_sock_server // call in handler vhost_user_recv_fds; read data from fds

vhost_server.c .
set_mem_table(ServerMsg *msg)

for (idx = 0; idx < msg->msg.memory.nregions; idx++) {
if (msg->fds[idx] > 0) {
VhostServerMemoryRegion *region = &vhost_server->memory.regions[idx];

region->guest_phys_addr = msg->msg.memory.regions[idx].guest_phys_addr;
region->memory_size = msg->msg.memory.regions[idx].memory_size;
region->userspace_addr = msg->msg.memory.regions[idx].userspace_addr;

assert(idx < msg->fd_num);
assert(msg->fds[idx] > 0);

region->mmap_addr = //this is the mmapped address int he server address space.
(uintptr_t) init_shm_from_fd(msg->fds[idx], region->memory_size); //these are the fds that were opened
by the client.

vhost_server->memory.nregions++;
}
}

Now vrings are shared between client and server. So a packet transferred from the guest running on client machine can reach to Server (host) with ZERO copy transfer. Now I am working on transferring the packet from Server host to Server guest.

In actual scenario, assume client as QEMU and server as any usermode process like snabbswitch or any third party application etc.

Thanks
Anshul makkar
anshul_makkar@justkernel.com

Tags: , , ,


Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.