From 697f3214fd16adcd524456003619f7f44ddd031b Mon Sep 17 00:00:00 2001 From: Marc-André Lureau Date: Fri, 24 Oct 2014 10:51:05 +0200 Subject: chardev: remove write polling In an effort to reduce the wakeups per second, get rid of the "write_to_dev" timer when the implementation supports SPICE_CHAR_DEVICE_NOTIFY_WRITABLE. When this flag is set, the frontend instance is responsible for calling spice_char_device_wakeup() when the device is ready to perform IO. Related to: https://bugzilla.redhat.com/show_bug.cgi?id=912763 --- server/char_device.c | 36 +++++++++++++++++++++++++++--------- server/spice.h | 9 +++++++-- 2 files changed, 34 insertions(+), 11 deletions(-) (limited to 'server') diff --git a/server/char_device.c b/server/char_device.c index 6d2339e8..c6dc45b9 100644 --- a/server/char_device.c +++ b/server/char_device.c @@ -438,7 +438,10 @@ static int spice_char_device_write_to_device(SpiceCharDeviceState *dev) } spice_char_device_state_ref(dev); - core->timer_cancel(dev->write_to_dev_timer); + + if (dev->write_to_dev_timer) { + core->timer_cancel(dev->write_to_dev_timer); + } sif = SPICE_CONTAINEROF(dev->sin->base.sif, SpiceCharDeviceInterface, base); while (dev->running) { @@ -473,8 +476,10 @@ static int spice_char_device_write_to_device(SpiceCharDeviceState *dev) /* retry writing as long as the write queue is not empty */ if (dev->running) { if (dev->cur_write_buf) { - core->timer_start(dev->write_to_dev_timer, - CHAR_DEVICE_WRITE_TO_TIMEOUT); + if (dev->write_to_dev_timer) { + core->timer_start(dev->write_to_dev_timer, + CHAR_DEVICE_WRITE_TO_TIMEOUT); + } } else { spice_assert(ring_is_empty(&dev->write_queue)); } @@ -488,7 +493,9 @@ static void spice_char_dev_write_retry(void *opaque) { SpiceCharDeviceState *dev = opaque; - core->timer_cancel(dev->write_to_dev_timer); + if (dev->write_to_dev_timer) { + core->timer_cancel(dev->write_to_dev_timer); + } spice_char_device_write_to_device(dev); } @@ -635,6 +642,7 @@ SpiceCharDeviceState *spice_char_device_state_create(SpiceCharDeviceInstance *si void *opaque) { SpiceCharDeviceState *char_dev; + SpiceCharDeviceInterface *sif; spice_assert(sin); spice_assert(cbs->read_one_msg_from_device && cbs->ref_msg_to_client && @@ -652,10 +660,15 @@ SpiceCharDeviceState *spice_char_device_state_create(SpiceCharDeviceInstance *si ring_init(&char_dev->write_bufs_pool); ring_init(&char_dev->clients); - char_dev->write_to_dev_timer = core->timer_add(spice_char_dev_write_retry, char_dev); - if (!char_dev->write_to_dev_timer) { - spice_error("failed creating char dev write timer"); + sif = SPICE_CONTAINEROF(char_dev->sin->base.sif, SpiceCharDeviceInterface, base); + if (sif->base.minor_version <= 2 || + !(sif->flags & SPICE_CHAR_DEVICE_NOTIFY_WRITABLE)) { + char_dev->write_to_dev_timer = core->timer_add(spice_char_dev_write_retry, char_dev); + if (!char_dev->write_to_dev_timer) { + spice_error("failed creating char dev write timer"); + } } + char_dev->refs = 1; sin->st = char_dev; spice_debug("sin %p dev_state %p", sin, char_dev); @@ -697,7 +710,9 @@ static void spice_char_device_state_unref(SpiceCharDeviceState *char_dev) void spice_char_device_state_destroy(SpiceCharDeviceState *char_dev) { reds_on_char_device_state_destroy(char_dev); - core->timer_remove(char_dev->write_to_dev_timer); + if (char_dev->write_to_dev_timer) { + core->timer_remove(char_dev->write_to_dev_timer); + } write_buffers_queue_free(&char_dev->write_queue); write_buffers_queue_free(&char_dev->write_bufs_pool); if (char_dev->cur_write_buf) { @@ -805,7 +820,9 @@ void spice_char_device_stop(SpiceCharDeviceState *dev) spice_debug("dev_state %p", dev); dev->running = FALSE; dev->active = FALSE; - core->timer_cancel(dev->write_to_dev_timer); + if (dev->write_to_dev_timer) { + core->timer_cancel(dev->write_to_dev_timer); + } } void spice_char_device_reset(SpiceCharDeviceState *dev) @@ -842,6 +859,7 @@ void spice_char_device_reset(SpiceCharDeviceState *dev) void spice_char_device_wakeup(SpiceCharDeviceState *dev) { + spice_char_device_write_to_device(dev); spice_char_device_read_from_device(dev); } diff --git a/server/spice.h b/server/spice.h index 58700d14..bd5bba89 100644 --- a/server/spice.h +++ b/server/spice.h @@ -24,7 +24,7 @@ #include #include -#define SPICE_SERVER_VERSION 0x000c05 /* release 0.12.5 */ +#define SPICE_SERVER_VERSION 0x000c06 /* release 0.12.6 */ #ifdef SPICE_SERVER_INTERNAL #undef SPICE_GNUC_DEPRECATED @@ -402,11 +402,15 @@ void spice_server_set_record_rate(SpiceRecordInstance *sin, uint32_t frequen #define SPICE_INTERFACE_CHAR_DEVICE "char_device" #define SPICE_INTERFACE_CHAR_DEVICE_MAJOR 1 -#define SPICE_INTERFACE_CHAR_DEVICE_MINOR 2 +#define SPICE_INTERFACE_CHAR_DEVICE_MINOR 3 typedef struct SpiceCharDeviceInterface SpiceCharDeviceInterface; typedef struct SpiceCharDeviceInstance SpiceCharDeviceInstance; typedef struct SpiceCharDeviceState SpiceCharDeviceState; +typedef enum { + SPICE_CHAR_DEVICE_NOTIFY_WRITABLE = 1 << 0, +} spice_char_device_flags; + struct SpiceCharDeviceInterface { SpiceBaseInterface base; @@ -414,6 +418,7 @@ struct SpiceCharDeviceInterface { int (*write)(SpiceCharDeviceInstance *sin, const uint8_t *buf, int len); int (*read)(SpiceCharDeviceInstance *sin, uint8_t *buf, int len); void (*event)(SpiceCharDeviceInstance *sin, uint8_t event); + spice_char_device_flags flags; }; struct SpiceCharDeviceInstance { -- cgit