Hi On Tue, May 11, 2021 at 1:04 PM Gerd Hoffmann wrote: > > > +/* ------------------------------------------------------------------ > */ > > > +/* send messages > */ > > > + > > > +static void vdagent_send_buf(VDAgentChardev *vd, void *ptr, uint32_t > > > msgsize) > > > +{ > > > + uint8_t *msgbuf = ptr; > > > + uint32_t len, pos = 0; > > > + > > > + while (pos < msgsize) { > > > + len = qemu_chr_be_can_write(CHARDEV(vd)); > > > + if (len > msgsize - pos) { > > > + len = msgsize - pos; > > > + } > > > + qemu_chr_be_write(CHARDEV(vd), msgbuf + pos, len); > > > + pos += len; > > > + } > > > > > > > This looks like it could easily busy loop. Have you thought about fixing > > this? > > Incremental fix [ to be squashed ] > > thanks, a few comments below take care, > Gerd > > diff --git a/ui/vdagent.c b/ui/vdagent.c > index 64213aa25a06..efa98725fb22 100644 > --- a/ui/vdagent.c > +++ b/ui/vdagent.c > @@ -3,7 +3,9 @@ > #include "include/qemu-common.h" > #include "chardev/char.h" > #include "hw/qdev-core.h" > +#include "qemu/buffer.h" > #include "qemu/option.h" > +#include "qemu/units.h" > #include "ui/clipboard.h" > #include "ui/console.h" > #include "ui/input.h" > @@ -16,6 +18,7 @@ > > #define VDAGENT_MOUSE_DEFAULT true > #define VDAGENT_CLIPBOARD_DEFAULT false > +#define VDAGENT_BUFFER_LIMIT (1 * MiB) > > struct VDAgentChardev { > Chardev parent; > @@ -32,6 +35,7 @@ struct VDAgentChardev { > uint32_t msgsize; > uint8_t *xbuf; > uint32_t xoff, xsize; > + Buffer outbuf; > > /* mouse */ > DeviceState mouse_dev; > @@ -124,18 +128,20 @@ static const char *type_name[] = { > /* ------------------------------------------------------------------ */ > /* send messages */ > > -static void vdagent_send_buf(VDAgentChardev *vd, void *ptr, uint32_t > msgsize) > +static void vdagent_send_buf(VDAgentChardev *vd) > { > - uint8_t *msgbuf = ptr; > - uint32_t len, pos = 0; > + uint32_t len; > > - while (pos < msgsize) { > + while (!buffer_empty(&vd->outbuf)) { > len = qemu_chr_be_can_write(CHARDEV(vd)); > - if (len > msgsize - pos) { > - len = msgsize - pos; > + if (len == 0) { > + return; > } > - qemu_chr_be_write(CHARDEV(vd), msgbuf + pos, len); > - pos += len; > + if (len > vd->outbuf.offset) { > + len = vd->outbuf.offset; > + } > + qemu_chr_be_write(CHARDEV(vd), vd->outbuf.buffer, len); > + buffer_advance(&vd->outbuf, len); > } > } > > @@ -150,16 +156,22 @@ static void vdagent_send_msg(VDAgentChardev *vd, > VDAgentMessage *msg) > > msg->protocol = VD_AGENT_PROTOCOL; > > + if (vd->outbuf.offset + msgsize > VDAGENT_BUFFER_LIMIT) { > + return; > + } > Silently dropping messages, there might be some bad consequences. At least I think we should error_report(). Eventually, the caller should be informed too. > + > while (msgoff < msgsize) { > chunk.port = VDP_CLIENT_PORT; > chunk.size = msgsize - msgoff; > if (chunk.size > 1024) { > chunk.size = 1024; > } > - vdagent_send_buf(vd, &chunk, sizeof(chunk)); > - vdagent_send_buf(vd, msgbuf + msgoff, chunk.size); > + buffer_reserve(&vd->outbuf, sizeof(chunk) + chunk.size); > + buffer_append(&vd->outbuf, &chunk, sizeof(chunk)); > + buffer_append(&vd->outbuf, msgbuf + msgoff, chunk.size); > msgoff += chunk.size; > } > + vdagent_send_buf(vd); > } > > static void vdagent_send_caps(VDAgentChardev *vd) > @@ -550,6 +562,7 @@ static void vdagent_chr_open(Chardev *chr, > > &vdagent_mouse_handler); > } > > + buffer_init(&vd->outbuf, "vdagent-outbuf"); > Needs a buffer_free(). Move it to object init/finalize ? *be_opened = true; > } > > @@ -702,6 +715,13 @@ static int vdagent_chr_write(Chardev *chr, const > uint8_t *buf, int len) > return ret; > } > > +static void vdagent_chr_accept_input(Chardev *chr) > +{ > + VDAgentChardev *vd = QEMU_VDAGENT_CHARDEV(chr); > + > + vdagent_send_buf(vd); > +} > + > static void vdagent_chr_set_fe_open(struct Chardev *chr, int fe_open) > { > VDAgentChardev *vd = QEMU_VDAGENT_CHARDEV(chr); > @@ -748,6 +768,7 @@ static void vdagent_chr_class_init(ObjectClass *oc, > void *data) > cc->open = vdagent_chr_open; > cc->chr_write = vdagent_chr_write; > cc->chr_set_fe_open = vdagent_chr_set_fe_open; > + cc->chr_accept_input = vdagent_chr_accept_input; > } > > static const TypeInfo vdagent_chr_type_info = { > -- > 2.31.1 > > -- Marc-André Lureau