Stefano Garzarella
2019-Jul-10 15:37 UTC
[RFC] virtio-net: share receive_*() and add_recvbuf_*() with virtio-vsock
Hi, as Jason suggested some months ago, I looked better at the virtio-net driver to understand if we can reuse some parts also in the virtio-vsock driver, since we have similar challenges (mergeable buffers, page allocation, small packets, etc.). Initially, I would add the skbuff in the virtio-vsock in order to re-use receive_*() functions. Then I would move receive_[small, big, mergeable]() and add_recvbuf_[small, big, mergeable]() outside of virtio-net driver, in order to call them also from virtio-vsock. I need to do some refactoring (e.g. leave the XDP part on the virtio-net driver), but I think it is feasible. The idea is to create a virtio-skb.[h,c] where put these functions and a new object where stores some attributes needed (e.g. hdr_len ) and status (e.g. some fields of struct receive_queue). This is an idea of virtio-skb.h that I have in mind: struct virtskb; struct sk_buff *virtskb_receive_small(struct virtskb *vs, ...); struct sk_buff *virtskb_receive_big(struct virtskb *vs, ...); struct sk_buff *virtskb_receive_mergeable(struct virtskb *vs, ...); int virtskb_add_recvbuf_small(struct virtskb*vs, ...); int virtskb_add_recvbuf_big(struct virtskb *vs, ...); int virtskb_add_recvbuf_mergeable(struct virtskb *vs, ...); For the Guest->Host path it should be easier, so maybe I can add a "virtskb_send(struct virtskb *vs, struct sk_buff *skb)" with a part of the code of xmit_skb(). Let me know if you have in mind better names or if I should put these function in another place. I would like to leave the control part completely separate, so, for example, the two drivers will negotiate the features independently and they will call the right virtskb_receive_*() function based on the negotiation. I already started to work on it, but before to do more steps and send an RFC patch, I would like to hear your opinion. Do you think that makes sense? Do you see any issue or a better solution? Thanks in advance, Stefano
Jason Wang
2019-Jul-11 07:37 UTC
[RFC] virtio-net: share receive_*() and add_recvbuf_*() with virtio-vsock
On 2019/7/10 ??11:37, Stefano Garzarella wrote:> Hi, > as Jason suggested some months ago, I looked better at the virtio-net driver to > understand if we can reuse some parts also in the virtio-vsock driver, since we > have similar challenges (mergeable buffers, page allocation, small > packets, etc.). > > Initially, I would add the skbuff in the virtio-vsock in order to re-use > receive_*() functions.Yes, that will be a good step.> Then I would move receive_[small, big, mergeable]() and > add_recvbuf_[small, big, mergeable]() outside of virtio-net driver, in order to > call them also from virtio-vsock. I need to do some refactoring (e.g. leave the > XDP part on the virtio-net driver), but I think it is feasible. > > The idea is to create a virtio-skb.[h,c] where put these functions and a new > object where stores some attributes needed (e.g. hdr_len ) and status (e.g. > some fields of struct receive_queue).My understanding is we could be more ambitious here. Do you see any blocker for reusing virtio-net directly? It's better to reuse not only the functions but also the logic like NAPI to avoid re-inventing something buggy and duplicated.> This is an idea of virtio-skb.h that > I have in mind: > struct virtskb;What fields do you want to store in virtskb? It looks to be exist sk_buff is flexible enough to us?> > struct sk_buff *virtskb_receive_small(struct virtskb *vs, ...); > struct sk_buff *virtskb_receive_big(struct virtskb *vs, ...); > struct sk_buff *virtskb_receive_mergeable(struct virtskb *vs, ...); > > int virtskb_add_recvbuf_small(struct virtskb*vs, ...); > int virtskb_add_recvbuf_big(struct virtskb *vs, ...); > int virtskb_add_recvbuf_mergeable(struct virtskb *vs, ...); > > For the Guest->Host path it should be easier, so maybe I can add a > "virtskb_send(struct virtskb *vs, struct sk_buff *skb)" with a part of the code > of xmit_skb().I may miss something, but I don't see any thing that prevents us from using xmit_skb() directly.> > Let me know if you have in mind better names or if I should put these function > in another place. > > I would like to leave the control part completely separate, so, for example, > the two drivers will negotiate the features independently and they will call > the right virtskb_receive_*() function based on the negotiation.If it's one the issue of negotiation, we can simply change the virtnet_probe() to deal with different devices.> > I already started to work on it, but before to do more steps and send an RFC > patch, I would like to hear your opinion. > Do you think that makes sense? > Do you see any issue or a better solution?I still think we need to seek a way of adding some codes on virtio-net.c directly if there's no huge different in the processing of TX/RX. That would save us a lot time. Thanks> > Thanks in advance, > Stefano
Stefano Garzarella
2019-Jul-11 11:41 UTC
[RFC] virtio-net: share receive_*() and add_recvbuf_*() with virtio-vsock
On Thu, Jul 11, 2019 at 03:37:00PM +0800, Jason Wang wrote:> > On 2019/7/10 ??11:37, Stefano Garzarella wrote: > > Hi, > > as Jason suggested some months ago, I looked better at the virtio-net driver to > > understand if we can reuse some parts also in the virtio-vsock driver, since we > > have similar challenges (mergeable buffers, page allocation, small > > packets, etc.). > > > > Initially, I would add the skbuff in the virtio-vsock in order to re-use > > receive_*() functions. > > > Yes, that will be a good step. >Okay, I'll go on this way.> > > Then I would move receive_[small, big, mergeable]() and > > add_recvbuf_[small, big, mergeable]() outside of virtio-net driver, in order to > > call them also from virtio-vsock. I need to do some refactoring (e.g. leave the > > XDP part on the virtio-net driver), but I think it is feasible. > > > > The idea is to create a virtio-skb.[h,c] where put these functions and a new > > object where stores some attributes needed (e.g. hdr_len ) and status (e.g. > > some fields of struct receive_queue). > > > My understanding is we could be more ambitious here. Do you see any blocker > for reusing virtio-net directly? It's better to reuse not only the functions > but also the logic like NAPI to avoid re-inventing something buggy and > duplicated. >These are my concerns: - virtio-vsock is not a "net_device", so a lot of code related to ethtool, net devices (MAC address, MTU, speed, VLAN, XDP, offloading) will be not used by virtio-vsock. - virtio-vsock has a different header. We can consider it as part of virtio_net payload, but it precludes the compatibility with old hosts. This was one of the major doubts that made me think about using only the send/recv skbuff functions, that it shouldn't break the compatibility.> > > This is an idea of virtio-skb.h that > > I have in mind: > > struct virtskb; > > > What fields do you want to store in virtskb? It looks to be exist sk_buff is > flexible enough to us?My idea is to store queues information, like struct receive_queue or struct send_queue, and some device attributes (e.g. hdr_len ).> > > > > > struct sk_buff *virtskb_receive_small(struct virtskb *vs, ...); > > struct sk_buff *virtskb_receive_big(struct virtskb *vs, ...); > > struct sk_buff *virtskb_receive_mergeable(struct virtskb *vs, ...); > > > > int virtskb_add_recvbuf_small(struct virtskb*vs, ...); > > int virtskb_add_recvbuf_big(struct virtskb *vs, ...); > > int virtskb_add_recvbuf_mergeable(struct virtskb *vs, ...); > > > > For the Guest->Host path it should be easier, so maybe I can add a > > "virtskb_send(struct virtskb *vs, struct sk_buff *skb)" with a part of the code > > of xmit_skb(). > > > I may miss something, but I don't see any thing that prevents us from using > xmit_skb() directly. >Yes, but my initial idea was to make it more parametric and not related to the virtio_net_hdr, so the 'hdr_len' could be a parameter and the 'num_buffers' should be handled by the caller.> > > > > Let me know if you have in mind better names or if I should put these function > > in another place. > > > > I would like to leave the control part completely separate, so, for example, > > the two drivers will negotiate the features independently and they will call > > the right virtskb_receive_*() function based on the negotiation. > > > If it's one the issue of negotiation, we can simply change the > virtnet_probe() to deal with different devices. > > > > > > I already started to work on it, but before to do more steps and send an RFC > > patch, I would like to hear your opinion. > > Do you think that makes sense? > > Do you see any issue or a better solution? > > > I still think we need to seek a way of adding some codes on virtio-net.c > directly if there's no huge different in the processing of TX/RX. That would > save us a lot time.After the reading of the buffers from the virtqueue I think the process is slightly different, because virtio-net will interface with the network stack, while virtio-vsock will interface with the vsock-core (socket). So the virtio-vsock implements the following: - control flow mechanism to avoid to loose packets, informing the peer about the amount of memory available in the receive queue using some fields in the virtio_vsock_hdr - de-multiplexing parsing the virtio_vsock_hdr and choosing the right socket depending on the port - socket state handling We can use the virtio-net as transport, but we should add a lot of code to skip "net device" stuff when it is used by the virtio-vsock. This could break something in virtio-net, for this reason, I thought to reuse only the send/recv functions starting from the idea to split the virtio-net driver in two parts: a. one with all stuff related to the network stack b. one with the stuff needed to communicate with the host And use skbuff to communicate between parts. In this way, virtio-vsock can use only the b part. Maybe we can do this split in a better way, but I'm not sure it is simple. Thanks, Stefano
Possibly Parallel Threads
- [RFC] virtio-net: share receive_*() and add_recvbuf_*() with virtio-vsock
- [RFC] virtio-net: share receive_*() and add_recvbuf_*() with virtio-vsock
- [RFC] virtio-net: share receive_*() and add_recvbuf_*() with virtio-vsock
- [RFC] virtio-net: share receive_*() and add_recvbuf_*() with virtio-vsock
- [RFC] virtio-net: share receive_*() and add_recvbuf_*() with virtio-vsock