tun: export underlying socket
Subsystems (10)
A message that is not in the archive (sent off-list or not yet received): [email protected]
Michael S. Tsirkin
maintainerPATCH v9 1/3 tun: export underlying socket
Tun device looks similar to a packet socket in that both pass complete frames from/to userspace.
This patch fills in enough fields in the socket underlying tun driver to support sendmsg/recvmsg operations, and message flags MSG_TRUNC and MSG_DONTWAIT, and exports access to this socket to modules. Regular read/write behaviour is unchanged.
This way, code using raw sockets to inject packets into a physical device, can support injecting packets into host network stack almost without modification.
First user of this interface will be vhost virtualization accelerator.
--- drivers/net/tun.c | 101 +++++++++++++++++++++++++++++++++++++++--------- include/linux/if_tun.h | 14 +++++++ 2 files changed, 96 insertions(+), 19 deletions(-)
drivers/net/tun.c +82 -19
@@ -144,6 +144,7 @@ static int tun_attach(struct tun_struct *tun, struct file *file) err =0 ; tfile->tun = tun; tun->tfile = tfile; + tun->socket.file = file;dev_hold (tun->dev);sock_hold (tun->socket.sk);atomic_inc (&tfile->count);
@@ -158,6 +159,7 @@ static void __tun_detach(struct tun_struct *tun)/* Detach from net device */ netif_tx_lock_bh (tun->dev); tun->tfile =NULL ; + tun->socket.file =NULL ;netif_tx_unlock_bh (tun->dev);/* Drop read queue */
@@ -387,7 +389,8 @@ static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev)/* Notify and wake up reader process */ if (tun->flags &TUN_FASYNC )kill_fasync (&tun->fasync,SIGIO ,POLL_IN ); -wake_up_interruptible (&tun->socket.wait); +wake_up_interruptible_poll (&tun->socket.wait,POLLIN | +POLLRDNORM |POLLRDBAND );return NETDEV_TX_OK ; drop:
@@ -743,7 +746,7 @@ static __inline__ ssize_t tun_put_user(struct tun_struct *tun, len =min_t (int, skb->len, len);skb_copy_datagram_const_iovec (skb,0 , iv, total, len); - total += len; + total += skb->len; tun->dev->stats.tx_packets++; tun->dev->stats.tx_bytes += len;
@@ -751,34 +754,23 @@ static __inline__ ssize_t tun_put_user(struct tun_struct *tun,return total; } -static ssize_t tun_chr_aio_read (struct kiocb *iocb,const struct iovec *iv, -unsigned long count,loff_t pos) +static ssize_t tun_do_read (struct tun_struct *tun, +struct kiocb *iocb,const struct iovec *iv, +ssize_t len,int noblock) { -struct file *file = iocb->ki_filp; -struct tun_file *tfile = file->private_data; -struct tun_struct *tun =__tun_get (tfile);DECLARE_WAITQUEUE (wait, current);struct sk_buff *skb; -ssize_t len, ret =0 ; - -if (!tun) -return -EBADFD ; +ssize_t ret =0 ;DBG (KERN_INFO "%s: tun_chr_read\n" , tun->dev->name); - len =iov_length (iv, count); -if (len <0 ) { - ret = -EINVAL ; - goto out; - } -add_wait_queue (&tun->socket.wait, &wait);while (len) { current->state =TASK_INTERRUPTIBLE ;/* Read frames from the queue */ if (!(skb=skb_dequeue (&tun->socket.sk->sk_receive_queue))) { -if (file->f_flags &O_NONBLOCK ) { +if (noblock) { ret = -EAGAIN ;break ; }
@@ -805,6 +797,27 @@ static ssize_t tun_chr_aio_read(struct kiocb *iocb, const struct iovec *iv, current->state =TASK_RUNNING ;remove_wait_queue (&tun->socket.wait, &wait); +return ret; +} + +static ssize_t tun_chr_aio_read (struct kiocb *iocb,const struct iovec *iv, +unsigned long count,loff_t pos) +{ +struct file *file = iocb->ki_filp; +struct tun_file *tfile = file->private_data; +struct tun_struct *tun =__tun_get (tfile); +ssize_t len, ret; + +if (!tun) +return -EBADFD ; + len =iov_length (iv, count); +if (len <0 ) { + ret = -EINVAL ; + goto out; + } + + ret =tun_do_read (tun, iocb, iv, len, file->f_flags &O_NONBLOCK ); + ret =min_t (ssize_t, ret, len); out:tun_put (tun);return ret;
@@ -847,7 +860,8 @@ static void tun_sock_write_space(struct sock *sk)return ;if (sk->sk_sleep &&waitqueue_active (sk->sk_sleep)) -wake_up_interruptible_sync (sk->sk_sleep); +wake_up_interruptible_sync_poll (sk->sk_sleep,POLLOUT | +POLLWRNORM |POLLWRBAND ); tun = container_of(sk, struct tun_sock, sk)->tun;kill_fasync (&tun->fasync,SIGIO ,POLL_OUT );
@@ -858,6 +872,37 @@ static void tun_sock_destruct(struct sock *sk) free_netdev(container_of(sk, struct tun_sock, sk)->tun->dev); } +static int tun_sendmsg (struct kiocb *iocb,struct socket *sock, +struct msghdr *m,size_t total_len) +{ + struct tun_struct *tun = container_of(sock, struct tun_struct, socket); +return tun_get_user (tun, m->msg_iov, total_len, + m->msg_flags &MSG_DONTWAIT ); +} + +static int tun_recvmsg (struct kiocb *iocb,struct socket *sock, +struct msghdr *m,size_t total_len, +int flags) +{ + struct tun_struct *tun = container_of(sock, struct tun_struct, socket); +int ret; +if (flags & ~(MSG_DONTWAIT |MSG_TRUNC )) +return -EINVAL ; + ret =tun_do_read (tun, iocb, m->msg_iov, total_len, + flags &MSG_DONTWAIT ); +if (ret > total_len) { + m->msg_flags |=MSG_TRUNC ; + ret = flags &MSG_TRUNC ? ret : total_len; + } +return ret; +} + +/* Ops structure to mimic raw sockets with tun */ +static const struct proto_ops tun_socket_ops = { + .sendmsg = tun_sendmsg, + .recvmsg = tun_recvmsg, +}; +static struct proto tun_proto = { .name ="tun" , .owner =THIS_MODULE ,
@@ -986,6 +1031,7 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) goto err_free_dev;init_waitqueue_head (&tun->socket.wait); + tun->socket.ops = &tun_socket_ops;sock_init_data (&tun->socket, sk); sk->sk_write_space = tun_sock_write_space; sk->sk_sndbuf =INT_MAX ;
@@ -1489,6 +1535,23 @@ static void tun_cleanup(void)rtnl_link_unregister (&tun_link_ops); } +/* Get an underlying socket object from tun file. Returns error unless file is +* attached to a device. The returned object works like a packet socket, it +* can be used for sock_sendmsg/sock_recvmsg. The caller is responsible for +* holding a reference to the file for as long as the socket is in use. */ +struct socket *tun_get_socket (struct file *file) +{ +struct tun_struct *tun; +if (file->f_op != &tun_fops) +return ERR_PTR (-EINVAL ); + tun =tun_get (file); +if (!tun) +return ERR_PTR (-EBADFD ); +tun_put (tun); +return &tun->socket; +} +EXPORT_SYMBOL_GPL (tun_get_socket); +module_init (tun_init);module_exit (tun_cleanup);MODULE_DESCRIPTION (DRV_DESCRIPTION );
include/linux/if_tun.h +14 -0
@@ -86,4 +86,18 @@ struct tun_filter { __u8 addr[0][ETH_ALEN]; }; +#ifdef __KERNEL__ +#if defined(CONFIG_TUN ) || defined(CONFIG_TUN_MODULE ) +struct socket *tun_get_socket (struct file *); +#else +#include <linux/err.h> +#include <linux/errno.h> +struct file ; +struct socket ; +static inline struct socket *tun_get_socket (struct file *f) +{ +return ERR_PTR (-EINVAL ); +} +#endif /* CONFIG_TUN */ +#endif /* __KERNEL__ */ #endif /* __IF_TUN_H */
Signature · 7 lines
1.6.5.2.143.g8cc62 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Michael S. Tsirkin
maintainerPATCH v9 1/3 tun: export underlying socket
In reply to a message not in the archiveTun device looks similar to a packet socket in that both pass complete frames from/to userspace.
This patch fills in enough fields in the socket underlying tun driver to support sendmsg/recvmsg operations, and message flags MSG_TRUNC and MSG_DONTWAIT, and exports access to this socket to modules. Regular read/write behaviour is unchanged.
This way, code using raw sockets to inject packets into a physical device, can support injecting packets into host network stack almost without modification.
First user of this interface will be vhost virtualization accelerator.
--- drivers/net/tun.c | 101 +++++++++++++++++++++++++++++++++++++++--------- include/linux/if_tun.h | 14 +++++++ 2 files changed, 96 insertions(+), 19 deletions(-)
drivers/net/tun.c +82 -19
@@ -144,6 +144,7 @@ static int tun_attach(struct tun_struct *tun, struct file *file) err =0 ; tfile->tun = tun; tun->tfile = tfile; + tun->socket.file = file;dev_hold (tun->dev);sock_hold (tun->socket.sk);atomic_inc (&tfile->count);
@@ -158,6 +159,7 @@ static void __tun_detach(struct tun_struct *tun)/* Detach from net device */ netif_tx_lock_bh (tun->dev); tun->tfile =NULL ; + tun->socket.file =NULL ;netif_tx_unlock_bh (tun->dev);/* Drop read queue */
@@ -387,7 +389,8 @@ static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev)/* Notify and wake up reader process */ if (tun->flags &TUN_FASYNC )kill_fasync (&tun->fasync,SIGIO ,POLL_IN ); -wake_up_interruptible (&tun->socket.wait); +wake_up_interruptible_poll (&tun->socket.wait,POLLIN | +POLLRDNORM |POLLRDBAND );return NETDEV_TX_OK ; drop:
@@ -743,7 +746,7 @@ static __inline__ ssize_t tun_put_user(struct tun_struct *tun, len =min_t (int, skb->len, len);skb_copy_datagram_const_iovec (skb,0 , iv, total, len); - total += len; + total += skb->len; tun->dev->stats.tx_packets++; tun->dev->stats.tx_bytes += len;
@@ -751,34 +754,23 @@ static __inline__ ssize_t tun_put_user(struct tun_struct *tun,return total; } -static ssize_t tun_chr_aio_read (struct kiocb *iocb,const struct iovec *iv, -unsigned long count,loff_t pos) +static ssize_t tun_do_read (struct tun_struct *tun, +struct kiocb *iocb,const struct iovec *iv, +ssize_t len,int noblock) { -struct file *file = iocb->ki_filp; -struct tun_file *tfile = file->private_data; -struct tun_struct *tun =__tun_get (tfile);DECLARE_WAITQUEUE (wait, current);struct sk_buff *skb; -ssize_t len, ret =0 ; - -if (!tun) -return -EBADFD ; +ssize_t ret =0 ;DBG (KERN_INFO "%s: tun_chr_read\n" , tun->dev->name); - len =iov_length (iv, count); -if (len <0 ) { - ret = -EINVAL ; - goto out; - } -add_wait_queue (&tun->socket.wait, &wait);while (len) { current->state =TASK_INTERRUPTIBLE ;/* Read frames from the queue */ if (!(skb=skb_dequeue (&tun->socket.sk->sk_receive_queue))) { -if (file->f_flags &O_NONBLOCK ) { +if (noblock) { ret = -EAGAIN ;break ; }
@@ -805,6 +797,27 @@ static ssize_t tun_chr_aio_read(struct kiocb *iocb, const struct iovec *iv, current->state =TASK_RUNNING ;remove_wait_queue (&tun->socket.wait, &wait); +return ret; +} + +static ssize_t tun_chr_aio_read (struct kiocb *iocb,const struct iovec *iv, +unsigned long count,loff_t pos) +{ +struct file *file = iocb->ki_filp; +struct tun_file *tfile = file->private_data; +struct tun_struct *tun =__tun_get (tfile); +ssize_t len, ret; + +if (!tun) +return -EBADFD ; + len =iov_length (iv, count); +if (len <0 ) { + ret = -EINVAL ; + goto out; + } + + ret =tun_do_read (tun, iocb, iv, len, file->f_flags &O_NONBLOCK ); + ret =min_t (ssize_t, ret, len); out:tun_put (tun);return ret;
@@ -847,7 +860,8 @@ static void tun_sock_write_space(struct sock *sk)return ;if (sk->sk_sleep &&waitqueue_active (sk->sk_sleep)) -wake_up_interruptible_sync (sk->sk_sleep); +wake_up_interruptible_sync_poll (sk->sk_sleep,POLLOUT | +POLLWRNORM |POLLWRBAND ); tun = container_of(sk, struct tun_sock, sk)->tun;kill_fasync (&tun->fasync,SIGIO ,POLL_OUT );
@@ -858,6 +872,37 @@ static void tun_sock_destruct(struct sock *sk) free_netdev(container_of(sk, struct tun_sock, sk)->tun->dev); } +static int tun_sendmsg (struct kiocb *iocb,struct socket *sock, +struct msghdr *m,size_t total_len) +{ + struct tun_struct *tun = container_of(sock, struct tun_struct, socket); +return tun_get_user (tun, m->msg_iov, total_len, + m->msg_flags &MSG_DONTWAIT ); +} + +static int tun_recvmsg (struct kiocb *iocb,struct socket *sock, +struct msghdr *m,size_t total_len, +int flags) +{ + struct tun_struct *tun = container_of(sock, struct tun_struct, socket); +int ret; +if (flags & ~(MSG_DONTWAIT |MSG_TRUNC )) +return -EINVAL ; + ret =tun_do_read (tun, iocb, m->msg_iov, total_len, + flags &MSG_DONTWAIT ); +if (ret > total_len) { + m->msg_flags |=MSG_TRUNC ; + ret = flags &MSG_TRUNC ? ret : total_len; + } +return ret; +} + +/* Ops structure to mimic raw sockets with tun */ +static const struct proto_ops tun_socket_ops = { + .sendmsg = tun_sendmsg, + .recvmsg = tun_recvmsg, +}; +static struct proto tun_proto = { .name ="tun" , .owner =THIS_MODULE ,
@@ -986,6 +1031,7 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) goto err_free_dev;init_waitqueue_head (&tun->socket.wait); + tun->socket.ops = &tun_socket_ops;sock_init_data (&tun->socket, sk); sk->sk_write_space = tun_sock_write_space; sk->sk_sndbuf =INT_MAX ;
@@ -1489,6 +1535,23 @@ static void tun_cleanup(void)rtnl_link_unregister (&tun_link_ops); } +/* Get an underlying socket object from tun file. Returns error unless file is +* attached to a device. The returned object works like a packet socket, it +* can be used for sock_sendmsg/sock_recvmsg. The caller is responsible for +* holding a reference to the file for as long as the socket is in use. */ +struct socket *tun_get_socket (struct file *file) +{ +struct tun_struct *tun; +if (file->f_op != &tun_fops) +return ERR_PTR (-EINVAL ); + tun =tun_get (file); +if (!tun) +return ERR_PTR (-EBADFD ); +tun_put (tun); +return &tun->socket; +} +EXPORT_SYMBOL_GPL (tun_get_socket); +module_init (tun_init);module_exit (tun_cleanup);MODULE_DESCRIPTION (DRV_DESCRIPTION );
include/linux/if_tun.h +14 -0
@@ -86,4 +86,18 @@ struct tun_filter { __u8 addr[0][ETH_ALEN]; }; +#ifdef __KERNEL__ +#if defined(CONFIG_TUN ) || defined(CONFIG_TUN_MODULE ) +struct socket *tun_get_socket (struct file *); +#else +#include <linux/err.h> +#include <linux/errno.h> +struct file ; +struct socket ; +static inline struct socket *tun_get_socket (struct file *f) +{ +return ERR_PTR (-EINVAL ); +} +#endif /* CONFIG_TUN */ +#endif /* __KERNEL__ */ #endif /* __IF_TUN_H */
Signature · 1 line
1.6.5.2.143.g8cc62
Michael S. Tsirkin
maintainerPATCH v9 2/3 mm: export use_mm/unuse_mm to modules
In reply to a message not in the archivevhost net module wants to do copy to/from user from a kernel thread, which needs use_mm. Export it to modules.
--- mm/mmu_context.c | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-)
mm/mmu_context.c +3 -0
@@ -5,6 +5,7 @@#include <linux/mm.h> #include <linux/mmu_context.h> +#include <linux/module.h> #include <linux/sched.h> #include <asm/mmu_context.h>
@@ -37,6 +38,7 @@ void use_mm(struct mm_struct *mm)if (active_mm != mm)mmdrop (active_mm); } +EXPORT_SYMBOL_GPL (use_mm);/* * unuse_mm
@@ -56,3 +58,4 @@ void unuse_mm(struct mm_struct *mm)enter_lazy_tlb (mm, tsk);task_unlock (tsk); } +EXPORT_SYMBOL_GPL (unuse_mm);
Signature · 7 lines
1.6.5.2.143.g8cc62 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Michael S. Tsirkin
maintainerPATCH v9 2/3 mm: export use_mm/unuse_mm to modules
In reply to a message not in the archivevhost net module wants to do copy to/from user from a kernel thread, which needs use_mm. Export it to modules.
--- mm/mmu_context.c | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-)
mm/mmu_context.c +3 -0
@@ -5,6 +5,7 @@#include <linux/mm.h> #include <linux/mmu_context.h> +#include <linux/module.h> #include <linux/sched.h> #include <asm/mmu_context.h>
@@ -37,6 +38,7 @@ void use_mm(struct mm_struct *mm)if (active_mm != mm)mmdrop (active_mm); } +EXPORT_SYMBOL_GPL (use_mm);/* * unuse_mm
@@ -56,3 +58,4 @@ void unuse_mm(struct mm_struct *mm)enter_lazy_tlb (mm, tsk);task_unlock (tsk); } +EXPORT_SYMBOL_GPL (unuse_mm);
Signature · 1 line
1.6.5.2.143.g8cc62
Michael S. Tsirkin
maintainerPATCH v9 3/3 vhost_net: a kernel-level virtio server
In reply to a message not in the archiveWhat it is: vhost net is a character device that can be used to reduce the number of system calls involved in virtio networking. Existing virtio net code is used in the guest without modification.
There's similarity with vringfd, with some differences and reduced scope
- uses eventfd for signalling
- structures can be moved around in memory at any time (good for migration, bug work-arounds in userspace)
- write logging is supported (good for migration)
- support memory table and not just an offset (needed for kvm)
common virtio related code has been put in a separate file vhost.c and can be made into a separate module if/when more backends appear. I used Rusty's lguest.c as the source for developing this part : this supplied me with witty comments I wouldn't be able to write myself.
What it is not: vhost net is not a bus, and not a generic new system call. No assumptions are made on how guest performs hypercalls. Userspace hypervisors are supported as well as kvm.
How it works: Basically, we connect virtio frontend (configured by userspace) to a backend. The backend could be a network device, or a tap device. Backend is also configured by userspace, including vlan/mac etc.
Status: This works for me, and I haven't see any crashes. Compared to userspace, people reported improved latency (as I save up to 4 system calls per packet), as well as better bandwidth and CPU utilization.
Features that I plan to look at in the future:
- mergeable buffers
- zero copy
- scalability tuning: figure out the best threading model to use
Note on RCU usage (this is also documented in vhost.h, near private_pointer which is the value protected by this variant of RCU):
what is happening is that the rcu_dereference() is being used in a workqueue item. The role of rcu_read_lock() is taken on by the start of execution of the workqueue item, of rcu_read_unlock() by the end of execution of the workqueue item, and of synchronize_rcu() by flush_workqueue()/flush_work(). In the future we might need to apply some gcc attribute or sparse annotation to the function passed to INIT_WORK(). Paul's ack below is for this RCU usage.
--- MAINTAINERS | 9 + arch/x86/kvm/Kconfig | 1 + drivers/Makefile | 1 + drivers/vhost/Kconfig | 11 + drivers/vhost/Makefile | 2 + drivers/vhost/net.c | 648 +++++++++++++++++++++++++++++ drivers/vhost/vhost.c | 965 ++++++++++++++++++++++++++++++++++++++++++++ drivers/vhost/vhost.h | 159 ++++++++ include/linux/Kbuild | 1 + include/linux/miscdevice.h | 1 + include/linux/vhost.h | 130 ++++++ 11 files changed, 1928 insertions(+), 0 deletions(-) create mode 100644 drivers/vhost/Kconfig create mode 100644 drivers/vhost/Makefile create mode 100644 drivers/vhost/net.c create mode 100644 drivers/vhost/vhost.c create mode 100644 drivers/vhost/vhost.h create mode 100644 include/linux/vhost.h
MAINTAINERS +9 -0
@@ -5636,6 +5636,15 @@ S: Maintained F: Documentation/filesystems/vfat.txt F: fs/fat/ +VIRTIO HOST (VHOST) +M: "Michael S. Tsirkin" <[email protected]> +L: [email protected] +L: [email protected] +L: [email protected] +S: Maintained +F: drivers/vhost/ +F: include/linux/vhost.h + VIA RHINE NETWORK DRIVER M: Roger Luethi <[email protected]> S: Maintained
arch/x86/kvm/Kconfig +1 -0
@@ -64,6 +64,7 @@ config KVM_AMD # OK, it's a little counter-intuitive to do this, but it puts it neatly under # the virtualization menu. +source drivers/vhost/Kconfig source drivers/lguest/Kconfig source drivers/virtio/Kconfig
drivers/Makefile +1 -0
@@ -106,6 +106,7 @@ obj-$(CONFIG_HID) += hid/ obj-$(CONFIG_PPC_PS3) += ps3/ obj-$(CONFIG_OF) += of/ obj-$(CONFIG_SSB) += ssb/ +obj-$(CONFIG_VHOST_NET) += vhost/ obj-$(CONFIG_VIRTIO) += virtio/ obj-$(CONFIG_VLYNQ) += vlynq/ obj-$(CONFIG_STAGING) += staging/
drivers/vhost/Kconfig new file +11 -0
@@ -0,0 +1,11 @@ +config VHOST_NET + tristate "Host kernel accelerator for virtio net (EXPERIMENTAL)" + depends on NET && EVENTFD && EXPERIMENTAL + ---help--- + This kernel module can be loaded in host kernel to accelerate + guest networking with virtio_net. Not to be confused with virtio_net + module itself which needs to be loaded in guest kernel. + + To compile this driver as a module, choose M here: the module will + be called vhost_net. +
drivers/vhost/Makefile new file +2 -0
@@ -0,0 +1,2 @@ +obj-$(CONFIG_VHOST_NET) += vhost_net.o +vhost_net-y := vhost.o net.o
drivers/vhost/net.c new file +648 -0
648 lines not on this page · raw message
drivers/vhost/vhost.c new file +965 -0
965 lines not on this page · raw message
drivers/vhost/vhost.h new file +159 -0
159 lines not on this page · raw message
include/linux/Kbuild +1 -0
@@ -361,6 +361,7 @@ unifdef-y += uio.h unifdef-y += unistd.h unifdef-y += usbdevice_fs.h unifdef-y += utsname.h +unifdef-y += vhost.h unifdef-y += videodev2.h unifdef-y += videodev.h unifdef-y += virtio_config.h
include/linux/miscdevice.h +1 -0
@@ -30,6 +30,7 @@#define HPET_MINOR 228#define FUSE_MINOR 229#define KVM_MINOR 232 +#define VHOST_NET_MINOR 233#define MISC_DYNAMIC_MINOR 255struct device ;
include/linux/vhost.h new file +130 -0
130 lines not on this page · raw message
Signature · 7 lines
1.6.5.2.143.g8cc62 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Rusty Russell
AppliedRe: [PATCHv9 3/3] vhost_net: a kernel-level virtio server
Quoted 3 lines · Michael S. Tsirkin
What it is: vhost net is a character device that can be used to reduce the number of system calls involved in virtio networking. Existing virtio net code is used in the guest without modification.
Thanks, applied. Will be in tomorrow's linux-next.
Cheers,
Rusty.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Rusty Russell
AppliedRe: [PATCHv9 3/3] vhost_net: a kernel-level virtio server
In reply to Michael S. TsirkinQuoted 3 lines · Michael S. Tsirkin
What it is: vhost net is a character device that can be used to reduce the number of system calls involved in virtio networking. Existing virtio net code is used in the guest without modification.
Thanks, applied. Will be in tomorrow's linux-next.
Cheers,
Rusty.
Re: [PATCHv9 3/3] vhost_net: a kernel-level virtio server
In reply to Michael S. TsirkinOne fix:
vhost: fix TUN=m VHOST_NET=y
drivers/built-in.o: In function `get_tun_socket': net.c:(.text+0x15436e): undefined reference to `tun_get_socket'
--- drivers/vhost/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/vhost/Kconfig +1 -1
@@ -1,6 +1,6 @@ config VHOST_NET tristate "Host kernel accelerator for virtio net (EXPERIMENTAL)" - depends on NET && EVENTFD && EXPERIMENTAL + depends on NET && EVENTFD && TUN && EXPERIMENTAL ---help--- This kernel module can be loaded in host kernel to accelerate guest networking with virtio_net. Not to be confused with virtio_net
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Michael S. Tsirkin
maintainerRe: [PATCHv9 3/3] vhost_net: a kernel-level virtio server
Quoted 16 lines · Rusty Russell
One fix:
vhost: fix TUN=m VHOST_NET=y
drivers/built-in.o: In function `get_tun_socket': net.c:(.text+0x15436e): undefined reference to `tun_get_socket'Signed-off-by Rusty Russell <[email protected]>--- drivers/vhost/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/vhost/Kconfig line 6
Quoted 7 lines
drivers/vhost/Kconfig +1
-1@@ -1,6 +1,6 @@ config VHOST_NET tristate "Host kernel accelerator for virtio net (EXPERIMENTAL)" - depends on NET && EVENTFD && EXPERIMENTAL + depends on NET && EVENTFD && TUN && EXPERIMENTAL ---help--- This kernel module can be loaded in host kernel to accelerate guest networking with virtio_net. Not to be confused with virtio_net
In fact, vhost can be built with TUN=n VHOST_NET=y as well (tun_get_socket is stubbed out in that case).
So I think this is better (it looks strange
until you realize that for tristate variables boolean logic math does not apply):
--->
From: Michael S. Tsirkin <[email protected]>
Subject: vhost: fix TUN=m VHOST_NET=y
drivers/built-in.o: In function `get_tun_socket':
net.c:(.text+0x15436e): undefined reference to `tun_get_socket'
If tun is a module, vhost must be a module, too. If tun is built-in or disabled, vhost can be built-in.
---
drivers/vhost/Kconfig +1 -1
@@ -1,6 +1,6 @@ config VHOST_NET tristate "Host kernel accelerator for virtio net (EXPERIMENTAL)" - depends on NET && EVENTFD && EXPERIMENTAL + depends on NET && EVENTFD && (TUN || !TUN) && EXPERIMENTAL ---help--- This kernel module can be loaded in host kernel to accelerate guest networking with virtio_net. Not to be confused with virtio_net
Signature · 7 lines
MST -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Rusty Russell
AppliedRe: [PATCHv9 3/3] vhost_net: a kernel-level virtio server
Quoted 2 lines · Michael S. Tsirkin
If tun is a module, vhost must be a module, too. If tun is built-in or disabled, vhost can be built-in.
I really like the brainbending :) Keeps readers on their toes...
Applied,
Rusty.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Rusty Russell
AppliedRe: [PATCHv9 3/3] vhost_net: a kernel-level virtio server
In reply to Michael S. TsirkinQuoted 2 lines · Michael S. Tsirkin
If tun is a module, vhost must be a module, too. If tun is built-in or disabled, vhost can be built-in.
I really like the brainbending :) Keeps readers on their toes...
Applied,
Rusty.
Michael S. Tsirkin
maintainerRe: [PATCHv9 3/3] vhost_net: a kernel-level virtio server
In reply to Rusty RussellQuoted 16 lines · Rusty Russell
One fix:
vhost: fix TUN=m VHOST_NET=y
drivers/built-in.o: In function `get_tun_socket': net.c:(.text+0x15436e): undefined reference to `tun_get_socket'Signed-off-by Rusty Russell <[email protected]>--- drivers/vhost/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/vhost/Kconfig line 6
Quoted 7 lines
drivers/vhost/Kconfig +1
-1@@ -1,6 +1,6 @@ config VHOST_NET tristate "Host kernel accelerator for virtio net (EXPERIMENTAL)" - depends on NET && EVENTFD && EXPERIMENTAL + depends on NET && EVENTFD && TUN && EXPERIMENTAL ---help--- This kernel module can be loaded in host kernel to accelerate guest networking with virtio_net. Not to be confused with virtio_net
In fact, vhost can be built with TUN=n VHOST_NET=y as well (tun_get_socket is stubbed out in that case).
So I think this is better (it looks strange
until you realize that for tristate variables boolean logic math does not apply):
--->
From: Michael S. Tsirkin <[email protected]>
Subject: vhost: fix TUN=m VHOST_NET=y
drivers/built-in.o: In function `get_tun_socket':
net.c:(.text+0x15436e): undefined reference to `tun_get_socket'
If tun is a module, vhost must be a module, too. If tun is built-in or disabled, vhost can be built-in.
---
drivers/vhost/Kconfig +1 -1
@@ -1,6 +1,6 @@ config VHOST_NET tristate "Host kernel accelerator for virtio net (EXPERIMENTAL)" - depends on NET && EVENTFD && EXPERIMENTAL + depends on NET && EVENTFD && (TUN || !TUN) && EXPERIMENTAL ---help--- This kernel module can be loaded in host kernel to accelerate guest networking with virtio_net. Not to be confused with virtio_net
Signature · 1 line
MST
Re: [PATCHv9 3/3] vhost_net: a kernel-level virtio server
In reply to Michael S. TsirkinOne fix:
vhost: fix TUN=m VHOST_NET=y
drivers/built-in.o: In function `get_tun_socket': net.c:(.text+0x15436e): undefined reference to `tun_get_socket'
--- drivers/vhost/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/vhost/Kconfig +1 -1
@@ -1,6 +1,6 @@ config VHOST_NET tristate "Host kernel accelerator for virtio net (EXPERIMENTAL)" - depends on NET && EVENTFD && EXPERIMENTAL + depends on NET && EVENTFD && TUN && EXPERIMENTAL ---help--- This kernel module can be loaded in host kernel to accelerate guest networking with virtio_net. Not to be confused with virtio_net
RE: [PATCHv9 3/3] vhost_net: a kernel-level virtio server
In reply to Michael S. TsirkinMichael,
Quoted 1 line
From the http://www.linux-kvm.org/page/VhostNet, we can see netperf with
TCP_STREAMcan get more than 4GMb/s for the receive side, and more than 5GMb/s for the send side.
Is it the result from the raw socket or through tap?
I want to duplicate such performance with vhost on my side. I can only get more than 1GMb/s with following conditions:
1) disabled the GRO feature in the host 10G NIC driver
2) vi->big_packet in guest is false
3) MTU is 1500.
4) raw socket, not the tap
5) using your vhost git tree
Is that the reasonable result with such conditions or maybe I have made some silly mistakes somewhere I don't know yet?
May you kindly describe your test environment/conditions in detail to have much better performance in your website (I really need the performance)?
And I have tested the tun support with vhost now, and may you share your /home/mst/ifup script here?
Thanks
Xiaohui
-----Original Message-----
From: [email protected] [mailto:[email protected]] On Behalf Of Michael S. Tsirkin
Sent: Tuesday, November 10, 2009 1:23 AM
To: [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; Rusty Russell; [email protected]; Daniel Walker; Eric Dumazet
Subject: [PATCHv9 3/3] vhost_net: a kernel-level virtio server
What it is: vhost net is a character device that can be used to reduce the number of system calls involved in virtio networking. Existing virtio net code is used in the guest without modification.
There's similarity with vringfd, with some differences and reduced scope
- uses eventfd for signalling
- structures can be moved around in memory at any time (good for migration, bug work-arounds in userspace)
- write logging is supported (good for migration)
- support memory table and not just an offset (needed for kvm)
common virtio related code has been put in a separate file vhost.c and can be made into a separate module if/when more backends appear. I used Rusty's lguest.c as the source for developing this part : this supplied me with witty comments I wouldn't be able to write myself.
What it is not: vhost net is not a bus, and not a generic new system call. No assumptions are made on how guest performs hypercalls. Userspace hypervisors are supported as well as kvm.
How it works: Basically, we connect virtio frontend (configured by userspace) to a backend. The backend could be a network device, or a tap device. Backend is also configured by userspace, including vlan/mac etc.
Status: This works for me, and I haven't see any crashes. Compared to userspace, people reported improved latency (as I save up to 4 system calls per packet), as well as better bandwidth and CPU utilization.
Features that I plan to look at in the future:
- mergeable buffers
- zero copy
- scalability tuning: figure out the best threading model to use
Note on RCU usage (this is also documented in vhost.h, near private_pointer which is the value protected by this variant of RCU):
what is happening is that the rcu_dereference() is being used in a workqueue item. The role of rcu_read_lock() is taken on by the start of execution of the workqueue item, of rcu_read_unlock() by the end of execution of the workqueue item, and of synchronize_rcu() by flush_workqueue()/flush_work(). In the future we might need to apply some gcc attribute or sparse annotation to the function passed to INIT_WORK(). Paul's ack below is for this RCU usage.
--- MAINTAINERS | 9 + arch/x86/kvm/Kconfig | 1 + drivers/Makefile | 1 + drivers/vhost/Kconfig | 11 + drivers/vhost/Makefile | 2 + drivers/vhost/net.c | 648 +++++++++++++++++++++++++++++ drivers/vhost/vhost.c | 965 ++++++++++++++++++++++++++++++++++++++++++++ drivers/vhost/vhost.h | 159 ++++++++ include/linux/Kbuild | 1 + include/linux/miscdevice.h | 1 + include/linux/vhost.h | 130 ++++++ 11 files changed, 1928 insertions(+), 0 deletions(-) create mode 100644 drivers/vhost/Kconfig create mode 100644 drivers/vhost/Makefile create mode 100644 drivers/vhost/net.c create mode 100644 drivers/vhost/vhost.c create mode 100644 drivers/vhost/vhost.h create mode 100644 include/linux/vhost.h
MAINTAINERS +9 -0
@@ -5636,6 +5636,15 @@ S: Maintained F: Documentation/filesystems/vfat.txt F: fs/fat/ +VIRTIO HOST (VHOST) +M: "Michael S. Tsirkin" <[email protected]> +L: [email protected] +L: [email protected] +L: [email protected] +S: Maintained +F: drivers/vhost/ +F: include/linux/vhost.h + VIA RHINE NETWORK DRIVER M: Roger Luethi <[email protected]> S: Maintained
arch/x86/kvm/Kconfig +1 -0
@@ -64,6 +64,7 @@ config KVM_AMD # OK, it's a little counter-intuitive to do this, but it puts it neatly under # the virtualization menu. +source drivers/vhost/Kconfig source drivers/lguest/Kconfig source drivers/virtio/Kconfig
drivers/Makefile +1 -0
@@ -106,6 +106,7 @@ obj-$(CONFIG_HID) += hid/ obj-$(CONFIG_PPC_PS3) += ps3/ obj-$(CONFIG_OF) += of/ obj-$(CONFIG_SSB) += ssb/ +obj-$(CONFIG_VHOST_NET) += vhost/ obj-$(CONFIG_VIRTIO) += virtio/ obj-$(CONFIG_VLYNQ) += vlynq/ obj-$(CONFIG_STAGING) += staging/
drivers/vhost/Kconfig new file +11 -0
@@ -0,0 +1,11 @@ +config VHOST_NET + tristate "Host kernel accelerator for virtio net (EXPERIMENTAL)" + depends on NET && EVENTFD && EXPERIMENTAL + ---help--- + This kernel module can be loaded in host kernel to accelerate + guest networking with virtio_net. Not to be confused with virtio_net + module itself which needs to be loaded in guest kernel. + + To compile this driver as a module, choose M here: the module will + be called vhost_net. +
drivers/vhost/Makefile new file +2 -0
@@ -0,0 +1,2 @@ +obj-$(CONFIG_VHOST_NET) += vhost_net.o +vhost_net-y := vhost.o net.o
drivers/vhost/net.c new file +648 -0
648 lines not on this page · raw message
drivers/vhost/vhost.c new file +965 -0
965 lines not on this page · raw message
drivers/vhost/vhost.h new file +159 -0
159 lines not on this page · raw message
include/linux/Kbuild +1 -0
@@ -361,6 +361,7 @@ unifdef-y += uio.h unifdef-y += unistd.h unifdef-y += usbdevice_fs.h unifdef-y += utsname.h +unifdef-y += vhost.h unifdef-y += videodev2.h unifdef-y += videodev.h unifdef-y += virtio_config.h
include/linux/miscdevice.h +1 -0
@@ -30,6 +30,7 @@#define HPET_MINOR 228#define FUSE_MINOR 229#define KVM_MINOR 232 +#define VHOST_NET_MINOR 233#define MISC_DYNAMIC_MINOR 255struct device ;
include/linux/vhost.h new file +130 -0
130 lines not on this page · raw message
--
1.6.5.2.143.g8cc62
--
To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Michael S. Tsirkin
maintainerRe: [PATCHv9 3/3] vhost_net: a kernel-level virtio server
Quoted 10 lines · Xiaohui
Michael,
Quoted 1 line
From the http://www.linux-kvm.org/page/VhostNet, we can see netperf with
TCP_STREAMcan get more than 4GMb/s for the receive side, and more than 5GMb/s for the send side.Is it the result from the raw socket or through tap?
I want to duplicate such performance with vhost on my side. I can only get more than 1GMb/s with following conditions:
1) disabled the GRO feature in the host 10G NIC driver
2)vi->big_packetin guest is false
3) MTU is 1500.
4) raw socket, not the tap
5) using your vhost git tree
Quoted 5 lines
Is that the reasonable result with such conditions or maybe I have made some silly mistakes somewhere I don't know yet?
May you kindly describe your test environment/conditions in detail to have much better performance in your website (I really need the performance)?Thanks
Xiaohui
These results where sent by Shirley Ma (Cc'd). I think they were with tap, host-to-guest/guest-to-host
Quoted 2 lines
And I have tested the tun support with vhost now, and may you share your
/home/mst/ifupscript here?
These are usually pretty simple, mine looks like this:
#!/bin/sh -x/sbin/ifconfig tap0 0.0.0.0 up
brctl addif br0 tap0
Signature · 7 lines
MST -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCHv9 3/3] vhost_net: a kernel-level virtio server
Quoted 2 lines · Michael S. Tsirkin
These results where sent by Shirley Ma (Cc'd). I think they were with tap, host-to-guest/guest-to-host
Yes, you are right.
Shirley
Re: [PATCHv9 3/3] vhost_net: a kernel-level virtio server
In reply to Michael S. TsirkinQuoted 2 lines · Michael S. Tsirkin
These results where sent by Shirley Ma (Cc'd). I think they were with tap, host-to-guest/guest-to-host
Yes, you are right.
Shirley
Michael S. Tsirkin
maintainerRe: [PATCHv9 3/3] vhost_net: a kernel-level virtio server
In reply to Xin, XiaohuiQuoted 10 lines · Xiaohui
Michael,
Quoted 1 line
From the http://www.linux-kvm.org/page/VhostNet, we can see netperf with
TCP_STREAMcan get more than 4GMb/s for the receive side, and more than 5GMb/s for the send side.Is it the result from the raw socket or through tap?
I want to duplicate such performance with vhost on my side. I can only get more than 1GMb/s with following conditions:
1) disabled the GRO feature in the host 10G NIC driver
2)vi->big_packetin guest is false
3) MTU is 1500.
4) raw socket, not the tap
5) using your vhost git tree
Quoted 5 lines
Is that the reasonable result with such conditions or maybe I have made some silly mistakes somewhere I don't know yet?
May you kindly describe your test environment/conditions in detail to have much better performance in your website (I really need the performance)?Thanks
Xiaohui
These results where sent by Shirley Ma (Cc'd). I think they were with tap, host-to-guest/guest-to-host
Quoted 2 lines
And I have tested the tun support with vhost now, and may you share your
/home/mst/ifupscript here?
These are usually pretty simple, mine looks like this:
#!/bin/sh -x/sbin/ifconfig tap0 0.0.0.0 up
brctl addif br0 tap0
Signature · 1 line
MST
RE: [PATCHv9 3/3] vhost_net: a kernel-level virtio server
In reply to Michael S. TsirkinMichael,
From the http://www.linux-kvm.org/page/VhostNet, we can see netperf with TCP_STREAM can get more than 4GMb/s for the receive side, and more than 5GMb/s for the send side. Is it the result from the raw socket or through tap?
I want to duplicate such performance with vhost on my side. I can only get more than 1GMb/s with following conditions:
1) disabled the GRO feature in the host 10G NIC driver
2) vi->big_packet in guest is false
3) MTU is 1500.
4) raw socket, not the tap
5) using your vhost git tree
Is that the reasonable result with such conditions or maybe I have made some silly mistakes somewhere I don't know yet?
May you kindly describe your test environment/conditions in detail to have much better performance in your website (I really need the performance)?
And I have tested the tun support with vhost now, and may you share your /home/mst/ifup script here?
Thanks
Xiaohui
-----Original Message-----
From: [email protected] [mailto:[email protected]] On Behalf Of Michael S. Tsirkin
Sent: Tuesday, November 10, 2009 1:23 AM
To: [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; Rusty Russell; [email protected]; Daniel Walker; Eric Dumazet
Subject: [PATCHv9 3/3] vhost_net: a kernel-level virtio server
What it is: vhost net is a character device that can be used to reduce the number of system calls involved in virtio networking. Existing virtio net code is used in the guest without modification.
There's similarity with vringfd, with some differences and reduced scope
- uses eventfd for signalling
- structures can be moved around in memory at any time (good for migration, bug work-arounds in userspace)
- write logging is supported (good for migration)
- support memory table and not just an offset (needed for kvm)
common virtio related code has been put in a separate file vhost.c and can be made into a separate module if/when more backends appear. I used Rusty's lguest.c as the source for developing this part : this supplied me with witty comments I wouldn't be able to write myself.
What it is not: vhost net is not a bus, and not a generic new system call. No assumptions are made on how guest performs hypercalls. Userspace hypervisors are supported as well as kvm.
How it works: Basically, we connect virtio frontend (configured by userspace) to a backend. The backend could be a network device, or a tap device. Backend is also configured by userspace, including vlan/mac etc.
Status: This works for me, and I haven't see any crashes. Compared to userspace, people reported improved latency (as I save up to 4 system calls per packet), as well as better bandwidth and CPU utilization.
Features that I plan to look at in the future:
- mergeable buffers
- zero copy
- scalability tuning: figure out the best threading model to use
Note on RCU usage (this is also documented in vhost.h, near private_pointer which is the value protected by this variant of RCU):
what is happening is that the rcu_dereference() is being used in a workqueue item. The role of rcu_read_lock() is taken on by the start of execution of the workqueue item, of rcu_read_unlock() by the end of execution of the workqueue item, and of synchronize_rcu() by flush_workqueue()/flush_work(). In the future we might need to apply some gcc attribute or sparse annotation to the function passed to INIT_WORK(). Paul's ack below is for this RCU usage.
--- MAINTAINERS | 9 + arch/x86/kvm/Kconfig | 1 + drivers/Makefile | 1 + drivers/vhost/Kconfig | 11 + drivers/vhost/Makefile | 2 + drivers/vhost/net.c | 648 +++++++++++++++++++++++++++++ drivers/vhost/vhost.c | 965 ++++++++++++++++++++++++++++++++++++++++++++ drivers/vhost/vhost.h | 159 ++++++++ include/linux/Kbuild | 1 + include/linux/miscdevice.h | 1 + include/linux/vhost.h | 130 ++++++ 11 files changed, 1928 insertions(+), 0 deletions(-) create mode 100644 drivers/vhost/Kconfig create mode 100644 drivers/vhost/Makefile create mode 100644 drivers/vhost/net.c create mode 100644 drivers/vhost/vhost.c create mode 100644 drivers/vhost/vhost.h create mode 100644 include/linux/vhost.h
MAINTAINERS +9 -0
@@ -5636,6 +5636,15 @@ S: Maintained F: Documentation/filesystems/vfat.txt F: fs/fat/ +VIRTIO HOST (VHOST) +M: "Michael S. Tsirkin" <[email protected]> +L: [email protected] +L: [email protected] +L: [email protected] +S: Maintained +F: drivers/vhost/ +F: include/linux/vhost.h + VIA RHINE NETWORK DRIVER M: Roger Luethi <[email protected]> S: Maintained
arch/x86/kvm/Kconfig +1 -0
@@ -64,6 +64,7 @@ config KVM_AMD # OK, it's a little counter-intuitive to do this, but it puts it neatly under # the virtualization menu. +source drivers/vhost/Kconfig source drivers/lguest/Kconfig source drivers/virtio/Kconfig
drivers/Makefile +1 -0
@@ -106,6 +106,7 @@ obj-$(CONFIG_HID) += hid/ obj-$(CONFIG_PPC_PS3) += ps3/ obj-$(CONFIG_OF) += of/ obj-$(CONFIG_SSB) += ssb/ +obj-$(CONFIG_VHOST_NET) += vhost/ obj-$(CONFIG_VIRTIO) += virtio/ obj-$(CONFIG_VLYNQ) += vlynq/ obj-$(CONFIG_STAGING) += staging/
drivers/vhost/Kconfig new file +11 -0
@@ -0,0 +1,11 @@ +config VHOST_NET + tristate "Host kernel accelerator for virtio net (EXPERIMENTAL)" + depends on NET && EVENTFD && EXPERIMENTAL + ---help--- + This kernel module can be loaded in host kernel to accelerate + guest networking with virtio_net. Not to be confused with virtio_net + module itself which needs to be loaded in guest kernel. + + To compile this driver as a module, choose M here: the module will + be called vhost_net. +
drivers/vhost/Makefile new file +2 -0
@@ -0,0 +1,2 @@ +obj-$(CONFIG_VHOST_NET) += vhost_net.o +vhost_net-y := vhost.o net.o
drivers/vhost/net.c new file +648 -0
648 lines not on this page · raw message
drivers/vhost/vhost.c new file +965 -0
965 lines not on this page · raw message
drivers/vhost/vhost.h new file +159 -0
159 lines not on this page · raw message
include/linux/Kbuild +1 -0
@@ -361,6 +361,7 @@ unifdef-y += uio.h unifdef-y += unistd.h unifdef-y += usbdevice_fs.h unifdef-y += utsname.h +unifdef-y += vhost.h unifdef-y += videodev2.h unifdef-y += videodev.h unifdef-y += virtio_config.h
include/linux/miscdevice.h +1 -0
@@ -30,6 +30,7 @@#define HPET_MINOR 228#define FUSE_MINOR 229#define KVM_MINOR 232 +#define VHOST_NET_MINOR 233#define MISC_DYNAMIC_MINOR 255struct device ;
include/linux/vhost.h new file +130 -0
130 lines not on this page · raw message
--
1.6.5.2.143.g8cc62
RE: [PATCHv9 3/3] vhost_net: a kernel-level virtio server
In reply to Michael S. TsirkinMichael,
Quoted 1 line
From the http://www.linux-kvm.org/page/VhostNet, we can see netperf with
TCP_STREAMcan get more than 4GMb/s for the receive side, and more than 5GMb/s for the send side.
Is it the result from the raw socket or through tap?
I want to duplicate such performance with vhost on my side. I can only get more than 1GMb/s with following conditions:
1) disabled the GRO feature in the host 10G NIC driver
2) vi->big_packet in guest is false
3) MTU is 1500.
4) raw socket, not the tap
5) using your vhost git tree
Is that the reasonable result with such conditions or maybe I have made some silly mistakes somewhere I don't know yet?
May you kindly describe your test environment/conditions in detail to have much better performance in your website (I really need the performance)?
And I have tested the tun support with vhost now, and may you share your /home/mst/ifup script here?
Thanks
Xiaohui
-----Original Message-----
From: [email protected] [mailto:[email protected]] On Behalf Of Michael S. Tsirkin
Sent: Tuesday, November 10, 2009 1:23 AM
To: [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; Rusty Russell; [email protected]; Daniel Walker; Eric Dumazet
Subject: [PATCHv9 3/3] vhost_net: a kernel-level virtio server
What it is: vhost net is a character device that can be used to reduce the number of system calls involved in virtio networking. Existing virtio net code is used in the guest without modification.
There's similarity with vringfd, with some differences and reduced scope
- uses eventfd for signalling
- structures can be moved around in memory at any time (good for migration, bug work-arounds in userspace)
- write logging is supported (good for migration)
- support memory table and not just an offset (needed for kvm)
common virtio related code has been put in a separate file vhost.c and can be made into a separate module if/when more backends appear. I used Rusty's lguest.c as the source for developing this part : this supplied me with witty comments I wouldn't be able to write myself.
What it is not: vhost net is not a bus, and not a generic new system call. No assumptions are made on how guest performs hypercalls. Userspace hypervisors are supported as well as kvm.
How it works: Basically, we connect virtio frontend (configured by userspace) to a backend. The backend could be a network device, or a tap device. Backend is also configured by userspace, including vlan/mac etc.
Status: This works for me, and I haven't see any crashes. Compared to userspace, people reported improved latency (as I save up to 4 system calls per packet), as well as better bandwidth and CPU utilization.
Features that I plan to look at in the future:
- mergeable buffers
- zero copy
- scalability tuning: figure out the best threading model to use
Note on RCU usage (this is also documented in vhost.h, near private_pointer which is the value protected by this variant of RCU):
what is happening is that the rcu_dereference() is being used in a workqueue item. The role of rcu_read_lock() is taken on by the start of execution of the workqueue item, of rcu_read_unlock() by the end of execution of the workqueue item, and of synchronize_rcu() by flush_workqueue()/flush_work(). In the future we might need to apply some gcc attribute or sparse annotation to the function passed to INIT_WORK(). Paul's ack below is for this RCU usage.
--- MAINTAINERS | 9 + arch/x86/kvm/Kconfig | 1 + drivers/Makefile | 1 + drivers/vhost/Kconfig | 11 + drivers/vhost/Makefile | 2 + drivers/vhost/net.c | 648 +++++++++++++++++++++++++++++ drivers/vhost/vhost.c | 965 ++++++++++++++++++++++++++++++++++++++++++++ drivers/vhost/vhost.h | 159 ++++++++ include/linux/Kbuild | 1 + include/linux/miscdevice.h | 1 + include/linux/vhost.h | 130 ++++++ 11 files changed, 1928 insertions(+), 0 deletions(-) create mode 100644 drivers/vhost/Kconfig create mode 100644 drivers/vhost/Makefile create mode 100644 drivers/vhost/net.c create mode 100644 drivers/vhost/vhost.c create mode 100644 drivers/vhost/vhost.h create mode 100644 include/linux/vhost.h
MAINTAINERS +9 -0
@@ -5636,6 +5636,15 @@ S: Maintained F: Documentation/filesystems/vfat.txt F: fs/fat/ +VIRTIO HOST (VHOST) +M: "Michael S. Tsirkin" <[email protected]> +L: [email protected] +L: [email protected] +L: [email protected] +S: Maintained +F: drivers/vhost/ +F: include/linux/vhost.h + VIA RHINE NETWORK DRIVER M: Roger Luethi <[email protected]> S: Maintained
arch/x86/kvm/Kconfig +1 -0
@@ -64,6 +64,7 @@ config KVM_AMD # OK, it's a little counter-intuitive to do this, but it puts it neatly under # the virtualization menu. +source drivers/vhost/Kconfig source drivers/lguest/Kconfig source drivers/virtio/Kconfig
drivers/Makefile +1 -0
@@ -106,6 +106,7 @@ obj-$(CONFIG_HID) += hid/ obj-$(CONFIG_PPC_PS3) += ps3/ obj-$(CONFIG_OF) += of/ obj-$(CONFIG_SSB) += ssb/ +obj-$(CONFIG_VHOST_NET) += vhost/ obj-$(CONFIG_VIRTIO) += virtio/ obj-$(CONFIG_VLYNQ) += vlynq/ obj-$(CONFIG_STAGING) += staging/
drivers/vhost/Kconfig new file +11 -0
@@ -0,0 +1,11 @@ +config VHOST_NET + tristate "Host kernel accelerator for virtio net (EXPERIMENTAL)" + depends on NET && EVENTFD && EXPERIMENTAL + ---help--- + This kernel module can be loaded in host kernel to accelerate + guest networking with virtio_net. Not to be confused with virtio_net + module itself which needs to be loaded in guest kernel. + + To compile this driver as a module, choose M here: the module will + be called vhost_net. +
drivers/vhost/Makefile new file +2 -0
@@ -0,0 +1,2 @@ +obj-$(CONFIG_VHOST_NET) += vhost_net.o +vhost_net-y := vhost.o net.o
drivers/vhost/net.c new file +648 -0
648 lines not on this page · raw message
drivers/vhost/vhost.c new file +965 -0
965 lines not on this page · raw message
drivers/vhost/vhost.h new file +159 -0
159 lines not on this page · raw message
include/linux/Kbuild +1 -0
@@ -361,6 +361,7 @@ unifdef-y += uio.h unifdef-y += unistd.h unifdef-y += usbdevice_fs.h unifdef-y += utsname.h +unifdef-y += vhost.h unifdef-y += videodev2.h unifdef-y += videodev.h unifdef-y += virtio_config.h
include/linux/miscdevice.h +1 -0
@@ -30,6 +30,7 @@#define HPET_MINOR 228#define FUSE_MINOR 229#define KVM_MINOR 232 +#define VHOST_NET_MINOR 233#define MISC_DYNAMIC_MINOR 255struct device ;
include/linux/vhost.h new file +130 -0
130 lines not on this page · raw message
--
1.6.5.2.143.g8cc62
--
To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Michael S. Tsirkin
maintainerPATCH v9 3/3 vhost_net: a kernel-level virtio server
In reply to a message not in the archiveWhat it is: vhost net is a character device that can be used to reduce the number of system calls involved in virtio networking. Existing virtio net code is used in the guest without modification.
There's similarity with vringfd, with some differences and reduced scope
- uses eventfd for signalling
- structures can be moved around in memory at any time (good for migration, bug work-arounds in userspace)
- write logging is supported (good for migration)
- support memory table and not just an offset (needed for kvm)
common virtio related code has been put in a separate file vhost.c and can be made into a separate module if/when more backends appear. I used Rusty's lguest.c as the source for developing this part : this supplied me with witty comments I wouldn't be able to write myself.
What it is not: vhost net is not a bus, and not a generic new system call. No assumptions are made on how guest performs hypercalls. Userspace hypervisors are supported as well as kvm.
How it works: Basically, we connect virtio frontend (configured by userspace) to a backend. The backend could be a network device, or a tap device. Backend is also configured by userspace, including vlan/mac etc.
Status: This works for me, and I haven't see any crashes. Compared to userspace, people reported improved latency (as I save up to 4 system calls per packet), as well as better bandwidth and CPU utilization.
Features that I plan to look at in the future:
- mergeable buffers
- zero copy
- scalability tuning: figure out the best threading model to use
Note on RCU usage (this is also documented in vhost.h, near private_pointer which is the value protected by this variant of RCU):
what is happening is that the rcu_dereference() is being used in a workqueue item. The role of rcu_read_lock() is taken on by the start of execution of the workqueue item, of rcu_read_unlock() by the end of execution of the workqueue item, and of synchronize_rcu() by flush_workqueue()/flush_work(). In the future we might need to apply some gcc attribute or sparse annotation to the function passed to INIT_WORK(). Paul's ack below is for this RCU usage.
--- MAINTAINERS | 9 + arch/x86/kvm/Kconfig | 1 + drivers/Makefile | 1 + drivers/vhost/Kconfig | 11 + drivers/vhost/Makefile | 2 + drivers/vhost/net.c | 648 +++++++++++++++++++++++++++++ drivers/vhost/vhost.c | 965 ++++++++++++++++++++++++++++++++++++++++++++ drivers/vhost/vhost.h | 159 ++++++++ include/linux/Kbuild | 1 + include/linux/miscdevice.h | 1 + include/linux/vhost.h | 130 ++++++ 11 files changed, 1928 insertions(+), 0 deletions(-) create mode 100644 drivers/vhost/Kconfig create mode 100644 drivers/vhost/Makefile create mode 100644 drivers/vhost/net.c create mode 100644 drivers/vhost/vhost.c create mode 100644 drivers/vhost/vhost.h create mode 100644 include/linux/vhost.h
MAINTAINERS +9 -0
@@ -5636,6 +5636,15 @@ S: Maintained F: Documentation/filesystems/vfat.txt F: fs/fat/ +VIRTIO HOST (VHOST) +M: "Michael S. Tsirkin" <[email protected]> +L: [email protected] +L: [email protected] +L: [email protected] +S: Maintained +F: drivers/vhost/ +F: include/linux/vhost.h + VIA RHINE NETWORK DRIVER M: Roger Luethi <[email protected]> S: Maintained
arch/x86/kvm/Kconfig +1 -0
@@ -64,6 +64,7 @@ config KVM_AMD # OK, it's a little counter-intuitive to do this, but it puts it neatly under # the virtualization menu. +source drivers/vhost/Kconfig source drivers/lguest/Kconfig source drivers/virtio/Kconfig
drivers/Makefile +1 -0
@@ -106,6 +106,7 @@ obj-$(CONFIG_HID) += hid/ obj-$(CONFIG_PPC_PS3) += ps3/ obj-$(CONFIG_OF) += of/ obj-$(CONFIG_SSB) += ssb/ +obj-$(CONFIG_VHOST_NET) += vhost/ obj-$(CONFIG_VIRTIO) += virtio/ obj-$(CONFIG_VLYNQ) += vlynq/ obj-$(CONFIG_STAGING) += staging/
drivers/vhost/Kconfig new file +11 -0
@@ -0,0 +1,11 @@ +config VHOST_NET + tristate "Host kernel accelerator for virtio net (EXPERIMENTAL)" + depends on NET && EVENTFD && EXPERIMENTAL + ---help--- + This kernel module can be loaded in host kernel to accelerate + guest networking with virtio_net. Not to be confused with virtio_net + module itself which needs to be loaded in guest kernel. + + To compile this driver as a module, choose M here: the module will + be called vhost_net. +
drivers/vhost/Makefile new file +2 -0
@@ -0,0 +1,2 @@ +obj-$(CONFIG_VHOST_NET) += vhost_net.o +vhost_net-y := vhost.o net.o
drivers/vhost/net.c new file +648 -0
648 lines not on this page · raw message
drivers/vhost/vhost.c new file +965 -0
965 lines not on this page · raw message
drivers/vhost/vhost.h new file +159 -0
159 lines not on this page · raw message
include/linux/Kbuild +1 -0
@@ -361,6 +361,7 @@ unifdef-y += uio.h unifdef-y += unistd.h unifdef-y += usbdevice_fs.h unifdef-y += utsname.h +unifdef-y += vhost.h unifdef-y += videodev2.h unifdef-y += videodev.h unifdef-y += virtio_config.h
include/linux/miscdevice.h +1 -0
@@ -30,6 +30,7 @@#define HPET_MINOR 228#define FUSE_MINOR 229#define KVM_MINOR 232 +#define VHOST_NET_MINOR 233#define MISC_DYNAMIC_MINOR 255struct device ;
include/linux/vhost.h new file +130 -0
130 lines not on this page · raw message
Signature · 1 line
1.6.5.2.143.g8cc62