MAJOR: cache: Send cached objects using zero-copy forwarding

The zero-copy forwarding is reintroduced implementing the .fastfwd callback
function. Otherwise, there is nothing special to say.
This commit is contained in:
Christopher Faulet 2024-01-23 08:45:24 +01:00
parent 863417292b
commit c061ba30f7
1 changed files with 37 additions and 35 deletions

View File

@ -1569,6 +1569,7 @@ static unsigned int htx_cache_dump_data_blk(struct appctx *appctx, struct htx *h
ctx->sent += total;
ctx->data_sent += data_len;
ctx->rem_data = rem_data + blksz;
appctx->to_forward -= data_len;
return total;
}
@ -1625,32 +1626,6 @@ static size_t htx_cache_dump_msg(struct appctx *appctx, struct htx *htx, unsigne
return total;
}
static void ff_cache_skip_tlr_blk(struct appctx *appctx, uint32_t info, struct shared_block *shblk, unsigned int offset)
{
struct cache_appctx *ctx = appctx->svcctx;
struct cache_flt_conf *cconf = appctx->rule->arg.act.p[0];
struct shared_context *shctx = shctx_ptr(cconf->c.cache);
unsigned int max, total;
uint32_t blksz;
blksz = (info & 0xff) + ((info >> 8) & 0xfffff);
total = 4;
while (blksz) {
max = MIN(blksz, shctx->block_size - offset);
offset += max;
blksz -= max;
total += max;
if (blksz || offset == shctx->block_size) {
shblk = LIST_NEXT(&shblk->list, typeof(shblk), list);
offset = 0;
}
}
ctx->offset = offset;
ctx->next = shblk;
ctx->sent += total;
}
static unsigned int ff_cache_dump_data_blk(struct appctx *appctx, struct buffer *buf, unsigned int len,
uint32_t info, struct shared_block *shblk, unsigned int offset)
{
@ -1696,10 +1671,11 @@ static unsigned int ff_cache_dump_data_blk(struct appctx *appctx, struct buffer
ctx->sent += total;
ctx->data_sent += data_len;
ctx->rem_data = rem_data + blksz;
appctx->to_forward -= data_len;
return total;
}
static __maybe_unused size_t ff_cache_dump_msg(struct appctx *appctx, struct buffer *buf, unsigned int len)
static size_t ff_cache_dump_msg(struct appctx *appctx, struct buffer *buf, unsigned int len)
{
struct cache_appctx *ctx = appctx->svcctx;
struct cache_entry *cache_ptr = ctx->entry;
@ -1738,15 +1714,8 @@ static __maybe_unused size_t ff_cache_dump_msg(struct appctx *appctx, struct buf
add_data_blk:
ret = ff_cache_dump_data_blk(appctx, buf, len, info, shblk, offset);
}
else if (type == HTX_BLK_TLR) {
ff_cache_skip_tlr_blk(appctx, info, shblk, offset);
BUG_ON(ctx->sent != first->len - sizeof(*cache_ptr));
else
ret = 0;
}
else {
sc_ep_clr(appctx_sc(appctx), SE_FL_MAY_FASTFWD);
ret = 0;
}
if (!ret)
break;
@ -1778,6 +1747,29 @@ static int htx_cache_add_age_hdr(struct appctx *appctx, struct htx *htx)
return 1;
}
static size_t http_cache_fastfwd(struct appctx *appctx, struct buffer *buf, size_t count, unsigned int flags)
{
struct cache_appctx *ctx = appctx->svcctx;
struct cache_entry *cache_ptr = ctx->entry;
struct shared_block *first = block_ptr(cache_ptr);
size_t ret;
BUG_ON(!appctx->to_forward || count > appctx->to_forward);
ret = ff_cache_dump_msg(appctx, buf, count);
if (!appctx->to_forward) {
se_fl_clr(appctx->sedesc, SE_FL_MAY_FASTFWD);
if (ctx->sent == first->len - sizeof(*cache_ptr)) {
applet_set_eoi(appctx);
applet_set_eos(appctx);
BUG_ON(ctx->data_sent != cache_ptr->body_size);
appctx->st0 = HTX_CACHE_END;
}
}
return ret;
}
static void http_cache_io_handler(struct appctx *appctx)
{
struct cache_appctx *ctx = appctx->svcctx;
@ -1791,6 +1783,8 @@ static void http_cache_io_handler(struct appctx *appctx)
if (applet_fl_test(appctx, APPCTX_FL_OUTBLK_ALLOC|APPCTX_FL_OUTBLK_FULL))
goto exit;
if (se_fl_test(appctx->sedesc, SE_FL_MAY_FASTFWD))
goto exit;
if (!appctx_get_buf(appctx, &appctx->outbuf)) {
appctx->flags |= APPCTX_FL_OUTBLK_ALLOC;
@ -1837,6 +1831,10 @@ static void http_cache_io_handler(struct appctx *appctx)
if (find_http_meth(istptr(meth), istlen(meth)) == HTTP_METH_HEAD || ctx->send_notmodified)
appctx->st0 = HTX_CACHE_EOM;
else {
if (!(global.tune.no_zero_copy_fwd & (NO_ZERO_COPY_FWD|NO_ZERO_COPY_FWD_CACHE)))
se_fl_set(appctx->sedesc, SE_FL_MAY_FASTFWD);
appctx->to_forward = cache_ptr->body_size;
len = first->len - sizeof(*cache_ptr) - ctx->sent;
appctx->st0 = HTX_CACHE_DATA;
}
@ -1850,6 +1848,7 @@ static void http_cache_io_handler(struct appctx *appctx)
goto out;
}
}
BUG_ON(appctx->to_forward);
BUG_ON(ctx->data_sent != cache_ptr->body_size);
appctx->st0 = HTX_CACHE_EOM;
}
@ -1858,6 +1857,7 @@ static void http_cache_io_handler(struct appctx *appctx)
/* no more data are expected. */
res_htx->flags |= HTX_FL_EOM;
applet_set_eoi(appctx);
se_fl_clr(appctx->sedesc, SE_FL_MAY_FASTFWD);
appctx->st0 = HTX_CACHE_END;
}
@ -1874,6 +1874,7 @@ static void http_cache_io_handler(struct appctx *appctx)
/* eat the whole request */
b_reset(&appctx->inbuf);
applet_fl_clr(appctx, APPCTX_FL_INBLK_FULL);
appctx->sedesc->iobuf.flags &= ~IOBUF_FL_FF_BLOCKED;
return;
error:
@ -3160,6 +3161,7 @@ struct applet http_cache_applet = {
.fct = http_cache_io_handler,
.rcv_buf = appctx_rcv_buf,
.snd_buf = appctx_snd_buf,
.fastfwd = http_cache_fastfwd,
.release = http_cache_applet_release,
};