From 569ea169bacad9e9cafaab888f00e3312919d576 Mon Sep 17 00:00:00 2001 From: Gert Wollny Date: Mon, 28 Dec 2020 14:55:43 +0100 Subject: [PATCH] vrend: reduce work done in command decoding loop v2: drop decode state and use local variables to handle keeping track of the decode buffer state (Chia-I Wo) Signed-off-by: Gert Wollny Reviewed-by: Chia-I Wu --- src/vrend_decode.c | 51 ++++++++++++++++++++-------------------------- 1 file changed, 22 insertions(+), 29 deletions(-) diff --git a/src/vrend_decode.c b/src/vrend_decode.c index 2d9f7d0..4783860 100644 --- a/src/vrend_decode.c +++ b/src/vrend_decode.c @@ -44,16 +44,8 @@ /* decode side */ #define DECODE_MAX_TOKENS 8000 -struct vrend_decoder_state { - const uint32_t *buf; - uint32_t buf_total; - uint32_t buf_offset; -}; - struct vrend_decode_ctx { struct virgl_context base; - - struct vrend_decoder_state ids, *ds; struct vrend_context *grctx; }; @@ -1467,8 +1459,6 @@ struct virgl_context *vrend_renderer_context_create(uint32_t handle, return NULL; } - dctx->ds = &dctx->ids; - return &dctx->base; } @@ -1603,42 +1593,45 @@ static int vrend_decode_ctx_submit_cmd(struct virgl_context *ctx, if (bret == false) return EINVAL; - gdctx->ds->buf = buffer; - gdctx->ds->buf_total = size / sizeof(uint32_t); - gdctx->ds->buf_offset = 0; + const uint32_t *typed_buf = (const uint32_t *)buffer; + const uint32_t buf_total = size / sizeof(uint32_t); + uint32_t buf_offset = 0; - while (gdctx->ds->buf_offset < gdctx->ds->buf_total) { - uint32_t header = gdctx->ds->buf[gdctx->ds->buf_offset]; - uint32_t len = header >> 16; - uint32_t cmd = header & 0xff; + while (buf_offset < buf_total) { +#ifndef NDEBUG + const uint32_t cur_offset = buf_offset; +#endif + + const uint32_t *buf = &typed_buf[buf_offset]; + uint32_t len = *buf >> 16; + uint32_t cmd = *buf & 0xff; if (cmd >= VIRGL_MAX_COMMANDS) return EINVAL; + buf_offset += len + 1; + ret = 0; /* check if the guest is doing something bad */ - if (gdctx->ds->buf_offset + len + 1 > gdctx->ds->buf_total) { + if (buf_offset > buf_total) { vrend_report_buffer_error(gdctx->grctx, 0); break; } VREND_DEBUG(dbg_cmd, gdctx->grctx,"%-4d %-20s len:%d\n", - gdctx->ds->buf_offset, vrend_get_comand_name(header & 0xff), len); + cur_offset, vrend_get_comand_name(cmd), len); - TRACE_SCOPE("%s", vrend_get_comand_name(header & 0xff)); + TRACE_SCOPE("%s", vrend_get_comand_name(cmd)); - ret = decode_table[cmd](gdctx, &gdctx->ds->buf[gdctx->ds->buf_offset], len); - if (ret == EINVAL) { - vrend_report_buffer_error(gdctx->grctx, header); - goto out; + ret = decode_table[cmd](gdctx, buf, len); + if (ret) { + if (ret == EINVAL) { + vrend_report_buffer_error(gdctx->grctx, *buf); + return ret; + } } - if (ret == ENOMEM) - goto out; - gdctx->ds->buf_offset += (len) + 1; } return 0; - out: - return ret; } static void vrend_decode_ctx_init_base(struct vrend_decode_ctx *dctx,