ptnetmap on bhyve - final status report

Stefano Garzarella stefanogarzarella at gmail.com
Mon Aug 17 09:10:07 UTC 2015


Dear All,
I finished the last step on my GSoC 2015 project ("A FreeBSD/bhyve version
of
the netmap virtual passthrough (ptnetmap) for VMs").
In the last week I tested my code and I added more comments in bhyve,
vmm.ko,
and netmap, to describe my work.
I also added some lines in bhyve.8 man page to explain how use ptnetmap
backend.

My code is available here:
https://svnweb.freebsd.org/socsvn/soc2015/stefano/ptnetmap/stable/10/
I used the 10-STABLE branch for my work.
To get the patches of modified modules, you can follow the following steps
on my
stable/10 branch:
    - bhyve
         svn diff -r 287649 usr.sbin/bhyve
    - virtio-net
         svn diff -r 287649 sys/dev/virtio/network
    - vmm.ko
         svn diff -r 287649 lib/libvmmapi sys/modules/vmm sys/amd64
    - netmap
         the changes will be shortly committed in HEAD and R10 by my mentor
         svn diff -r 287649 sys/conf/files sys/modules/netmap sys/dev/cxgbe
\
                                      sys/dev/netmap sys/net

The ptnetmap support for linux-KVM and QEMU is available here:
https://github.com/stefano-garzarella/ptnetmap

I implemented ptnetmap on bhyve working on the following steps:
 - bhyve network backends
         I reused the code developed by Luigi Rizzo (my mentor) and Vincenzo
         Maffione to support multiple backend in bhyve and to interface them
         with a fronteds.
         The backends availabale are:
            - tap
            - netmap (netmap, vale)
            - ptnetmap (ptnetmap, ptvale)

 - ptnetmap support on virtio-net device for FreeBSD
         I modified the virtio-net guest device driver and the virtio-net
fronted
         of thh host hypervisor (bhyve) to support ptnetmap.

         guest:
                 - new PTNETMAP config flag in virtio-net device driver to
check
                   if ptnetmap is supported.
                 - ptnetmap device-specific code (netmap -
if_vtnet_netmap.h)

         host (hypervisor):
                 - ptnetmap support on virtio-net fronted (bhyve -
pci_virtio_ptnetmap.h)
                 - ptnetmap backend [name: ptnetmap, ptvale] (bhyve -
net_backends.c)

- map netmap host memory into the guest
         I added a new IOCTL to vmm.ko to map an userspace guest buffer in
the
         guest VM. Then I implemented a new PCI device (ptnetmap-memdev) to
map
         the netmap host memory in the guest through PCI MEMORY-BAR.

         kernel host (vmm.ko):
                 - new VM_MAP_USER_BUF ioctl to map buffer in the guest

         userspace host (bhyve):
                 - vm_map_user_buf() in libvmmapi
                 - ptnetmap‐memdev device emulation (bhyve -
pci_ptnetmap_memdev.c)

         kernel guest (netmap):
                 - device driver for ptnetmap-memdev inluded in netmap
module

 - ptnetmap support for FreeBSD host:
         I implemented kernel thread in netmap module to support ptnetmap on
         FreeBSD host.

         kernel host (netmap):
                 - nm_os_kthread_*() functions to handle netmap kthreads.
                   (netmap - netmap_freebsd.c ptnetmap.c)

 - netmap guest/host notification mechanisms.
         I needed two mechanisms:
         1) notification from ptnetmap kthread to guest VM (interrupt/irq)
             vmm.ko already has IOCTL to send interrupt to the guest and I
used it
             in the ptnetmap kernel threads.
         2) notification from guest VM to ptnetmap kthread (write into the
             specific register)
             I added new IOCTL on vmm.ko (VM_IO_REG_HANDLER) to catch
write/read
             on specific I/O address and send notification.
             For now I've implemented only one type of handler
(VM_IO_REGH_KWEVENTS)
             to use these events in the kernel through wakeup() and
tsleep()/msleep(),
             but I wrote the code to be easily extended to support other
type of
             handler (cond_signal, write/ioctl on fd, etc).

         kernel host (vmm.ko):
                 - new VM_IO_REG_HANDLER ioctl to catch write/read on
specific
                   I/O address and to choose an handler. (eg.
wakeup(event_id)
                 - vm_io_reg_handler() in libvmmapi

         kernel host (netmap)
                 - msleep() on event_id.

         userspace host (bhyve)
                 - vm_io_reg_handler(VTCFG_R_QNOTIFY, event_id)
                   send guest notifications to ptnetmap kthreads when the
guest
                   writes on this virtio register (bhyve -
pci_virtio_ptnetmap.h)
                 - tell to netmap kthreads the event_id where they can wait
for
                   events

Example:

 Run a 2GB single‐CPU virtual machine with three network ports which use
 netmap and ptnetmap backends:

 bhyve ‐s 0,hostbridge ‐s 1,lpc \
         ‐s 2:1,virtio‐net,vale0:1 \            /* normal vale backend */
         ‐s 2:2,ptnetmap‐memdev \        /* ptnetmap-memdev is needed for
each
                                                            * ptnetmap port
                                                            * (If two or
more ptnetmap ports
                                                            * share the
same netmap memory allocator,
                                                            * only one
ptnetmap‐memdev is required)
                                                            */
         ‐s 2:3,virtio‐net,ptvale1:1 \         /* vale port in ptnetmap mode
                                                            * If "pt"
prefix is used, the port
                                                            * is opened in
passthrough mode (ptnetmap)
                                                            */
         ‐s 2:2,ptnetmap‐memdev \
         ‐s 2:3,virtio‐net,ptvale2{1 \         /* netmap-pipe in ptnetmap
mode */
         ‐s 3,ptnetmap‐memdev \
         ‐s 4,virtio‐net,ptnetmap:ix0 \      /* NIC in ptnetmap mode */
         ‐l com1,stdio ‐A ‐H ‐P ‐m 2G netmapvm

I have results (obtained with pkt-gen) very close to linux/KVM and netmap
host
(both linux and FreeBSD) experiments (physical devices [14.88 Mpps],
software switches
[25 Mpps], shared memory channels [50 Mpps]).
I used one instance of pkt-gen in the guest and the other one in the host.

Thanks for your help!
It was a pleasure working with you.

Cheers,
Stefano

-- 
*Stefano Garzarella*
Software Engineer

e-mail: stefano.garzarella at gmail.com
github: http://github.com/stefano-garzarella
linkedin: http://it.linkedin.com/pub/stefano-garzarella


More information about the soc-status mailing list