From 0350b90e318f2e5a29d87159308d675a40cc8a1a Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Tue, 28 May 2019 10:58:50 +0200 Subject: [PATCH] MEDIUM: htx: make htx_add_data() never defragment the buffer Now instead of trying to fit 100% of the input data into the output buffer at the risk of defragmenting it, we put what fits into it only and return the amount of bytes transferred. In a test, compared to the previous commit, it increases the cached data rate from 44 Gbps to 55 Gbps and saves a lot in case of large buffers : with a 1 MB buffer, uncached transfers jumped from 700 Mbps to 30 Gbps. --- src/htx.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 60 insertions(+), 4 deletions(-) diff --git a/src/htx.c b/src/htx.c index 32e23d115f..9281ebac61 100644 --- a/src/htx.c +++ b/src/htx.c @@ -763,13 +763,69 @@ struct htx_blk *htx_add_endof(struct htx *htx, enum htx_blk_type type) */ size_t htx_add_data(struct htx *htx, const struct ist data) { - struct htx_blk *blk; + struct htx_blk *blk, *tailblk, *headblk, *frtblk; + struct ist v; + int32_t room; + int32_t len = data.len; + + if (!htx->used) + goto add_new_block; + + /* Not enough space to store data */ + if (len > htx_free_data_space(htx)) + len = htx_free_data_space(htx); - blk = htx_add_data_atonce(htx, data); - if (blk) - return data.len; + if (!len) + return 0; + + /* get the tail and head block */ + tailblk = htx_get_tail_blk(htx); + headblk = htx_get_head_blk(htx); + if (tailblk == NULL || headblk == NULL) + goto add_new_block; + + /* Don't try to append data if the last inserted block is not of the + * same type */ + if (htx_get_blk_type(tailblk) != HTX_BLK_DATA) + goto add_new_block; + + /* + * Same type and enough space: append data + */ + frtblk = htx_get_blk(htx, htx->front); + if (tailblk->addr >= headblk->addr) { + if (htx->tail != htx->front) + goto add_new_block; + room = sizeof(htx->blocks[0]) * htx_pos_to_idx(htx, htx->tail) - (frtblk->addr + htx_get_blksz(frtblk)); + } else + room = headblk->addr - (tailblk->addr + htx_get_blksz(tailblk)); + + if (room < len) + len = room; + + append_data: + /* get the value of the tail block */ + /* FIXME: check v.len + len < 256MB */ + v = htx_get_blk_value(htx, tailblk); + + /* Append data and update the block itself */ + memcpy(v.ptr + v.len, data.ptr, len); + htx_set_blk_value_len(tailblk, v.len + len); + + /* Update HTTP message */ + htx->data += len; + return len; + + add_new_block: + /* FIXME: check tlr.len (< 256MB) */ + blk = htx_add_blk(htx, HTX_BLK_DATA, len); + if (!blk) return 0; + + blk->info += len; + memcpy(htx_get_blk_ptr(htx, blk), data.ptr, len); + return len; } /* Adds an HTX block of type TLR in . It returns the new block on -- 2.39.5