On Tue, Mar 15, 2022 at 11:07 PM Akihiko Odaki
wrote:
> On 2022/03/16 4:59, Vladislav Yaroshchuk wrote:
> > Interaction with vmnet.framework in different modes
> > differs only on configuration stage, so we can create
> > common `send`, `receive`, etc. procedures and reuse them.
> >
> > Signed-off-by: Phillip Tennen
> > Signed-off-by: Vladislav Yaroshchuk
> > ---
> > net/vmnet-common.m | 368 +
> > net/vmnet-shared.c | 90 ++-
> > net/vmnet_int.h| 40 -
> > 3 files changed, 493 insertions(+), 5 deletions(-)
> >
> > diff --git a/net/vmnet-common.m b/net/vmnet-common.m
> > index 06326efb1c..b9dac7b241 100644
> > --- a/net/vmnet-common.m
> > +++ b/net/vmnet-common.m
> > @@ -10,6 +10,8 @@
> >*/
> >
> > #include "qemu/osdep.h"
> > +#include "qemu/main-loop.h"
> > +#include "qemu/log.h"
> > #include "qapi/qapi-types-net.h"
> > #include "vmnet_int.h"
> > #include "clients.h"
> > @@ -17,4 +19,370 @@
> > #include "qapi/error.h"
> >
> > #include
> > +#include
> >
> > +
>
[...]
> > +/**
> > + * Bottom half callback that transfers packets from vmnet interface
> > + * to QEMU.
> > + *
> > + * The process of transferring packets is three-staged:
> > + * 1. Handle vmnet event;
> > + * 2. Read packets from vmnet interface into temporary buffer;
> > + * 3. Write packets from temporary buffer to QEMU.
> > + *
> > + * QEMU may suspend this process on the last stage, returning 0 from
> > + * qemu_send_packet_async function. If this happens, we should
> > + * respectfully wait until it is ready to consume more packets,
> > + * write left ones in temporary buffer and only after this
> > + * continue reading more packets from vmnet interface.
> > + *
> > + * Packets to be transferred are stored into packets_buf,
> > + * in the window (packets_send_current_pos..packets_send_end_pos]
> > + * excluding current_pos, including end_pos.
>
> I wonder why you changed the window from [packets_send_current_pos,
> packets_send_end_pos). It is an unconventional way to represent such
> kind of window, requires signed integers and calculating
> packets_send_current_pos + 1 before operating with the first item of the
> window.
>
>
Did this mistakenly while removing send_enabled :facepalm:
Sorry for this.
Submitting v19 with this fixed.
Best Regards,
Vladislav Yaroshchuk
> Regards,
> Akihiko Odaki
>
> + *
> > + * Thus, if QEMU is not ready, buffer is not read and
> > + * packets_send_current_pos < packets_send_end_pos.
> > + */
> > +static void vmnet_send_bh(void *opaque)
> > +{
> > +NetClientState *nc = (NetClientState *) opaque;
> > +VmnetState *s = DO_UPCAST(VmnetState, nc, nc);
> > +
> > +/*
> > + * Do nothing if QEMU is not ready - wait
> > + * for completion callback invocation
> > + */
> > +if (s->packets_send_current_pos < s->packets_send_end_pos) {
> > +return;
> > +}
> > +
> > +/* Read packets from vmnet interface */
> > +if (vmnet_read_packets(s) > 0) {
> > +/* Send them to QEMU */
> > +vmnet_write_packets_to_qemu(s);
> > +}
> > +}
> > +
> > +
> > +/**
> > + * Completion callback to be invoked by QEMU when it becomes
> > + * ready to consume more packets.
> > + */
> > +static void vmnet_send_completed(NetClientState *nc, ssize_t len)
> > +{
> > +VmnetState *s = DO_UPCAST(VmnetState, nc, nc);
> > +
> > +/* Callback is invoked eq queued packet is sent */
> > +++s->packets_send_current_pos;
> > +
> > +/* Complete sending packets left in VmnetState buffers */
> > +vmnet_write_packets_to_qemu(s);
> > +
> > +/* And read new ones from vmnet if VmnetState buffer is ready */
> > +if (s->packets_send_current_pos < s->packets_send_end_pos) {
> > +qemu_bh_schedule(s->send_bh);
> > +}
> > +}
> > +
> > +
> > +static void vmnet_bufs_init(VmnetState *s)
> > +{
> > +struct vmpktdesc *packets = s->packets_buf;
> > +struct iovec *iov = s->iov_buf;
> > +int i;
> > +
> > +for (i = 0; i < VMNET_PACKETS_LIMIT; ++i) {
> > +iov[i].iov_len = s->max_packet_size;
> > +iov[i].iov_base = g_malloc0(iov[i].iov_len);
> > +packets[i].vm_pkt_iov = iov + i;
> > +}
> > +}
> > +
> > +
> > +int vmnet_if_create(NetClientState *nc,
> > +xpc_object_t if_desc,
> > +Error **errp)
> > +{
> > +VmnetState *s = DO_UPCAST(VmnetState, nc, nc);
> > +dispatch_semaphore_t if_created_sem = dispatch_semaphore_create(0);
> > +__block vmnet_return_t if_status;
> > +
> > +s->if_queue = dispatch_queue_create(
> > +"org.qemu.vmnet.if_queue",
> > +DISPATCH_QUEUE_SERIAL
> > +);
> > +
> > +xpc_dictionary_set_bool(
> > +if_desc,
> > +vmnet_allocate_mac_address_key,
> > +false
> > +);
> > +
> > +#ifdef DEBUG
> > +qemu_log("vmnet.start.interface_desc:\n");
> > +xpc_dictionary_apply(if_desc,
> > + ^bool(const char