[Spice-devel] [PATCH spice-server 2/3] stream: implements flush using TCP_CORK

Frediano Ziglio fziglio at redhat.com
Fri Apr 13 10:38:07 UTC 2018


> 
> On Tue, Jan 16, 2018 at 02:18:14PM +0000, Frediano Ziglio wrote:
> > Cork is a system interface implemented by Linux and some *BSD systems to
> > tell the system that other data are expected to be written to a socket.
> > This allows the system to reduce network fragmentation waiting a network
> 
> 'waiting for network packets to be complete' I think.
> 
> > packet to be complete.
> > 
> > Using some replay capture and some instrumentation resulted in a
> > bandwith reduction of 11% and a packet reduction of 56%.
> 
> I would add a link to
> https://lists.freedesktop.org/archives/spice-devel/2017-February/035577.html
> and maybe even copy the data you put in there.
> 

Added part of it, the TLS part was not strictly related (and surely the
small TLS optimization tests does not belong here).

Specifically I added:

    The tests was done using replay utility so results could be a bit different
    from real cases as:
    - replay goes as fast as it can, for instance packets could
      be merged by the kernel decreasing packet numbers and a bit
      byte spent (this actually make the following improves worse);
    - there are fewer channels (no much cursor, sound, etc).
    The following tests shows count packet and total bytes from server to
    client using a real network. I used a direct cable connection using 1gb
    connection and 2 laptops.

    cork: 537 1582240
    cork: 681 1823754
    cork: 524 1583287
    cork: 538 1582350
    no cork: 1329 1834630
    no cork: 1290 1829094
    no cork: 1289 1830164
    no cork: 1317 1833589
    no cork: 1320 1835705

> > 
> > Signed-off-by: Frediano Ziglio <fziglio at redhat.com>
> > ---
> >  server/red-stream.c | 34 +++++++++++++++++++++++++++++++++-
> >  1 file changed, 33 insertions(+), 1 deletion(-)
> > 
> > diff --git a/server/red-stream.c b/server/red-stream.c
> > index 4812d8e4..4833077c 100644
> > --- a/server/red-stream.c
> > +++ b/server/red-stream.c
> > @@ -24,6 +24,7 @@
> >  #include <unistd.h>
> >  #include <sys/socket.h>
> >  #include <fcntl.h>
> > +#include <netinet/tcp.h>
> >  
> >  #include <glib.h>
> >  
> > @@ -83,6 +84,8 @@ struct RedStreamPrivate {
> >       * deallocated when main_dispatcher handles the
> >       SPICE_CHANNEL_EVENT_DISCONNECTED
> >       * event, either from same thread or by call back from main thread. */
> >      SpiceChannelEventInfo* info;
> > +    bool use_cork;
> > +    bool corked;
> >  
> >      ssize_t (*read)(RedStream *s, void *buf, size_t nbyte);
> >      ssize_t (*write)(RedStream *s, const void *buf, size_t nbyte);
> > @@ -92,6 +95,15 @@ struct RedStreamPrivate {
> >      SpiceCoreInterfaceInternal *core;
> >  };
> >  
> > +/**
> > + * Set TCP_CORK on socket
> > + */
> > +/* NOTE: enabled must be int */
> 
> Maybe verify(sizeof(socket) == sizeof(int))?
> 

added a SPICE_VERIFY inside the function, specifically

    SPICE_VERIFY(sizeof(enabled) == sizeof(int));

> > +static inline int socket_set_cork(int socket, int enabled)
> 
> I'd drop the 'inline'
> 
> > +{
> > +    return setsockopt(socket, IPPROTO_TCP, TCP_CORK, &enabled,
> > sizeof(enabled));
> 
> I suspect we'll need to add a configure check for this? It seems to be
> called TCP_NOPUSH in OpenBSD? https://man.openbsd.org/tcp
> 

I'll add a

#ifndef TCP_CORK
#define TCP_CORK TCP_NOPUSH
#endif

at the beginning of the file

> > +}
> > +
> >  static ssize_t stream_write_cb(RedStream *s, const void *buf, size_t size)
> >  {
> >      return write(s->socket, buf, size);
> > @@ -205,11 +217,31 @@ bool red_stream_write_all(RedStream *stream, const
> > void *in_buf, size_t n)
> >  
> >  bool red_stream_set_auto_flush(RedStream *s, bool enable)
> >  {
> > -    return enable;
> > +    if (s->priv->use_cork == !enable) {
> 
> Might be slightly more readable if 'enable' is renamed to 'auto_flush'
> 

Agreed, done

> 
> Acked-by: Christophe Fergeau <cfergeau at redhat.com>
> 

Frediano


More information about the Spice-devel mailing list