All of lore.kernel.org
 help / color / mirror / Atom feed
From: Arseniy Krasnov <oxffffaa@gmail.com>
To: Bobby Eshleman <bobbyeshleman@gmail.com>
Cc: Bobby Eshleman <bobby.eshleman@bytedance.com>,
	Stefan Hajnoczi <stefanha@redhat.com>,
	Stefano Garzarella <sgarzare@redhat.com>,
	"Michael S. Tsirkin" <mst@redhat.com>,
	Jason Wang <jasowang@redhat.com>,
	Xuan Zhuo <xuanzhuo@linux.alibaba.com>,
	"David S. Miller" <davem@davemloft.net>,
	Eric Dumazet <edumazet@google.com>,
	Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
	"K. Y. Srinivasan" <kys@microsoft.com>,
	Haiyang Zhang <haiyangz@microsoft.com>,
	Wei Liu <wei.liu@kernel.org>, Dexuan Cui <decui@microsoft.com>,
	Bryan Tan <bryantan@vmware.com>, Vishnu Dasa <vdasa@vmware.com>,
	VMware PV-Drivers Reviewers <pv-drivers@vmware.com>,
	Dan Carpenter <dan.carpenter@linaro.org>,
	Simon Horman <simon.horman@corigine.com>,
	kvm@vger.kernel.org, virtualization@lists.linux-foundation.org,
	netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
	linux-hyperv@vger.kernel.org, bpf@vger.kernel.org
Subject: Re: [PATCH RFC net-next v5 01/14] af_vsock: generalize vsock_dgram_recvmsg() to all transports
Date: Thu, 27 Jul 2023 10:53:14 +0300	[thread overview]
Message-ID: <f0bca831-207c-6cbb-48e9-7d2ea02229ff@gmail.com> (raw)
In-Reply-To: <ZMFkFE0AqaOUfric@bullseye>



On 26.07.2023 21:21, Bobby Eshleman wrote:
> On Mon, Jul 24, 2023 at 09:11:44PM +0300, Arseniy Krasnov wrote:
>>
>>
>> On 19.07.2023 03:50, Bobby Eshleman wrote:
>>> This commit drops the transport->dgram_dequeue callback and makes
>>> vsock_dgram_recvmsg() generic to all transports.
>>>
>>> To make this possible, two transport-level changes are introduced:
>>> - implementation of the ->dgram_addr_init() callback to initialize
>>>   the sockaddr_vm structure with data from incoming socket buffers.
>>> - transport implementations set the skb->data pointer to the beginning
>>>   of the payload prior to adding the skb to the socket's receive queue.
>>>   That is, they must use skb_pull() before enqueuing. This is an
>>>   agreement between the transport and the socket layer that skb->data
>>>   always points to the beginning of the payload (and not, for example,
>>>   the packet header).
>>>
>>> Signed-off-by: Bobby Eshleman <bobby.eshleman@bytedance.com>
>>> ---
>>>  drivers/vhost/vsock.c                   |  1 -
>>>  include/linux/virtio_vsock.h            |  5 ---
>>>  include/net/af_vsock.h                  |  3 +-
>>>  net/vmw_vsock/af_vsock.c                | 40 ++++++++++++++++++++++-
>>>  net/vmw_vsock/hyperv_transport.c        |  7 ----
>>>  net/vmw_vsock/virtio_transport.c        |  1 -
>>>  net/vmw_vsock/virtio_transport_common.c |  9 -----
>>>  net/vmw_vsock/vmci_transport.c          | 58 ++++++---------------------------
>>>  net/vmw_vsock/vsock_loopback.c          |  1 -
>>>  9 files changed, 50 insertions(+), 75 deletions(-)
>>>
>>> diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c
>>> index 6578db78f0ae..ae8891598a48 100644
>>> --- a/drivers/vhost/vsock.c
>>> +++ b/drivers/vhost/vsock.c
>>> @@ -410,7 +410,6 @@ static struct virtio_transport vhost_transport = {
>>>  		.cancel_pkt               = vhost_transport_cancel_pkt,
>>>  
>>>  		.dgram_enqueue            = virtio_transport_dgram_enqueue,
>>> -		.dgram_dequeue            = virtio_transport_dgram_dequeue,
>>>  		.dgram_bind               = virtio_transport_dgram_bind,
>>>  		.dgram_allow              = virtio_transport_dgram_allow,
>>>  
>>> diff --git a/include/linux/virtio_vsock.h b/include/linux/virtio_vsock.h
>>> index c58453699ee9..18cbe8d37fca 100644
>>> --- a/include/linux/virtio_vsock.h
>>> +++ b/include/linux/virtio_vsock.h
>>> @@ -167,11 +167,6 @@ virtio_transport_stream_dequeue(struct vsock_sock *vsk,
>>>  				size_t len,
>>>  				int type);
>>>  int
>>> -virtio_transport_dgram_dequeue(struct vsock_sock *vsk,
>>> -			       struct msghdr *msg,
>>> -			       size_t len, int flags);
>>> -
>>> -int
>>>  virtio_transport_seqpacket_enqueue(struct vsock_sock *vsk,
>>>  				   struct msghdr *msg,
>>>  				   size_t len);
>>> diff --git a/include/net/af_vsock.h b/include/net/af_vsock.h
>>> index 0e7504a42925..305d57502e89 100644
>>> --- a/include/net/af_vsock.h
>>> +++ b/include/net/af_vsock.h
>>> @@ -120,11 +120,10 @@ struct vsock_transport {
>>>  
>>>  	/* DGRAM. */
>>>  	int (*dgram_bind)(struct vsock_sock *, struct sockaddr_vm *);
>>> -	int (*dgram_dequeue)(struct vsock_sock *vsk, struct msghdr *msg,
>>> -			     size_t len, int flags);
>>>  	int (*dgram_enqueue)(struct vsock_sock *, struct sockaddr_vm *,
>>>  			     struct msghdr *, size_t len);
>>>  	bool (*dgram_allow)(u32 cid, u32 port);
>>> +	void (*dgram_addr_init)(struct sk_buff *skb, struct sockaddr_vm *addr);
>>>  
>>>  	/* STREAM. */
>>>  	/* TODO: stream_bind() */
>>> diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
>>> index deb72a8c44a7..ad71e084bf2f 100644
>>> --- a/net/vmw_vsock/af_vsock.c
>>> +++ b/net/vmw_vsock/af_vsock.c
>>> @@ -1272,11 +1272,15 @@ static int vsock_dgram_connect(struct socket *sock,
>>>  int vsock_dgram_recvmsg(struct socket *sock, struct msghdr *msg,
>>>  			size_t len, int flags)
>>>  {
>>> +	const struct vsock_transport *transport;
>>>  #ifdef CONFIG_BPF_SYSCALL
>>>  	const struct proto *prot;
>>>  #endif
>>>  	struct vsock_sock *vsk;
>>> +	struct sk_buff *skb;
>>> +	size_t payload_len;
>>>  	struct sock *sk;
>>> +	int err;
>>>  
>>>  	sk = sock->sk;
>>>  	vsk = vsock_sk(sk);
>>> @@ -1287,7 +1291,41 @@ int vsock_dgram_recvmsg(struct socket *sock, struct msghdr *msg,
>>>  		return prot->recvmsg(sk, msg, len, flags, NULL);
>>>  #endif
>>>  
>>> -	return vsk->transport->dgram_dequeue(vsk, msg, len, flags);
>>> +	if (flags & MSG_OOB || flags & MSG_ERRQUEUE)
>>> +		return -EOPNOTSUPP;
>>> +
>>> +	transport = vsk->transport;
>>> +
>>> +	/* Retrieve the head sk_buff from the socket's receive queue. */
>>> +	err = 0;
>>> +	skb = skb_recv_datagram(sk_vsock(vsk), flags, &err);
>>> +	if (!skb)
>>> +		return err;
>>> +
>>> +	payload_len = skb->len;
>>> +
>>> +	if (payload_len > len) {
>>> +		payload_len = len;
>>> +		msg->msg_flags |= MSG_TRUNC;
>>> +	}
>>> +
>>> +	/* Place the datagram payload in the user's iovec. */
>>> +	err = skb_copy_datagram_msg(skb, 0, msg, payload_len);
>>> +	if (err)
>>> +		goto out;
>>> +
>>> +	if (msg->msg_name) {
>>> +		/* Provide the address of the sender. */
>>> +		DECLARE_SOCKADDR(struct sockaddr_vm *, vm_addr, msg->msg_name);
>>> +
>>> +		transport->dgram_addr_init(skb, vm_addr);
>>
>> Do we need check that dgram_addr_init != NULL? because I see that not all transports have this
>> callback set in this patch
>>
> 
> How about adding the check somewhere outside of the hotpath, such as
> when the transport is assigned?

Yes, may be we can return ESOCKTNOSUPPORT if this callback is not provided by transport (as we dereference
it here without any checks).

Thanks, Arseniy

> 
>>> +		msg->msg_namelen = sizeof(*vm_addr);
>>> +	}
>>> +	err = payload_len;
>>> +
>>> +out:
>>> +	skb_free_datagram(&vsk->sk, skb);
>>> +	return err;
>>>  }
>>>  EXPORT_SYMBOL_GPL(vsock_dgram_recvmsg);
>>>  
>>> diff --git a/net/vmw_vsock/hyperv_transport.c b/net/vmw_vsock/hyperv_transport.c
>>> index 7cb1a9d2cdb4..7f1ea434656d 100644
>>> --- a/net/vmw_vsock/hyperv_transport.c
>>> +++ b/net/vmw_vsock/hyperv_transport.c
>>> @@ -556,12 +556,6 @@ static int hvs_dgram_bind(struct vsock_sock *vsk, struct sockaddr_vm *addr)
>>>  	return -EOPNOTSUPP;
>>>  }
>>>  
>>> -static int hvs_dgram_dequeue(struct vsock_sock *vsk, struct msghdr *msg,
>>> -			     size_t len, int flags)
>>> -{
>>> -	return -EOPNOTSUPP;
>>> -}
>>> -
>>>  static int hvs_dgram_enqueue(struct vsock_sock *vsk,
>>>  			     struct sockaddr_vm *remote, struct msghdr *msg,
>>>  			     size_t dgram_len)
>>> @@ -833,7 +827,6 @@ static struct vsock_transport hvs_transport = {
>>>  	.shutdown                 = hvs_shutdown,
>>>  
>>>  	.dgram_bind               = hvs_dgram_bind,
>>> -	.dgram_dequeue            = hvs_dgram_dequeue,
>>>  	.dgram_enqueue            = hvs_dgram_enqueue,
>>>  	.dgram_allow              = hvs_dgram_allow,
>>>  
>>> diff --git a/net/vmw_vsock/virtio_transport.c b/net/vmw_vsock/virtio_transport.c
>>> index e95df847176b..66edffdbf303 100644
>>> --- a/net/vmw_vsock/virtio_transport.c
>>> +++ b/net/vmw_vsock/virtio_transport.c
>>> @@ -429,7 +429,6 @@ static struct virtio_transport virtio_transport = {
>>>  		.cancel_pkt               = virtio_transport_cancel_pkt,
>>>  
>>>  		.dgram_bind               = virtio_transport_dgram_bind,
>>> -		.dgram_dequeue            = virtio_transport_dgram_dequeue,
>>>  		.dgram_enqueue            = virtio_transport_dgram_enqueue,
>>>  		.dgram_allow              = virtio_transport_dgram_allow,
>>>  
>>> diff --git a/net/vmw_vsock/virtio_transport_common.c b/net/vmw_vsock/virtio_transport_common.c
>>> index b769fc258931..01ea1402ad40 100644
>>> --- a/net/vmw_vsock/virtio_transport_common.c
>>> +++ b/net/vmw_vsock/virtio_transport_common.c
>>> @@ -583,15 +583,6 @@ virtio_transport_seqpacket_enqueue(struct vsock_sock *vsk,
>>>  }
>>>  EXPORT_SYMBOL_GPL(virtio_transport_seqpacket_enqueue);
>>>  
>>> -int
>>> -virtio_transport_dgram_dequeue(struct vsock_sock *vsk,
>>> -			       struct msghdr *msg,
>>> -			       size_t len, int flags)
>>> -{
>>> -	return -EOPNOTSUPP;
>>> -}
>>> -EXPORT_SYMBOL_GPL(virtio_transport_dgram_dequeue);
>>> -
>>>  s64 virtio_transport_stream_has_data(struct vsock_sock *vsk)
>>>  {
>>>  	struct virtio_vsock_sock *vvs = vsk->trans;
>>> diff --git a/net/vmw_vsock/vmci_transport.c b/net/vmw_vsock/vmci_transport.c
>>> index b370070194fa..0bbbdb222245 100644
>>> --- a/net/vmw_vsock/vmci_transport.c
>>> +++ b/net/vmw_vsock/vmci_transport.c
>>> @@ -641,6 +641,7 @@ static int vmci_transport_recv_dgram_cb(void *data, struct vmci_datagram *dg)
>>>  	sock_hold(sk);
>>>  	skb_put(skb, size);
>>>  	memcpy(skb->data, dg, size);
>>> +	skb_pull(skb, VMCI_DG_HEADERSIZE);
>>>  	sk_receive_skb(sk, skb, 0);
>>>  
>>>  	return VMCI_SUCCESS;
>>> @@ -1731,57 +1732,18 @@ static int vmci_transport_dgram_enqueue(
>>>  	return err - sizeof(*dg);
>>>  }
>>>  
>>> -static int vmci_transport_dgram_dequeue(struct vsock_sock *vsk,
>>> -					struct msghdr *msg, size_t len,
>>> -					int flags)
>>> +static void vmci_transport_dgram_addr_init(struct sk_buff *skb,
>>> +					   struct sockaddr_vm *addr)
>>>  {
>>> -	int err;
>>>  	struct vmci_datagram *dg;
>>> -	size_t payload_len;
>>> -	struct sk_buff *skb;
>>> -
>>> -	if (flags & MSG_OOB || flags & MSG_ERRQUEUE)
>>> -		return -EOPNOTSUPP;
>>> -
>>> -	/* Retrieve the head sk_buff from the socket's receive queue. */
>>> -	err = 0;
>>> -	skb = skb_recv_datagram(&vsk->sk, flags, &err);
>>> -	if (!skb)
>>> -		return err;
>>> -
>>> -	dg = (struct vmci_datagram *)skb->data;
>>> -	if (!dg)
>>> -		/* err is 0, meaning we read zero bytes. */
>>> -		goto out;
>>> -
>>> -	payload_len = dg->payload_size;
>>> -	/* Ensure the sk_buff matches the payload size claimed in the packet. */
>>> -	if (payload_len != skb->len - sizeof(*dg)) {
>>> -		err = -EINVAL;
>>> -		goto out;
>>> -	}
>>> -
>>> -	if (payload_len > len) {
>>> -		payload_len = len;
>>> -		msg->msg_flags |= MSG_TRUNC;
>>> -	}
>>> +	unsigned int cid, port;
>>>  
>>> -	/* Place the datagram payload in the user's iovec. */
>>> -	err = skb_copy_datagram_msg(skb, sizeof(*dg), msg, payload_len);
>>> -	if (err)
>>> -		goto out;
>>> -
>>> -	if (msg->msg_name) {
>>> -		/* Provide the address of the sender. */
>>> -		DECLARE_SOCKADDR(struct sockaddr_vm *, vm_addr, msg->msg_name);
>>> -		vsock_addr_init(vm_addr, dg->src.context, dg->src.resource);
>>> -		msg->msg_namelen = sizeof(*vm_addr);
>>> -	}
>>> -	err = payload_len;
>>> +	WARN_ONCE(skb->head == skb->data, "vmci vsock bug: bad dgram skb");
>>>  
>>> -out:
>>> -	skb_free_datagram(&vsk->sk, skb);
>>> -	return err;
>>> +	dg = (struct vmci_datagram *)skb->head;
>>> +	cid = dg->src.context;
>>> +	port = dg->src.resource;
>>> +	vsock_addr_init(addr, cid, port);
>>
>> I think we
>>
>> 1) can short this to:
>>
>> vsock_addr_init(addr, dg->src.context, dg->src.resource);
>>
>> 2) w/o previous point, cid and port better be u32, as VMCI structure has u32 fields 'context' and
>>    'resource' and 'vsock_addr_init()' also has u32 type for both arguments.
>>
>> Thanks, Arseniy
> 
> Sounds good, thanks.
> 
>>
>>>  }
>>>  
>>>  static bool vmci_transport_dgram_allow(u32 cid, u32 port)
>>> @@ -2040,9 +2002,9 @@ static struct vsock_transport vmci_transport = {
>>>  	.release = vmci_transport_release,
>>>  	.connect = vmci_transport_connect,
>>>  	.dgram_bind = vmci_transport_dgram_bind,
>>> -	.dgram_dequeue = vmci_transport_dgram_dequeue,
>>>  	.dgram_enqueue = vmci_transport_dgram_enqueue,
>>>  	.dgram_allow = vmci_transport_dgram_allow,
>>> +	.dgram_addr_init = vmci_transport_dgram_addr_init,
>>>  	.stream_dequeue = vmci_transport_stream_dequeue,
>>>  	.stream_enqueue = vmci_transport_stream_enqueue,
>>>  	.stream_has_data = vmci_transport_stream_has_data,
>>> diff --git a/net/vmw_vsock/vsock_loopback.c b/net/vmw_vsock/vsock_loopback.c
>>> index 5c6360df1f31..2a59dd177c74 100644
>>> --- a/net/vmw_vsock/vsock_loopback.c
>>> +++ b/net/vmw_vsock/vsock_loopback.c
>>> @@ -62,7 +62,6 @@ static struct virtio_transport loopback_transport = {
>>>  		.cancel_pkt               = vsock_loopback_cancel_pkt,
>>>  
>>>  		.dgram_bind               = virtio_transport_dgram_bind,
>>> -		.dgram_dequeue            = virtio_transport_dgram_dequeue,
>>>  		.dgram_enqueue            = virtio_transport_dgram_enqueue,
>>>  		.dgram_allow              = virtio_transport_dgram_allow,
>>>  
>>>
> 
> Thanks,
> Bobby

  reply	other threads:[~2023-07-27  7:53 UTC|newest]

Thread overview: 58+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-07-19  0:50 [PATCH RFC net-next v5 00/14] virtio/vsock: support datagrams Bobby Eshleman
2023-07-19  0:50 ` [PATCH RFC net-next v5 01/14] af_vsock: generalize vsock_dgram_recvmsg() to all transports Bobby Eshleman
2023-07-24 18:11   ` Arseniy Krasnov
2023-07-26 18:21     ` Bobby Eshleman
2023-07-27  7:53       ` Arseniy Krasnov [this message]
2023-07-19  0:50 ` [PATCH RFC net-next v5 02/14] af_vsock: refactor transport lookup code Bobby Eshleman
2023-07-19  0:50 ` [PATCH RFC net-next v5 03/14] af_vsock: support multi-transport datagrams Bobby Eshleman
2023-07-22 21:53   ` Arseniy Krasnov
2023-08-02 22:24     ` Bobby Eshleman
2023-08-03  0:53       ` Bobby Eshleman
2023-08-03 12:42         ` Stefano Garzarella
2023-08-03 12:42           ` Stefano Garzarella
2023-08-03 18:58           ` Bobby Eshleman
2023-08-04 14:11             ` Stefano Garzarella
2023-08-04 14:11               ` Stefano Garzarella
2023-08-04 17:01               ` Bobby Eshleman
2023-07-19  0:50 ` [PATCH RFC net-next v5 04/14] af_vsock: generalize bind table functions Bobby Eshleman
2023-07-19  0:50 ` [PATCH RFC net-next v5 05/14] af_vsock: use a separate dgram bind table Bobby Eshleman
2023-07-19  0:50 ` [PATCH RFC net-next v5 06/14] virtio/vsock: add VIRTIO_VSOCK_TYPE_DGRAM Bobby Eshleman
2023-07-19  0:50 ` [PATCH RFC net-next v5 07/14] virtio/vsock: add common datagram send path Bobby Eshleman
2023-07-22  8:16   ` Arseniy Krasnov
2023-07-26 17:08     ` Bobby Eshleman
2023-07-27  7:57       ` Arseniy Krasnov
2023-08-02 20:08         ` Bobby Eshleman
2023-07-19  0:50 ` [PATCH RFC net-next v5 08/14] af_vsock: add vsock_find_bound_dgram_socket() Bobby Eshleman
2023-07-19  0:50 ` [PATCH RFC net-next v5 09/14] virtio/vsock: add common datagram recv path Bobby Eshleman
2023-07-19  0:50 ` [PATCH RFC net-next v5 10/14] virtio/vsock: add VIRTIO_VSOCK_F_DGRAM feature bit Bobby Eshleman
2023-07-26 18:38   ` Michael S. Tsirkin
2023-07-26 18:38     ` Michael S. Tsirkin
2023-07-27  7:48     ` Stefano Garzarella
2023-07-27  7:48       ` Stefano Garzarella
2023-08-01  4:30       ` Bobby Eshleman
2023-08-01 16:04         ` Stefano Garzarella
2023-08-01 16:04           ` Stefano Garzarella
2023-07-19  0:50 ` [PATCH RFC net-next v5 11/14] vhost/vsock: implement datagram support Bobby Eshleman
2023-07-22  8:42   ` Arseniy Krasnov
2023-07-26 17:55     ` Bobby Eshleman
2023-07-27  8:00       ` Arseniy Krasnov
2023-08-02 21:23         ` Bobby Eshleman
2023-08-04 13:16           ` Arseniy Krasnov
2023-07-27  8:04       ` Arseniy Krasnov
2023-07-26 18:40   ` Michael S. Tsirkin
2023-07-26 18:40     ` Michael S. Tsirkin
2023-08-01  4:26     ` Bobby Eshleman
2023-08-02 19:28     ` Bobby Eshleman
2023-08-12  8:01       ` Bobby Eshleman
2023-07-19  0:50 ` [PATCH RFC net-next v5 12/14] vsock/loopback: " Bobby Eshleman
2023-07-19  0:50 ` [PATCH RFC net-next v5 13/14] virtio/vsock: " Bobby Eshleman
2023-07-22  8:45   ` Arseniy Krasnov
2023-07-26 17:58     ` Bobby Eshleman
2023-07-27  8:09       ` Arseniy Krasnov
2023-08-01  4:14         ` [PATCH RFC net-next v5 13/14] virtio/vsock: implement datagram supporty Bobby Eshleman
2023-07-19  0:50 ` [PATCH RFC net-next v5 14/14] test/vsock: add vsock dgram tests Bobby Eshleman
2023-07-22  8:51 ` [PATCH RFC net-next v5 00/14] virtio/vsock: support datagrams Arseniy Krasnov
2023-07-26 18:02 ` Bobby Eshleman
2023-07-27  7:51 ` Michael S. Tsirkin
2023-07-27  7:51   ` Michael S. Tsirkin
2023-08-01  5:30   ` Bobby Eshleman

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=f0bca831-207c-6cbb-48e9-7d2ea02229ff@gmail.com \
    --to=oxffffaa@gmail.com \
    --cc=bobby.eshleman@bytedance.com \
    --cc=bobbyeshleman@gmail.com \
    --cc=bpf@vger.kernel.org \
    --cc=bryantan@vmware.com \
    --cc=dan.carpenter@linaro.org \
    --cc=davem@davemloft.net \
    --cc=decui@microsoft.com \
    --cc=edumazet@google.com \
    --cc=haiyangz@microsoft.com \
    --cc=jasowang@redhat.com \
    --cc=kuba@kernel.org \
    --cc=kvm@vger.kernel.org \
    --cc=kys@microsoft.com \
    --cc=linux-hyperv@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mst@redhat.com \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=pv-drivers@vmware.com \
    --cc=sgarzare@redhat.com \
    --cc=simon.horman@corigine.com \
    --cc=stefanha@redhat.com \
    --cc=vdasa@vmware.com \
    --cc=virtualization@lists.linux-foundation.org \
    --cc=wei.liu@kernel.org \
    --cc=xuanzhuo@linux.alibaba.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.