summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVictor Toso <victortoso@redhat.com>2015-08-19 11:26:34 +0200
committerVictor Toso <victortoso@redhat.com>2015-11-13 08:15:38 +0100
commit2832fdf25a9a2097efc58545eb389342393562fc (patch)
tree75e2c1835eae6a591939f237101692ba22735417
parentd7bee1bc56e2d3ea6af399ba8479cb4b849d4b15 (diff)
downloadspice-2832fdf25a9a2097efc58545eb389342393562fc.zip
spice-2832fdf25a9a2097efc58545eb389342393562fc.tar.gz
spice-2832fdf25a9a2097efc58545eb389342393562fc.tar.xz
char-device: Define a memory pool limit
Otherwise the amount of unused memory could grow while transfering big chunks of data. This change only means that once the memory was used it will not be stored again after the limit was reached. Related: https://bugs.freedesktop.org/show_bug.cgi?id=91350
-rw-r--r--server/char_device.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/server/char_device.c b/server/char_device.c
index 4381981..3aa88ef 100644
--- a/server/char_device.c
+++ b/server/char_device.c
@@ -27,6 +27,7 @@
#define CHAR_DEVICE_WRITE_TO_TIMEOUT 100
#define SPICE_CHAR_DEVICE_WAIT_TOKENS_TIMEOUT 30000
+#define MAX_POOL_SIZE (10 * 64 * 1024)
typedef struct SpiceCharDeviceClientState SpiceCharDeviceClientState;
struct SpiceCharDeviceClientState {
@@ -52,6 +53,7 @@ struct SpiceCharDeviceState {
Ring write_queue;
Ring write_bufs_pool;
+ uint64_t cur_pool_size;
SpiceCharDeviceWriteBuffer *cur_write_buf;
uint8_t *cur_write_buf_pos;
SpiceTimer *write_to_dev_timer;
@@ -114,10 +116,12 @@ static void write_buffers_queue_free(Ring *write_queue)
static void spice_char_device_write_buffer_pool_add(SpiceCharDeviceState *dev,
SpiceCharDeviceWriteBuffer *buf)
{
- if (buf->refs == 1) {
+ if (buf->refs == 1 &&
+ dev->cur_pool_size < MAX_POOL_SIZE) {
buf->buf_used = 0;
buf->origin = WRITE_BUFFER_ORIGIN_NONE;
buf->client = NULL;
+ dev->cur_pool_size += buf->buf_size;
ring_add(&dev->write_bufs_pool, &buf->link);
return;
}
@@ -529,6 +533,7 @@ static SpiceCharDeviceWriteBuffer *__spice_char_device_write_buffer_get(
if ((item = ring_get_tail(&dev->write_bufs_pool))) {
ret = SPICE_CONTAINEROF(item, SpiceCharDeviceWriteBuffer, link);
ring_remove(item);
+ dev->cur_pool_size -= ret->buf_size;
} else {
ret = spice_new0(SpiceCharDeviceWriteBuffer, 1);
}
@@ -569,6 +574,7 @@ static SpiceCharDeviceWriteBuffer *__spice_char_device_write_buffer_get(
ret->refs = 1;
return ret;
error:
+ dev->cur_pool_size += ret->buf_size;
ring_add(&dev->write_bufs_pool, &ret->link);
return NULL;
}
@@ -739,6 +745,7 @@ void spice_char_device_state_destroy(SpiceCharDeviceState *char_dev)
}
write_buffers_queue_free(&char_dev->write_queue);
write_buffers_queue_free(&char_dev->write_bufs_pool);
+ char_dev->cur_pool_size = 0;
spice_char_device_write_buffer_free(char_dev->cur_write_buf);
while (!ring_is_empty(&char_dev->clients)) {