Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 508108ea authored by Thomas Hellstrom's avatar Thomas Hellstrom
Browse files

drm/vmwgfx: Don't refcount command-buffer managed resource lookups during command buffer validation



The typical pattern of these lookups are
-Lookup
-Put on validate list if not already there.
-Unreference
And since we are the exclusive user of the context during lookup time,
we can be sure that the resource will stay alive during the sequence.
So avoid taking a reference during lookup, and also avoid unreferencing
when done.

Signed-off-by: default avatarThomas Hellstrom <thellstrom@vmware.com>
Reviewed-by: default avatarSinclair Yeh <syeh@vmware.com>
parent b139d43d
Loading
Loading
Loading
Loading
+1 −2
Original line number Original line Diff line number Diff line
@@ -89,8 +89,7 @@ vmw_cmdbuf_res_lookup(struct vmw_cmdbuf_res_manager *man,
	if (unlikely(ret != 0))
	if (unlikely(ret != 0))
		return ERR_PTR(ret);
		return ERR_PTR(ret);


	return vmw_resource_reference
	return drm_hash_entry(hash, struct vmw_cmdbuf_res, hash)->res;
		(drm_hash_entry(hash, struct vmw_cmdbuf_res, hash)->res);
}
}


/**
/**
+26 −43
Original line number Original line Diff line number Diff line
@@ -314,9 +314,13 @@ static int vmw_view_res_val_add(struct vmw_sw_context *sw_context,
 *
 *
 * The view is represented by a view id and the DX context it's created on,
 * The view is represented by a view id and the DX context it's created on,
 * or scheduled for creation on. If there is no DX context set, the function
 * or scheduled for creation on. If there is no DX context set, the function
 * will return -EINVAL. Otherwise returns 0 on success and -EINVAL on failure.
 * will return an -EINVAL error pointer.
 *
 * Returns: Unreferenced pointer to the resource on success, negative error
 * pointer on failure.
 */
 */
static int vmw_view_id_val_add(struct vmw_sw_context *sw_context,
static struct vmw_resource *
vmw_view_id_val_add(struct vmw_sw_context *sw_context,
		    enum vmw_view_type view_type, u32 id)
		    enum vmw_view_type view_type, u32 id)
{
{
	struct vmw_ctx_validation_info *ctx_node = sw_context->dx_ctx_node;
	struct vmw_ctx_validation_info *ctx_node = sw_context->dx_ctx_node;
@@ -325,17 +329,18 @@ static int vmw_view_id_val_add(struct vmw_sw_context *sw_context,


	if (!ctx_node) {
	if (!ctx_node) {
		DRM_ERROR("DX Context not set.\n");
		DRM_ERROR("DX Context not set.\n");
		return -EINVAL;
		return ERR_PTR(-EINVAL);
	}
	}


	view = vmw_view_lookup(sw_context->man, view_type, id);
	view = vmw_view_lookup(sw_context->man, view_type, id);
	if (IS_ERR(view))
	if (IS_ERR(view))
		return PTR_ERR(view);
		return view;


	ret = vmw_view_res_val_add(sw_context, view);
	ret = vmw_view_res_val_add(sw_context, view);
	vmw_resource_unreference(&view);
	if (ret)
		return ERR_PTR(ret);


	return ret;
	return view;
}
}


/**
/**
@@ -740,34 +745,24 @@ static int vmw_view_bindings_add(struct vmw_sw_context *sw_context,
				 u32 first_slot)
				 u32 first_slot)
{
{
	struct vmw_ctx_validation_info *ctx_node = sw_context->dx_ctx_node;
	struct vmw_ctx_validation_info *ctx_node = sw_context->dx_ctx_node;
	struct vmw_cmdbuf_res_manager *man;
	u32 i;
	u32 i;
	int ret;


	if (!ctx_node) {
	if (!ctx_node) {
		DRM_ERROR("DX Context not set.\n");
		DRM_ERROR("DX Context not set.\n");
		return -EINVAL;
		return -EINVAL;
	}
	}


	man = sw_context->man;
	for (i = 0; i < num_views; ++i) {
	for (i = 0; i < num_views; ++i) {
		struct vmw_ctx_bindinfo_view binding;
		struct vmw_ctx_bindinfo_view binding;
		struct vmw_resource *view = NULL;
		struct vmw_resource *view = NULL;


		if (view_ids[i] != SVGA3D_INVALID_ID) {
		if (view_ids[i] != SVGA3D_INVALID_ID) {
			view = vmw_view_lookup(man, view_type, view_ids[i]);
			view = vmw_view_id_val_add(sw_context, view_type,
						   view_ids[i]);
			if (IS_ERR(view)) {
			if (IS_ERR(view)) {
				DRM_ERROR("View not found.\n");
				DRM_ERROR("View not found.\n");
				return PTR_ERR(view);
				return PTR_ERR(view);
			}
			}

			ret = vmw_view_res_val_add(sw_context, view);
			if (ret) {
				DRM_ERROR("Could not add view to "
					  "validation list.\n");
				vmw_resource_unreference(&view);
				return ret;
			}
		}
		}
		binding.bi.ctx = ctx_node->ctx;
		binding.bi.ctx = ctx_node->ctx;
		binding.bi.res = view;
		binding.bi.res = view;
@@ -776,8 +771,6 @@ static int vmw_view_bindings_add(struct vmw_sw_context *sw_context,
		binding.slot = first_slot + i;
		binding.slot = first_slot + i;
		vmw_binding_add(ctx_node->staged, &binding.bi,
		vmw_binding_add(ctx_node->staged, &binding.bi,
				shader_slot, binding.slot);
				shader_slot, binding.slot);
		if (view)
			vmw_resource_unreference(&view);
	}
	}


	return 0;
	return 0;
@@ -2136,11 +2129,8 @@ static int vmw_cmd_set_shader(struct vmw_private *dev_priv,
					cmd->body.type);
					cmd->body.type);


		if (!IS_ERR(res)) {
		if (!IS_ERR(res)) {
			struct vmw_resource *tmp_res = res;

			ret = vmw_cmd_res_reloc_add(dev_priv, sw_context,
			ret = vmw_cmd_res_reloc_add(dev_priv, sw_context,
						    &cmd->body.shid, res);
						    &cmd->body.shid, res);
			vmw_resource_unreference(&tmp_res);
			if (unlikely(ret != 0))
			if (unlikely(ret != 0))
				return ret;
				return ret;
		}
		}
@@ -2359,7 +2349,7 @@ static int vmw_cmd_dx_set_shader(struct vmw_private *dev_priv,


		ret = vmw_resource_val_add(sw_context, res);
		ret = vmw_resource_val_add(sw_context, res);
		if (ret)
		if (ret)
			goto out_unref;
			return ret;
	}
	}


	binding.bi.ctx = ctx_node->ctx;
	binding.bi.ctx = ctx_node->ctx;
@@ -2369,11 +2359,8 @@ static int vmw_cmd_dx_set_shader(struct vmw_private *dev_priv,


	vmw_binding_add(ctx_node->staged, &binding.bi,
	vmw_binding_add(ctx_node->staged, &binding.bi,
			binding.shader_slot, 0);
			binding.shader_slot, 0);
out_unref:
	if (res)
		vmw_resource_unreference(&res);


	return ret;
	return 0;
}
}


/**
/**
@@ -2530,8 +2517,8 @@ static int vmw_cmd_dx_clear_rendertarget_view(struct vmw_private *dev_priv,
		SVGA3dCmdDXClearRenderTargetView body;
		SVGA3dCmdDXClearRenderTargetView body;
	} *cmd = container_of(header, typeof(*cmd), header);
	} *cmd = container_of(header, typeof(*cmd), header);


	return vmw_view_id_val_add(sw_context, vmw_view_rt,
	return PTR_RET(vmw_view_id_val_add(sw_context, vmw_view_rt,
				   cmd->body.renderTargetViewId);
					   cmd->body.renderTargetViewId));
}
}


/**
/**
@@ -2551,8 +2538,8 @@ static int vmw_cmd_dx_clear_depthstencil_view(struct vmw_private *dev_priv,
		SVGA3dCmdDXClearDepthStencilView body;
		SVGA3dCmdDXClearDepthStencilView body;
	} *cmd = container_of(header, typeof(*cmd), header);
	} *cmd = container_of(header, typeof(*cmd), header);


	return vmw_view_id_val_add(sw_context, vmw_view_ds,
	return PTR_RET(vmw_view_id_val_add(sw_context, vmw_view_ds,
				   cmd->body.depthStencilViewId);
					   cmd->body.depthStencilViewId));
}
}


static int vmw_cmd_dx_view_define(struct vmw_private *dev_priv,
static int vmw_cmd_dx_view_define(struct vmw_private *dev_priv,
@@ -2904,17 +2891,13 @@ static int vmw_cmd_dx_bind_shader(struct vmw_private *dev_priv,
	ret = vmw_resource_val_add(sw_context, res);
	ret = vmw_resource_val_add(sw_context, res);
	if (ret) {
	if (ret) {
		DRM_ERROR("Error creating resource validation node.\n");
		DRM_ERROR("Error creating resource validation node.\n");
		goto out_unref;
		return ret;
	}
	}




	ret = vmw_cmd_res_switch_backup(dev_priv, sw_context, res,
	return vmw_cmd_res_switch_backup(dev_priv, sw_context, res,
					 &cmd->body.mobid,
					 &cmd->body.mobid,
					 cmd->body.offsetInBytes);
					 cmd->body.offsetInBytes);
out_unref:
	vmw_resource_unreference(&res);

	return ret;
}
}


/**
/**
@@ -2933,8 +2916,8 @@ static int vmw_cmd_dx_genmips(struct vmw_private *dev_priv,
		SVGA3dCmdDXGenMips body;
		SVGA3dCmdDXGenMips body;
	} *cmd = container_of(header, typeof(*cmd), header);
	} *cmd = container_of(header, typeof(*cmd), header);


	return vmw_view_id_val_add(sw_context, vmw_view_sr,
	return PTR_RET(vmw_view_id_val_add(sw_context, vmw_view_sr,
				   cmd->body.shaderResourceViewId);
					   cmd->body.shaderResourceViewId));
}
}


/**
/**