aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Hellstrom <thellstrom@vmware.com>2016-10-10 14:06:45 -0400
committerSinclair Yeh <syeh@vmware.com>2016-10-10 14:15:05 -0400
commita19440304db2d97aed5cee9bfa5017c98d2348bf (patch)
treecf6c0727b420debe8be56edc17d50e6a8487e471
parent51ab70bed997f64f091a639dbe22b629725a7faf (diff)
drm/vmwgfx: Avoid validating views on view destruction
When a view destruction command was present in the command stream, the view was validated to avoid a device error. That caused excessive and unnecessary validations of views, surfaces and mobs on view destruction. Replace this with a new relocation type that patches the view destruction command to a NOP if the view is not present in the device after the execbuf validation sequence. Also add checks for the member size of the vmw_res_relocation struct. Fixes sporadic command submission errors on google-earth exit. Reported-by: Brian Paul <brianp@vmware.com> Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com> Reviewed-by: Brian Paul <brianp@vmware.com> Reviewed-by: Sinclair Yeh <syeh@vmware.com> Signed-off-by: Sinclair Yeh <syeh@vmware.com> Cc: stable@vger.kernel.org
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c71
1 files changed, 58 insertions, 13 deletions
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
index d1f4a48dee0f..c7b53d987f06 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
@@ -35,17 +35,37 @@
35#define VMW_RES_HT_ORDER 12 35#define VMW_RES_HT_ORDER 12
36 36
37/** 37/**
38 * enum vmw_resource_relocation_type - Relocation type for resources
39 *
40 * @vmw_res_rel_normal: Traditional relocation. The resource id in the
41 * command stream is replaced with the actual id after validation.
42 * @vmw_res_rel_nop: NOP relocation. The command is unconditionally replaced
43 * with a NOP.
44 * @vmw_res_rel_cond_nop: Conditional NOP relocation. If the resource id
45 * after validation is -1, the command is replaced with a NOP. Otherwise no
46 * action.
47 */
48enum vmw_resource_relocation_type {
49 vmw_res_rel_normal,
50 vmw_res_rel_nop,
51 vmw_res_rel_cond_nop,
52 vmw_res_rel_max
53};
54
55/**
38 * struct vmw_resource_relocation - Relocation info for resources 56 * struct vmw_resource_relocation - Relocation info for resources
39 * 57 *
40 * @head: List head for the software context's relocation list. 58 * @head: List head for the software context's relocation list.
41 * @res: Non-ref-counted pointer to the resource. 59 * @res: Non-ref-counted pointer to the resource.
42 * @offset: Offset of single byte entries into the command buffer where the 60 * @offset: Offset of single byte entries into the command buffer where the
43 * id that needs fixup is located. 61 * id that needs fixup is located.
62 * @rel_type: Type of relocation.
44 */ 63 */
45struct vmw_resource_relocation { 64struct vmw_resource_relocation {
46 struct list_head head; 65 struct list_head head;
47 const struct vmw_resource *res; 66 const struct vmw_resource *res;
48 unsigned long offset; 67 u32 offset:29;
68 enum vmw_resource_relocation_type rel_type:3;
49}; 69};
50 70
51/** 71/**
@@ -421,10 +441,13 @@ static int vmw_resource_context_res_add(struct vmw_private *dev_priv,
421 * @res: The resource. 441 * @res: The resource.
422 * @offset: Offset into the command buffer currently being parsed where the 442 * @offset: Offset into the command buffer currently being parsed where the
423 * id that needs fixup is located. Granularity is one byte. 443 * id that needs fixup is located. Granularity is one byte.
444 * @rel_type: Relocation type.
424 */ 445 */
425static int vmw_resource_relocation_add(struct list_head *list, 446static int vmw_resource_relocation_add(struct list_head *list,
426 const struct vmw_resource *res, 447 const struct vmw_resource *res,
427 unsigned long offset) 448 unsigned long offset,
449 enum vmw_resource_relocation_type
450 rel_type)
428{ 451{
429 struct vmw_resource_relocation *rel; 452 struct vmw_resource_relocation *rel;
430 453
@@ -436,6 +459,7 @@ static int vmw_resource_relocation_add(struct list_head *list,
436 459
437 rel->res = res; 460 rel->res = res;
438 rel->offset = offset; 461 rel->offset = offset;
462 rel->rel_type = rel_type;
439 list_add_tail(&rel->head, list); 463 list_add_tail(&rel->head, list);
440 464
441 return 0; 465 return 0;
@@ -470,12 +494,24 @@ static void vmw_resource_relocations_apply(uint32_t *cb,
470{ 494{
471 struct vmw_resource_relocation *rel; 495 struct vmw_resource_relocation *rel;
472 496
497 /* Validate the struct vmw_resource_relocation member size */
498 BUILD_BUG_ON(SVGA_CB_MAX_SIZE >= (1 << 29));
499 BUILD_BUG_ON(vmw_res_rel_max >= (1 << 3));
500
473 list_for_each_entry(rel, list, head) { 501 list_for_each_entry(rel, list, head) {
474 u32 *addr = (u32 *)((unsigned long) cb + rel->offset); 502 u32 *addr = (u32 *)((unsigned long) cb + rel->offset);
475 if (likely(rel->res != NULL)) 503 switch (rel->rel_type) {
504 case vmw_res_rel_normal:
476 *addr = rel->res->id; 505 *addr = rel->res->id;
477 else 506 break;
507 case vmw_res_rel_nop:
478 *addr = SVGA_3D_CMD_NOP; 508 *addr = SVGA_3D_CMD_NOP;
509 break;
510 default:
511 if (rel->res->id == -1)
512 *addr = SVGA_3D_CMD_NOP;
513 break;
514 }
479 } 515 }
480} 516}
481 517
@@ -668,7 +704,8 @@ static int vmw_cmd_res_reloc_add(struct vmw_private *dev_priv,
668 ret = vmw_resource_relocation_add(&sw_context->res_relocations, 704 ret = vmw_resource_relocation_add(&sw_context->res_relocations,
669 res, 705 res,
670 vmw_ptr_diff(sw_context->buf_start, 706 vmw_ptr_diff(sw_context->buf_start,
671 id_loc)); 707 id_loc),
708 vmw_res_rel_normal);
672 if (unlikely(ret != 0)) 709 if (unlikely(ret != 0))
673 return ret; 710 return ret;
674 711
@@ -734,7 +771,8 @@ vmw_cmd_res_check(struct vmw_private *dev_priv,
734 771
735 return vmw_resource_relocation_add 772 return vmw_resource_relocation_add
736 (&sw_context->res_relocations, res, 773 (&sw_context->res_relocations, res,
737 vmw_ptr_diff(sw_context->buf_start, id_loc)); 774 vmw_ptr_diff(sw_context->buf_start, id_loc),
775 vmw_res_rel_normal);
738 } 776 }
739 777
740 ret = vmw_user_resource_lookup_handle(dev_priv, 778 ret = vmw_user_resource_lookup_handle(dev_priv,
@@ -2158,7 +2196,8 @@ static int vmw_cmd_shader_define(struct vmw_private *dev_priv,
2158 return vmw_resource_relocation_add(&sw_context->res_relocations, 2196 return vmw_resource_relocation_add(&sw_context->res_relocations,
2159 NULL, 2197 NULL,
2160 vmw_ptr_diff(sw_context->buf_start, 2198 vmw_ptr_diff(sw_context->buf_start,
2161 &cmd->header.id)); 2199 &cmd->header.id),
2200 vmw_res_rel_nop);
2162} 2201}
2163 2202
2164/** 2203/**
@@ -2202,7 +2241,8 @@ static int vmw_cmd_shader_destroy(struct vmw_private *dev_priv,
2202 return vmw_resource_relocation_add(&sw_context->res_relocations, 2241 return vmw_resource_relocation_add(&sw_context->res_relocations,
2203 NULL, 2242 NULL,
2204 vmw_ptr_diff(sw_context->buf_start, 2243 vmw_ptr_diff(sw_context->buf_start,
2205 &cmd->header.id)); 2244 &cmd->header.id),
2245 vmw_res_rel_nop);
2206} 2246}
2207 2247
2208/** 2248/**
@@ -2859,8 +2899,7 @@ static int vmw_cmd_dx_cid_check(struct vmw_private *dev_priv,
2859 * @header: Pointer to the command header in the command stream. 2899 * @header: Pointer to the command header in the command stream.
2860 * 2900 *
2861 * Check that the view exists, and if it was not created using this 2901 * Check that the view exists, and if it was not created using this
2862 * command batch, make sure it's validated (present in the device) so that 2902 * command batch, conditionally make this command a NOP.
2863 * the remove command will not confuse the device.
2864 */ 2903 */
2865static int vmw_cmd_dx_view_remove(struct vmw_private *dev_priv, 2904static int vmw_cmd_dx_view_remove(struct vmw_private *dev_priv,
2866 struct vmw_sw_context *sw_context, 2905 struct vmw_sw_context *sw_context,
@@ -2888,10 +2927,16 @@ static int vmw_cmd_dx_view_remove(struct vmw_private *dev_priv,
2888 return ret; 2927 return ret;
2889 2928
2890 /* 2929 /*
2891 * Add view to the validate list iff it was not created using this 2930 * If the view wasn't created during this command batch, it might
2892 * command batch. 2931 * have been removed due to a context swapout, so add a
2932 * relocation to conditionally make this command a NOP to avoid
2933 * device errors.
2893 */ 2934 */
2894 return vmw_view_res_val_add(sw_context, view); 2935 return vmw_resource_relocation_add(&sw_context->res_relocations,
2936 view,
2937 vmw_ptr_diff(sw_context->buf_start,
2938 &cmd->header.id),
2939 vmw_res_rel_cond_nop);
2895} 2940}
2896 2941
2897/** 2942/**