Skip to contentSkip to conversation

VM Sockets for Linux upstreaming

PATCH Applied Andy King 5 participants 23 messages Feb 7, 2013 – Feb 19, 2013

Subsystems (6)
lore
Share & tools
lore
author
#1 lore raw

PATCH 1/1 VSOCK: Introduce VM Sockets

In reply to Andy King

VM Sockets allows communication between virtual machines and the hypervisor. User level applications both in a virtual machine and on the host can use the VM Sockets API, which facilitates fast and efficient communication between guest virtual machines and their host. A socket address family, designed to be compatible with UDP and TCP at the interface level, is provided.

Today, VM Sockets is used by various VMware Tools components inside the guest for zero-config, network-less access to VMware host services. In addition to this, VMware's users are using VM Sockets for various applications, where network access of the virtual machine is restricted or non-existent. Examples of this are VMs communicating with device proxies for proprietary hardware running as host applications and automated testing of applications running within virtual machines.

The VMware VM Sockets are similar to other socket types, like Berkeley UNIX socket interface. The VM Sockets module supports both connection-oriented stream sockets like TCP, and connectionless datagram sockets like UDP. The VM Sockets protocol family is defined as "AF_VSOCK" and the socket operations split for SOCK_DGRAM and SOCK_STREAM.

For additional information about the use of VM Sockets, please refer to the VM Sockets Programming Guide available at:

https://www.vmware.com/support/developer/vmci-sdk/

---
 include/linux/socket.h                       |    4 +-
 include/uapi/linux/vm_sockets.h              |  171 ++
 net/Kconfig                                  |    1 +
 net/Makefile                                 |    1 +
 net/vmw_vsock/Kconfig                        |   28 +
 net/vmw_vsock/Makefile                       |    7 +
 net/vmw_vsock/af_vsock.c                     | 2015 ++++++++++++++++++++++++
 net/vmw_vsock/af_vsock.h                     |  175 +++
 net/vmw_vsock/vmci_transport.c               | 2157 ++++++++++++++++++++++++++
 net/vmw_vsock/vmci_transport.h               |  139 ++
 net/vmw_vsock/vmci_transport_notify.c        |  680 ++++++++
 net/vmw_vsock/vmci_transport_notify.h        |   83 +
 net/vmw_vsock/vmci_transport_notify_qstate.c |  438 ++++++
 net/vmw_vsock/vsock_addr.c                   |   86 +
 net/vmw_vsock/vsock_addr.h                   |   32 +
 net/vmw_vsock/vsock_version.h                |   22 +
 16 files changed, 6038 insertions(+), 1 deletions(-)
 create mode 100644 include/uapi/linux/vm_sockets.h
 create mode 100644 net/vmw_vsock/Kconfig
 create mode 100644 net/vmw_vsock/Makefile
 create mode 100644 net/vmw_vsock/af_vsock.c
 create mode 100644 net/vmw_vsock/af_vsock.h
 create mode 100644 net/vmw_vsock/vmci_transport.c
 create mode 100644 net/vmw_vsock/vmci_transport.h
 create mode 100644 net/vmw_vsock/vmci_transport_notify.c
 create mode 100644 net/vmw_vsock/vmci_transport_notify.h
 create mode 100644 net/vmw_vsock/vmci_transport_notify_qstate.c
 create mode 100644 net/vmw_vsock/vsock_addr.c
 create mode 100644 net/vmw_vsock/vsock_addr.h
 create mode 100644 net/vmw_vsock/vsock_version.h
include/linux/socket.h +3 -1
index 9a546ff..2b9f74b 100644
@@ -178,7 +178,8 @@ struct ucred {
 #define AF_CAIF		37	/* CAIF sockets			*/
 #define AF_ALG		38	/* Algorithm sockets		*/
 #define AF_NFC		39	/* NFC sockets			*/
-#define AF_MAX		40	/* For now.. */
+#define AF_VSOCK	40	/* vSockets			*/
+#define AF_MAX		41	/* For now.. */
 
 /* Protocol families, same as address families. */
 #define PF_UNSPEC	AF_UNSPEC
@@ -221,6 +222,7 @@ struct ucred {
 #define PF_CAIF		AF_CAIF
 #define PF_ALG		AF_ALG
 #define PF_NFC		AF_NFC
+#define PF_VSOCK	AF_VSOCK
 #define PF_MAX		AF_MAX
 
 /* Maximum queue length specifiable by listen.  */
include/uapi/linux/vm_sockets.h new file +171 -0

171 lines not on this page · raw message

net/Kconfig +1 -0
index 30b48f5..f143ac3 100644
@@ -218,6 +218,7 @@ source "net/dcb/Kconfig"
 source "net/dns_resolver/Kconfig"
 source "net/batman-adv/Kconfig"
 source "net/openvswitch/Kconfig"
+source "net/vmw_vsock/Kconfig"
 
 config RPS
 	boolean
net/Makefile +1 -0
index 4f4ee08..f9d0e0e 100644
@@ -70,3 +70,4 @@ obj-$(CONFIG_CEPH_LIB)		+= ceph/
 obj-$(CONFIG_BATMAN_ADV)	+= batman-adv/
 obj-$(CONFIG_NFC)		+= nfc/
 obj-$(CONFIG_OPENVSWITCH)	+= openvswitch/
+obj-$(CONFIG_VSOCKETS)	+= vmw_vsock/
net/vmw_vsock/Kconfig new file +28 -0
new file mode 100644
index 0000000..b5fa7e4
@@ -0,0 +1,28 @@
+#
+# Vsock protocol
+#
+
+config VSOCKETS
+	tristate "Virtual Socket protocol"
+	help
+	  Virtual Socket Protocol is a socket protocol similar to TCP/IP
+	  allowing comunication between Virtual Machines and hypervisor
+	  or host.
+
+	  You should also select one or more hypervisor-specific transports
+	  below.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called vsock. If unsure, say N.
+
+config VMWARE_VMCI_VSOCKETS
+	tristate "VMware VMCI transport for Virtual Sockets"
+	depends on VSOCKETS && VMWARE_VMCI
+	help
+	  This module implements a VMCI transport for Virtual Sockets.
+
+	  Enable this transport if your Virtual Machine runs on a VMware
+	  hypervisor.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called vmw_vsock_vmci_transport. If unsure, say N.
net/vmw_vsock/Makefile new file +7 -0
new file mode 100644
index 0000000..2ce52d7
@@ -0,0 +1,7 @@
+obj-$(CONFIG_VSOCKETS) += vsock.o
+obj-$(CONFIG_VMWARE_VMCI_VSOCKETS) += vmw_vsock_vmci_transport.o
+
+vsock-y += af_vsock.o vsock_addr.o
+
+vmw_vsock_vmci_transport-y += vmci_transport.o vmci_transport_notify.o \
+	vmci_transport_notify_qstate.o
net/vmw_vsock/af_vsock.c new file +2015 -0

2,015 lines not on this page · raw message

net/vmw_vsock/af_vsock.h new file +175 -0

175 lines not on this page · raw message

net/vmw_vsock/vmci_transport.c new file +2157 -0

577 lines not on this page · raw message

net/vmw_vsock/vmci_transport.h new file +139 -0

139 lines not on this page · raw message

net/vmw_vsock/vmci_transport_notify.c new file +680 -0

680 lines not on this page · raw message

net/vmw_vsock/vmci_transport_notify.h new file +83 -0

83 lines not on this page · raw message

net/vmw_vsock/vmci_transport_notify_qstate.c new file +438 -0

438 lines not on this page · raw message

net/vmw_vsock/vsock_addr.c new file +86 -0

86 lines not on this page · raw message

net/vmw_vsock/vsock_addr.h new file +32 -0
new file mode 100644
index 0000000..cdfbcef

Lines of this file are not shown. View the raw message.

net/vmw_vsock/vsock_version.h new file +22 -0
new file mode 100644
index 0000000..4df7f5e

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Signature · 1 line
1.7.4.1

Part of the diff is not shown here. View the raw message.

Andy King

author
#0 lore raw

cover VM Sockets for Linux upstreaming

In an effort to improve the out-of-the-box experience with Linux kernels for VMware users, VMware is working on readying the VM Sockets (VSOCK, formerly VMCI Sockets) (vsock) kernel module for inclusion in the Linux kernel. The purpose of this post is to acquire feedback on the vsock kernel module.

Unlike previous submissions, where the new socket family was entirely reliant on VMware's VMCI PCI device (and thus VMware's hypervisor), VM Sockets is now completely[1] separated out into two parts, each in its own module:

o Core socket code, which is transport-neutral and invokes transport callbacks to communicate with the hypervisor. This is vsock.ko.
o A VMCI transport, which communicates over VMCI with the VMware hypervisor. This is vmw_vsock_vmci_transport.ko, and it registers with the core module as a transport.

This should provide a path to introducing additional transports, for example virtio, with the ultimate goal being to make this new socket family hypervisor-neutral.

[1] If Gerd tries it and determines this to be false (still), I'll ship him a keg of beer.

Andy King (1):
VSOCK: Introduce VM Sockets

 include/linux/socket.h                       |    4 +-
 include/uapi/linux/vm_sockets.h              |  171 ++
 net/Kconfig                                  |    1 +
 net/Makefile                                 |    1 +
 net/vmw_vsock/Kconfig                        |   28 +
 net/vmw_vsock/Makefile                       |    7 +
 net/vmw_vsock/af_vsock.c                     | 2015 ++++++++++++++++++++++++
 net/vmw_vsock/af_vsock.h                     |  175 +++
 net/vmw_vsock/vmci_transport.c               | 2157 ++++++++++++++++++++++++++
 net/vmw_vsock/vmci_transport.h               |  139 ++
 net/vmw_vsock/vmci_transport_notify.c        |  680 ++++++++
 net/vmw_vsock/vmci_transport_notify.h        |   83 +
 net/vmw_vsock/vmci_transport_notify_qstate.c |  438 ++++++
 net/vmw_vsock/vsock_addr.c                   |   86 +
 net/vmw_vsock/vsock_addr.h                   |   32 +
 net/vmw_vsock/vsock_version.h                |   22 +
 16 files changed, 6038 insertions(+), 1 deletions(-)
 create mode 100644 include/uapi/linux/vm_sockets.h
 create mode 100644 net/vmw_vsock/Kconfig
 create mode 100644 net/vmw_vsock/Makefile
 create mode 100644 net/vmw_vsock/af_vsock.c
 create mode 100644 net/vmw_vsock/af_vsock.h
 create mode 100644 net/vmw_vsock/vmci_transport.c
 create mode 100644 net/vmw_vsock/vmci_transport.h
 create mode 100644 net/vmw_vsock/vmci_transport_notify.c
 create mode 100644 net/vmw_vsock/vmci_transport_notify.h
 create mode 100644 net/vmw_vsock/vmci_transport_notify_qstate.c
 create mode 100644 net/vmw_vsock/vsock_addr.c
 create mode 100644 net/vmw_vsock/vsock_addr.h
 create mode 100644 net/vmw_vsock/vsock_version.h
Signature · 1 line
1.7.4.1
#20 lore raw

Hi David,

Quoted 15 lines · Andy King

In an effort to improve the out-of-the-box experience with Linux kernels for VMware users, VMware is working on readying the VM Sockets (VSOCK, formerly VMCI Sockets) (vsock) kernel module for inclusion in the Linux kernel. The purpose of this post is to acquire feedback on the vsock kernel module.

Unlike previous submissions, where the new socket family was entirely reliant on VMware's VMCI PCI device (and thus VMware's hypervisor), VM Sockets is now completely[1] separated out into two parts, each in its own module:

o Core socket code, which is transport-neutral and invokes transport callbacks to communicate with the hypervisor. This is vsock.ko.
o A VMCI transport, which communicates over VMCI with the VMware hypervisor. This is vmw_vsock_vmci_transport.ko, and it registers with the core module as a transport.

Quoted 3 lines

This should provide a path to introducing additional transports, for example virtio, with the ultimate goal being to make this new socket family hypervisor-neutral.

As Andy mentioned in another e-mail, we would like very much to get vsock in 3.9 release, so now that it is split into hypervisor neutral and transport parts is there any high level issues that we need to resolve before the code can be accepted?

Thanks,
Dmitry

maintainer
#21 lore raw

From: Dmitry Torokhov <[email protected]>
Date: Fri, 8 Feb 2013 17:20:44 -0800

Quoted 18 lines

Hi David,

Quoted 15 lines · Andy King

In an effort to improve the out-of-the-box experience with Linux kernels for VMware users, VMware is working on readying the VM Sockets (VSOCK, formerly VMCI Sockets) (vsock) kernel module for inclusion in the Linux kernel. The purpose of this post is to acquire feedback on the vsock kernel module.

Unlike previous submissions, where the new socket family was entirely reliant on VMware's VMCI PCI device (and thus VMware's hypervisor), VM Sockets is now completely[1] separated out into two parts, each in its own module:

o Core socket code, which is transport-neutral and invokes transport callbacks to communicate with the hypervisor. This is vsock.ko.
o A VMCI transport, which communicates over VMCI with the VMware hypervisor. This is vmw_vsock_vmci_transport.ko, and it registers with the core module as a transport.

Quoted 8 lines
Quoted 3 lines

This should provide a path to introducing additional transports, for example virtio, with the ultimate goal being to make this new socket family hypervisor-neutral.

As Andy mentioned in another e-mail, we would like very much to get vsock in 3.9 release, so now that it is split into hypervisor neutral and transport parts is there any high level issues that we need to resolve before the code can be accepted?

I have no idea, I haven't gotten to reviewing your changes yet, and I will do so at a time of my own choosing. Pressing me about the matter is unlikely to make me review things any faster, and in fact will have the opposite effect.

Therefore, just be patient like everyone else is.

maintainer Applied
#22 lore raw
In reply to Andy King

From: Andy King <[email protected]>
Date: Wed, 6 Feb 2013 16:23:55 -0800

Quoted 15 lines

In an effort to improve the out-of-the-box experience with Linux kernels for VMware users, VMware is working on readying the VM Sockets (VSOCK, formerly VMCI Sockets) (vsock) kernel module for inclusion in the Linux kernel. The purpose of this post is to acquire feedback on the vsock kernel module.

Unlike previous submissions, where the new socket family was entirely reliant on VMware's VMCI PCI device (and thus VMware's hypervisor), VM Sockets is now completely[1] separated out into two parts, each in its own module:

o Core socket code, which is transport-neutral and invokes transport callbacks to communicate with the hypervisor. This is vsock.ko.
o A VMCI transport, which communicates over VMCI with the VMware hypervisor. This is vmw_vsock_vmci_transport.ko, and it registers with the core module as a transport.

Quoted 3 lines

This should provide a path to introducing additional transports, for example virtio, with the ultimate goal being to make this new socket family hypervisor-neutral.

Applied, thanks.

#2 lore raw

Re: [PATCH 1/1] VSOCK: Introduce VM Sockets

In reply to Andy King
Quoted 65 lines · Andy King
net/vmw_vsock/af_vsock.h new file +65 -0
+struct vsock_transport_recv_notify_data {
+	u64 data1; /* Transport-defined. */
+	u64 data2; /* Transport-defined. */
+	bool notify_on_block;
+};
+
+struct vsock_transport_send_notify_data {
+	u64 data1; /* Transport-defined. */
+	u64 data2; /* Transport-defined. */
+};
+
+struct vsock_transport {
+	/* Initialize/tear-down socket. */
+	int (*init)(struct vsock_sock *, struct vsock_sock *);
+	void (*destruct)(struct vsock_sock *);
+	void (*release)(struct vsock_sock *);
+
+	/* Connections. */
+	int (*connect)(struct vsock_sock *);
+
+	/* DGRAM. */
+	int (*dgram_bind)(struct vsock_sock *, struct sockaddr_vm *);
+	int (*dgram_dequeue)(struct kiocb *kiocb, struct vsock_sock *vsk,
+			     struct msghdr *msg, size_t len, int flags);
+	int (*dgram_enqueue)(struct vsock_sock *, struct sockaddr_vm *,
+			     struct iovec *, size_t len);
+	bool (*dgram_allow)(u32 cid, u32 port);
+
+	/* STREAM. */
+	/* TODO: stream_bind() */
+	ssize_t (*stream_dequeue)(struct vsock_sock *, struct iovec *,
+				  size_t len, int flags);
+	ssize_t (*stream_enqueue)(struct vsock_sock *, struct iovec *,
+				  size_t len);
+	s64 (*stream_has_data)(struct vsock_sock *);
+	s64 (*stream_has_space)(struct vsock_sock *);
+	u64 (*stream_rcvhiwat)(struct vsock_sock *);
+	bool (*stream_is_active)(struct vsock_sock *);
+	bool (*stream_allow)(u32 cid, u32 port);
+
+	/* Notification. */
+	int (*notify_poll_in)(struct vsock_sock *, size_t, bool *);
+	int (*notify_poll_out)(struct vsock_sock *, size_t, bool *);
+	int (*notify_recv_init)(struct vsock_sock *, size_t,
+		struct vsock_transport_recv_notify_data *);
+	int (*notify_recv_pre_block)(struct vsock_sock *, size_t,
+		struct vsock_transport_recv_notify_data *);
+	int (*notify_recv_pre_dequeue)(struct vsock_sock *, size_t,
+		struct vsock_transport_recv_notify_data *);
+	int (*notify_recv_post_dequeue)(struct vsock_sock *, size_t,
+		ssize_t, bool, struct vsock_transport_recv_notify_data *);
+	int (*notify_send_init)(struct vsock_sock *,
+		struct vsock_transport_send_notify_data *);
+	int (*notify_send_pre_block)(struct vsock_sock *,
+		struct vsock_transport_send_notify_data *);
+	int (*notify_send_pre_enqueue)(struct vsock_sock *,
+		struct vsock_transport_send_notify_data *);
+	int (*notify_send_post_enqueue)(struct vsock_sock *, ssize_t,
+		struct vsock_transport_send_notify_data *);
+
+	/* Shutdown. */
+	int (*shutdown)(struct vsock_sock *, int);
+
+	/* Buffer sizes. */
+	void (*set_buffer_size)(struct vsock_sock *, u64);

net/vmw_vsock/af_vsock.h line 155

Quoted 10 lines
net/vmw_vsock/af_vsock.h new file +10 -0
+	void (*set_min_buffer_size)(struct vsock_sock *, u64);
+	void (*set_max_buffer_size)(struct vsock_sock *, u64);
+	u64 (*get_buffer_size)(struct vsock_sock *);
+	u64 (*get_min_buffer_size)(struct vsock_sock *);
+	u64 (*get_max_buffer_size)(struct vsock_sock *);
+
+	/* Addressing. */
+	u32 (*get_local_cid)(void);
+};
+

Whoa. This has grown *alot*. Care to explain this please? Patch creating a Documentation/virtual/vsock.txt would be cool.

*_enqueue + *_dequeue is sending/receiving data, ok.

stream_has_data + stream_has_space + stream_rcvhiwat look like they are needed for buffer management. Details please (especially for stream_rcvhiwat).

What is stream_is_active?
What is *_allow?

What are all those notify_* calls?

Why do you need vsock_transport_{send,recv}_notify_data structs? Can't this live in vsock_sock->trans?

thanks,
Gerd

#8 lore raw

Re: [PATCH 1/1] VSOCK: Introduce VM Sockets

In reply to Andy King

On 02/07/13 01:23, Andy King wrote:

Hi,

include/uapi/linux/vm_sockets.h line 62

Quoted 8 lines
include/uapi/linux/vm_sockets.h new file +8 -0
+/* Option name for socket's service label.  Use as the option name in
+ * setsockopt(3) or getsockopt(3) to set or get the service label for a socket.
+ * The service label is a C-style NUL-terminated string.  Only available for
+ * hypervisor endpoints.
+ */
+
+#define SO_VM_SOCKETS_SERVICE_LABEL 4
+

What is this and how does it work?

cheers,
Gerd

author
#3 lore raw

Re: [PATCH 1/1] VSOCK: Introduce VM Sockets

In reply to Gerd Hoffmann

Hi Gerd,

Quoted 1 line
Quoted 1 line

+struct vsock_transport {

...

Quoted 2 lines

Whoa. This has grown *alot*. Care to explain this please? Patch creating a Documentation/virtual/vsock.txt would be cool.

Yes, it grew because of the notification stuff, which I'd forgotten about until I removed the vmci header from the core code. You are free to use empty functions for these if they don't make any sense for virtio. The alternative is for us to move the entire body of vsock_stream_recv/send into the transport, where we can hide the notification stuff, but it seems like folks will just end up duplicating a lot of code then.

Quoted 3 lines

stream_has_data + stream_has_space + stream_rcvhiwat look like they are needed for buffer management. Details please (especially for stream_rcvhiwat).

stream_has_data: Returns amount of data available (in bytes) in the socket's receive buffer, or -1 if empty.

stream_has_space: Returns amount of space available (in bytes) in the socket's send buffer, or -1 if full.

stream_rcvhiwat: The upper bound on the socket's receive buffer. Which technically is the same as the value returned by get_buffer_size(), so perhaps we could substitute that here and drop this one.

Quoted 1 line

What is stream_is_active?

For the VMCI transport, it indicates if the underlying queuepair is still around (i.e., make sure we haven't torn it down while sleeping in a blocking send or receive). Perhaps it's not the best name?

Quoted 1 line

What is *_allow?

It's very basic filtering. We have specific addresses that we don't allow, and we look for them in the allow() functions. You can just return true if you like.

Quoted 1 line

What are all those notify_* calls?

They're to do with signaling and flow-control. Again, they might not make any sense at all, but it's hard to know without having written another transport :)

Quoted 2 lines

Why do you need vsock_transport_{send,recv}_notify_data structs? Can't this live in vsock_sock->trans?

Those have to be setup on a per-call basis (per-thread), so it's just easier to have them on the stack of the send/recv calls. If you think there's a better name, or a better way to allocate them, I'm all ears.

Thanks!
- Andy

author
#4 lore raw

Re: [Pv-drivers] [PATCH 1/1] VSOCK: Introduce VM Sockets

Quoted 5 lines

stream_has_data: Returns amount of data available (in bytes) in the socket's receive buffer, or -1 if empty.

stream_has_space: Returns amount of space available (in bytes) in the socket's send buffer, or -1 if full.

Actually, I think it's for empty/full, and -1 for an error (say, the transport closed or whatever).

Thanks!
- Andy

author
#9 lore raw

Re: [PATCH 1/1] VSOCK: Introduce VM Sockets

In reply to Gerd Hoffmann

Hi Gerd,

Quoted 4 lines
Quoted 4 lines

+/* Option name for socket's service label. Use as the option name in
+ * setsockopt(3) or getsockopt(3) to set or get the service label for a socket.
+ * The service label is a C-style NUL-terminated string. Only available

Quoted 8 lines

include/uapi/linux/vm_sockets.h line 62

Quoted 6 lines

for
+ * hypervisor endpoints.
+ */

include/uapi/linux/vm_sockets.h new file +3 -0
+
+#define SO_VM_SOCKETS_SERVICE_LABEL 4
+

What is this and how does it work?

Oops, that's specific to ESX. Thankfully it's only in the header and not in anything under net/vmw_vsock, so removing it is easy. I'll send out a patch in the morning.

Thanks!
- Andy

#5 lore raw

Re: [PATCH 1/1] VSOCK: Introduce VM Sockets

In reply to Andy King
Quoted 11 lines · Andy King

Hi Gerd,

Quoted 1 line
Quoted 1 line

+struct vsock_transport {

...

Quoted 2 lines

Whoa. This has grown *alot*. Care to explain this please? Patch creating a Documentation/virtual/vsock.txt would be cool.

Yes, it grew because of the notification stuff, which I'd forgotten about until I removed the vmci header from the core code. You are free to use empty functions for these if they don't make any sense for virtio.

I've seen you have a notify_ops in the vmci bits. Do you have different notify ops depending on socket type or something? Does it make sense to move the notify ops ptr into "struct vsock_sock" maybe?

And can we make it optional please (i.e. allow the function pointers to be NULL)?

Quoted 4 lines

The alternative is for us to move the entire body of vsock_stream_recv/send into the transport, where we can hide the notification stuff, but it seems like folks will just end up duplicating a lot of code then.

Sounds not so good. However, it is still not very clear what this notification stuff is all about. And it's not just notification, the calls can return errors too.

Which problem you are trying to tackle with the notifications?

Quoted 9 lines
Quoted 3 lines

stream_has_data + stream_has_space + stream_rcvhiwat look like they are needed for buffer management. Details please (especially for stream_rcvhiwat).

stream_has_data: Returns amount of data available (in bytes) in the socket's receive buffer, or -1 if empty.

stream_has_space: Returns amount of space available (in bytes) in the socket's send buffer, or -1 if full.

As one would expect from the names, good.

Quoted 4 lines

stream_rcvhiwat: The upper bound on the socket's receive buffer. Which technically is the same as the value returned by get_buffer_size(), so perhaps we could substitute that here and drop this one.

Yes, please.

Quoted 5 lines
Quoted 1 line

What is stream_is_active?

For the VMCI transport, it indicates if the underlying queuepair is still around (i.e., make sure we haven't torn it down while sleeping in a blocking send or receive). Perhaps it's not the best name?

How you'd hit that? Peer closing the socket while sleeping? Other thread closing the socket wile sleeping? Both?

I think a state field in struct vsock_sock would be a better solution here.

Quoted 5 lines
Quoted 1 line

What is *_allow?

It's very basic filtering. We have specific addresses that we don't allow, and we look for them in the allow() functions. You can just return true if you like.

Can we make those calls optional too please?

Quoted 5 lines
Quoted 1 line

What are all those notify_* calls?

They're to do with signaling and flow-control. Again, they might not make any sense at all, but it's hard to know without having written another transport :)

I don't see a immediate need for them in the virto transport, but it's hard to say without knowing what exactly they are doing.

Quoted 7 lines
Quoted 2 lines

Why do you need vsock_transport_{send,recv}_notify_data structs? Can't this live in vsock_sock->trans?

Those have to be setup on a per-call basis (per-thread), so it's just easier to have them on the stack of the send/recv calls. If you think there's a better name, or a better way to allocate them, I'm all ears.

Hmm. The struct content seems to be vmci-specific and it is in generic code, which isn't that nice.

The notify_*_init could return a opaque pointer instead. But then you'll need a notify_*_free too. And you can't place it on the stack and thus have a allocation in the hot path, which I guess you are trying to avoid in the first place.

No good idea offhand, but maybe that changes if the purpose of all those notify_* calls is more clear.

cheers,
Gerd

#10 lore raw

Re: [PATCH 1/1] VSOCK: Introduce VM Sockets

In reply to Andy King

net/vmw_vsock/af_vsock.c line 1868

Quoted 9 lines · Andy King
net/vmw_vsock/af_vsock.c new file +9 -0
+static int vsock_create(struct net *net, struct socket *sock,
+			int protocol, int kern)
+{
+	if (!sock)
+		return -EINVAL;
+
+	if (protocol)
+		return -EPROTONOSUPPORT;
+

IMO protocol == PF_VSOCK should not get rejected here.

cheers,
Gerd

author
#11 lore raw

Re: [PATCH 1/1] VSOCK: Introduce VM Sockets

Quoted 5 lines

net/vmw_vsock/af_vsock.c line 1868

Quoted 3 lines
net/vmw_vsock/af_vsock.c new file +3 -0
+	if (protocol)
+		return -EPROTONOSUPPORT;
+

IMO protocol == PF_VSOCK should not get rejected here.

Agreed, let me fix that too.

Thanks!
- Andy

author
#6 lore raw

Re: [PATCH 1/1] VSOCK: Introduce VM Sockets

In reply to Gerd Hoffmann
Quoted 3 lines

I've seen you have a notify_ops in the vmci bits. Do you have different notify ops depending on socket type or something? Does it make sense to move the notify ops ptr into "struct vsock_sock" maybe?

The notify stuff only applies to STREAMs. However, we have two different notify impls, one for legacy ESX and one for newer, and we figure out at runtime which protocol we're using with the hypervisor and set the callbacks appropriately. The difference between the two is that the newer one is much smarter and knows not to signal (the peer) quite so much, i.e., it has some basic but sensible flow-control, which improves performance quite a bit. Again, that might not make any sense at all for virtio. Do you need to signal when you enqueue to a ring? And is there coalescing? Dunno...

Quoted 2 lines

And can we make it optional please (i.e. allow the function pointers to be NULL)?

They were originally allowed to be NULL, but I changed it in the last round of patches while moving them into the transport, since I disliked the NULL checks so much. I can put them back, but that's a bigger change, and I'm not sure we want to push large patches to Dave right now :)

Quoted 1 line

Which problem you are trying to tackle with the notifications?

It's to do with signaling the peer, or more appropriately, trying to avoid signaling the peer when possible. The naive impl. is to signal every time we enqueue or dequeue data (into our VMCI queuepairs). But signaling is slow, since it involves a world exit, so we prefer not to. Which means we need to keep track of rate of flow and figure out when we should and should not, and that's what all the notification stuff does. It's...ugly...

Quoted 8 lines
Quoted 3 lines

For the VMCI transport, it indicates if the underlying queuepair is still around (i.e., make sure we haven't torn it down while sleeping in a blocking send or receive). Perhaps it's not the best name?

How you'd hit that? Peer closing the socket while sleeping? Other thread closing the socket wile sleeping? Both?

I think a state field in struct vsock_sock would be a better solution here.

Hrm, lemme think about this one.

Quoted 8 lines
Quoted 6 lines
Quoted 2 lines

What is *_allow?

It's very basic filtering. We have specific addresses that we don't allow, and we look for them in the allow() functions. You can just return true if you like.

Can we make those calls optional too please?

Sure.

Quoted 4 lines

The notify_*_init could return a opaque pointer instead. But then you'll need a notify_*_free too. And you can't place it on the stack and thus have a allocation in the hot path, which I guess you are trying to avoid in the first place.

Avoiding allocation is good, but at the same time, I wonder if it's not a big deal compared with the time spent copying out of the buffers, in which case it won't matter. So maybe we can do this.

Thanks!
- Andy

#7 lore raw

Re: [PATCH 1/1] VSOCK: Introduce VM Sockets

Hi,

Quoted 8 lines
Quoted 3 lines

I've seen you have a notify_ops in the vmci bits. Do you have different notify ops depending on socket type or something? Does it make sense to move the notify ops ptr into "struct vsock_sock" maybe?

The notify stuff only applies to STREAMs. However, we have two different notify impls, one for legacy ESX and one for newer, and we figure out at runtime which protocol we're using with the hypervisor and set the callbacks appropriately.

Ok.

Quoted 4 lines

The difference between the two is that the
newer one is much smarter and knows not to signal (the peer) quite so much, i.e., it has some basic but sensible flow-control, which improves performance quite a bit.

Yea, with that background it makes more sense. I think we can reduce number of hooks though.

Looking at vsock_stream_sendmsg:
* notify_send_init -- needed I guess.
* notify_send_pre_block -- needed too, I guess you'll force signaling the peer here (buffers full and there is more data).
* notify_send_pre_enqueue + notify_send_post_enqueue look like they could easily be folded into stream_enqueue.

Quoted 3 lines

Again, that might not make any sense at all
for virtio. Do you need to signal when you enqueue to a ring? And is there coalescing?

Sure virtio signals, we have to if we don't want poll ;)

Usually virtio only signals in case it finds the ring empty, if there are requests not yet processed by the peer there is no need to signal. The ring lives in guest memory and to figure whenever the peer has seen the requests in there we only need a memory barrier, not a vmexit.

In the end it is up to the driver when he signals the peer. The virtio net driver goes beyond the simple "signal-when-the-ring-is-empty" and has some logic for coalescing things when there is a high network load, while trying to not trade that for high latencies when the virtual nic is almost idle.

I guess you try archiving something simliar with vsock/vmci using the notifications, and yes, we might want use them with virtio too some day.
Most likely not for the first revision though, there are more important
issues to tackle first.

Quoted 8 lines
Quoted 2 lines

And can we make it optional please (i.e. allow the function pointers to be NULL)?

They were originally allowed to be NULL, but I changed it in the last round of patches while moving them into the transport, since I disliked the NULL checks so much. I can put them back, but that's a bigger change, and I'm not sure we want to push large patches to Dave right now :)

Yea, it's probably better to discuss+collect the refinements and send them batched.

Quoted 9 lines
Quoted 1 line

Which problem you are trying to tackle with the notifications?

It's to do with signaling the peer, or more appropriately, trying to avoid signaling the peer when possible. The naive impl. is to signal every time we enqueue or dequeue data (into our VMCI queuepairs). But signaling is slow, since it involves a world exit, so we prefer not to. Which means we need to keep track of rate of flow and figure out when we should and should not, and that's what all the notification stuff does. It's...ugly...

But makes sense even if it isn't that pretty.

But /me wonders why you maintain the notify state per-call and not per-socket/queuepair. For the data flow it shouldn't make a difference whenever the application does a few send(big-buffer) or many send(small-buffer) calls.

Quoted 10 lines
Quoted 8 lines
Quoted 3 lines

For the VMCI transport, it indicates if the underlying queuepair is still around (i.e., make sure we haven't torn it down while sleeping in a blocking send or receive). Perhaps it's not the best name?

How you'd hit that? Peer closing the socket while sleeping? Other thread closing the socket wile sleeping? Both?

I think a state field in struct vsock_sock would be a better solution here.

Hrm, lemme think about this one.

There is already vsock->sk.sk_state ...

cheers,
Gerd

From e085c81d3fc95a7e2e938deec65843ba7c00afe3 Mon Sep 17 00:00:00 2001
From: Gerd Hoffmann <[email protected]>
Date: Wed, 13 Feb 2013 18:00:19 +0100
Subject: [PATCH 2/4] af_vsock: don't overwrite sock->state

We set sock->state to SS_CONNECTING before calling the transport, no need to do that again afterwards, thereby overwriting any updates the transport's connect function might have done.

---
 net/vmw_vsock/af_vsock.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
net/vmw_vsock/af_vsock.c +3 -3
index 54bb7bd..e5d1467 100644
@@ -1184,11 +1184,11 @@ static int vsock_stream_connect(struct socket *sock, struct sockaddr *addr,
 		if (err < 0)
 			goto out;
 
-		/* Mark sock as connecting and set the error code to in
+		/* When still connecting set the error code to in
 		 * progress in case this is a non-blocking connect.
 		 */
-		sock->state = SS_CONNECTING;
-		err = -EINPROGRESS;
+		if (sock->state == SS_CONNECTING)
+			err = -EINPROGRESS;
 	}
 
 	/* The receive path will handle all communication until we are able to
Signature · 1 line
1.7.9.7

_______________________________________________
Virtualization mailing list
[email protected]
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

#13 lore raw

Re: [PATCH 1/1] VSOCK: Introduce VM Sockets

In reply to Andy King

net/vmw_vsock/af_vsock.c line 1632

Quoted 3 lines · Andy King
net/vmw_vsock/af_vsock.c new file +3 -0
+		written = transport->stream_enqueue(
+				vsk, msg->msg_iov,
+				len - total_written);

Hmm, shouldn't we pass total_written to stream_enqueue here?

In case a blocking send(big-buffer) call gets splitted into multiple stream_enqueue calls the second (and further) stream_enqueue calls need to know at which msg offset they should continue sending the data, no?

cheers,
Gerd

#16 lore raw

Re: [PATCH 1/1] VSOCK: Introduce VM Sockets

In reply to Andy King

Hi Andy,

Quoted 14 lines · Andy King

+ * Specifically, we initialize the vsock_bind_table array to a size of
+ * VSOCK_HASH_SIZE + 1 so that vsock_bind_table[0] through
+ * vsock_bind_table[VSOCK_HASH_SIZE - 1] are for bound sockets and
+ * vsock_bind_table[VSOCK_HASH_SIZE] is for unbound sockets. The hash function
+ * mods with VSOCK_HASH_SIZE - 1 to ensure this.
+ */

net/vmw_vsock/af_vsock.c new file +8 -0
+#define VSOCK_HASH_SIZE         251
+#define MAX_PORT_RETRIES        24
+
+#define VSOCK_HASH(addr)        ((addr)->svm_port % (VSOCK_HASH_SIZE - 1))
+#define vsock_bound_sockets(addr) (&vsock_bind_table[VSOCK_HASH(addr)])
+#define vsock_unbound_sockets     (&vsock_bind_table[VSOCK_HASH_SIZE])
+
+/* XXX This can probably be implemented in a better way. */

net/vmw_vsock/af_vsock.c line 169

Quoted 10 lines
net/vmw_vsock/af_vsock.c new file +10 -0
+#define VSOCK_CONN_HASH(src, dst)                              \
+       (((src)->svm_cid ^ (dst)->svm_port) % (VSOCK_HASH_SIZE - 1))
+#define vsock_connected_sockets(src, dst)              \
+       (&vsock_connected_table[VSOCK_CONN_HASH(src, dst)])
+#define vsock_connected_sockets_vsk(vsk)                               \
+       vsock_connected_sockets(&(vsk)->remote_addr, &(vsk)->local_addr)
+
+static struct list_head vsock_bind_table[VSOCK_HASH_SIZE + 1];
+static struct list_head vsock_connected_table[VSOCK_HASH_SIZE];
+static DEFINE_SPINLOCK(vsock_table_lock);

Why isn't it using the kernel's linux/hashtable.h?

Thanks,
Sasha

#19 lore raw

Re: [PATCH 1/1] VSOCK: Introduce VM Sockets

In reply to Andy King
Quoted 9 lines · Andy King
include/uapi/linux/vm_sockets.h new file +9 -0
+/* Use this as the destination CID in an address when referring to the
+ * hypervisor.  VMCI relies on it being 0, but this would be useful for other
+ * transports too.
+ */
+
+#define VMADDR_CID_HYPERVISOR 0
+
+/* This CID is specific to VMCI and can be considered reserved (even VMCI
+ * doesn't use it anymore, it's a legacy value from an older release).

include/uapi/linux/vm_sockets.h line 122

Quoted 10 lines
include/uapi/linux/vm_sockets.h new file +10 -0
+ */
+
+#define VMADDR_CID_RESERVED 1
+
+/* Use this as the destination CID in an address when referring to the host
+ * (any process other than the hypervisor).  VMCI relies on it being 2, but
+ * this would be useful for other transports too.
+ */
+
+#define VMADDR_CID_HOST 2

CIDs larger than 2 will address other VMs on the same host, with the hypervisor forwarding the data from one guest to the other and back?

How does VMADDR_CID_HOST work? Given the age of the vsock transport layer I don't think you have a vsock_transport_host.ko module ...

Is there some registry for the port numbers?

cheers,
Gerd

author
#12 lore raw

Re: [PATCH 1/1] VSOCK: Introduce VM Sockets

In reply to Gerd Hoffmann
Quoted 5 lines

net/vmw_vsock/af_vsock.c line 1868

Quoted 3 lines
net/vmw_vsock/af_vsock.c new file +3 -0
+	if (protocol)
+		return -EPROTONOSUPPORT;
+

IMO protocol == PF_VSOCK should not get rejected here.

Good catch, I've sent out a patch for this.

Thanks!
- Andy

author
#14 lore raw

Re: [PATCH 1/1] VSOCK: Introduce VM Sockets

In reply to Gerd Hoffmann

Hi Gerd,

Quoted 9 lines

net/vmw_vsock/af_vsock.c line 1632

Quoted 3 lines
net/vmw_vsock/af_vsock.c new file +3 -0
+		written = transport->stream_enqueue(
+				vsk, msg->msg_iov,
+				len - total_written);

Hmm, shouldn't we pass total_written to stream_enqueue here?

In case a blocking send(big-buffer) call gets splitted into multiple stream_enqueue calls the second (and further) stream_enqueue calls need to know at which msg offset they should continue sending the data, no?

On the client side, the iov tracks it internally; see memcpy_fromiovec(). On the socket side, VMCI uses a ring buffer, so it also knows its position internally. Or did I misunderstand the question?

Thanks!
- Andy

author
#17 lore raw

Re: [PATCH 1/1] VSOCK: Introduce VM Sockets

In reply to Sasha Levin

Hi Sasha,

Quoted 2 lines
Quoted 2 lines

+ * Specifically, we initialize the vsock_bind_table array to a size of
+ * VSOCK_HASH_SIZE + 1 so that vsock_bind_table[0] through

...

Quoted 1 line

Why isn't it using the kernel's linux/hashtable.h?

Gah, that's a leftover from when it was platform independent :/ I have a patch lying around to address this, once we have some more fixes batched up I'll send it out. Sorry about that!

Thanks!
- Andy

author
#18 lore raw

Re: [PATCH 1/1] VSOCK: Introduce VM Sockets

In reply to Sasha Levin

Hi Sasha,

Quoted 2 lines
Quoted 2 lines

+ * Specifically, we initialize the vsock_bind_table array to a size of
+ * VSOCK_HASH_SIZE + 1 so that vsock_bind_table[0] through

...

Quoted 1 line

Why isn't it using the kernel's linux/hashtable.h?

Gah, that's a leftover from when it was platform independent :/ I have a patch lying around to address this, once we have some more fixes batched up I'll send it out. Sorry about that!

Thanks!
- Andy

#15 lore raw

Re: [PATCH 1/1] VSOCK: Introduce VM Sockets

In reply to Andy King
Quoted 8 lines · Andy King

Hi Gerd,

Quoted 6 lines

net/vmw_vsock/af_vsock.c line 1632

Quoted 3 lines
net/vmw_vsock/af_vsock.c new file +3 -0
+		written = transport->stream_enqueue(
+				vsk, msg->msg_iov,
+				len - total_written);

Hmm, shouldn't we pass total_written to stream_enqueue here?

Quoted 5 lines
Quoted 3 lines

In case a blocking send(big-buffer) call gets splitted into multiple stream_enqueue calls the second (and further) stream_enqueue calls need to know at which msg offset they should continue sending the data, no?

On the client side, the iov tracks it internally; see memcpy_fromiovec().

Ah, memcpy_fromiovec patches the iovec to keep track of the offset. Wasn't aware it does this. Yes, we don't need to pass the offset then.

cheers,
Gerd