diff options
author | Thomas Hellstrom <thellstrom@vmware.com> | 2017-08-24 08:06:29 +0200 |
---|---|---|
committer | Sinclair Yeh <syeh@vmware.com> | 2017-08-28 17:40:46 +0200 |
commit | 65b97a2bec2fc75e9137e8a17954cb66809215bf (patch) | |
tree | 44d3b6e344866347de986da999e0d4003bfc8b17 /drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | |
parent | ef369904aaf717e0390b483efd47daba9ba8ddf2 (diff) |
drm/vmwgfx: Restart command buffers after errors
Previously we skipped the command buffer and added an extra fence to
avoid hangs due to skipped fence commands.
Now we instead restart the command buffer after the failing command,
if there are any commands left.
In addition we print out some information about the failing command
and its location in the command buffer.
Testing Done: ran glxgears using mesa modified to send the NOP_ERROR
command before each 10th clear and verified that we detected the device
error properly and that there were no other device errors caused by
incorrectly ordered command buffers. Also ran the piglit "quick" test
suite which generates a couple of device errors and verified that
they were handled as intended.
Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
Reviewed-by: Brian Paul <brianp@vmware.com>
Reviewed-by: Sinclair Yeh <syeh@vmware.com>
Diffstat (limited to 'drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c')
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 48 |
1 files changed, 47 insertions, 1 deletions
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c index 2cfb3c93f42a..ba2032e04f06 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c @@ -112,11 +112,12 @@ struct vmw_cmd_entry { bool user_allow; bool gb_disable; bool gb_enable; + const char *cmd_name; }; #define VMW_CMD_DEF(_cmd, _func, _user_allow, _gb_disable, _gb_enable) \ [(_cmd) - SVGA_3D_CMD_BASE] = {(_func), (_user_allow),\ - (_gb_disable), (_gb_enable)} + (_gb_disable), (_gb_enable), #_cmd} static int vmw_resource_context_res_add(struct vmw_private *dev_priv, struct vmw_sw_context *sw_context, @@ -3469,6 +3470,51 @@ static const struct vmw_cmd_entry vmw_cmd_entries[SVGA_3D_CMD_MAX] = { true, false, true), }; +bool vmw_cmd_describe(const void *buf, u32 *size, char const **cmd) +{ + u32 cmd_id = ((u32 *) buf)[0]; + + if (cmd_id >= SVGA_CMD_MAX) { + SVGA3dCmdHeader *header = (SVGA3dCmdHeader *) buf; + const struct vmw_cmd_entry *entry; + + *size = header->size + sizeof(SVGA3dCmdHeader); + cmd_id = header->id; + if (cmd_id >= SVGA_3D_CMD_MAX) + return false; + + cmd_id -= SVGA_3D_CMD_BASE; + entry = &vmw_cmd_entries[cmd_id]; + *cmd = entry->cmd_name; + return true; + } + + switch (cmd_id) { + case SVGA_CMD_UPDATE: + *cmd = "SVGA_CMD_UPDATE"; + *size = sizeof(u32) + sizeof(SVGAFifoCmdUpdate); + break; + case SVGA_CMD_DEFINE_GMRFB: + *cmd = "SVGA_CMD_DEFINE_GMRFB"; + *size = sizeof(u32) + sizeof(SVGAFifoCmdDefineGMRFB); + break; + case SVGA_CMD_BLIT_GMRFB_TO_SCREEN: + *cmd = "SVGA_CMD_BLIT_GMRFB_TO_SCREEN"; + *size = sizeof(u32) + sizeof(SVGAFifoCmdBlitGMRFBToScreen); + break; + case SVGA_CMD_BLIT_SCREEN_TO_GMRFB: + *cmd = "SVGA_CMD_BLIT_SCREEN_TO_GMRFB"; + *size = sizeof(u32) + sizeof(SVGAFifoCmdBlitGMRFBToScreen); + break; + default: + *cmd = "UNKNOWN"; + *size = 0; + return false; + } + + return true; +} + static int vmw_cmd_check(struct vmw_private *dev_priv, struct vmw_sw_context *sw_context, void *buf, uint32_t *size) |