linux/drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c

// SPDX-License-Identifier: GPL-2.0 OR MIT
/**************************************************************************
 *
 * Copyright 2014-2023 VMware, Inc., Palo Alto, CA., USA
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sub license, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice (including the
 * next paragraph) shall be included in all copies or substantial portions
 * of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
 * USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 **************************************************************************/
/*
 * Treat context OTables as resources to make use of the resource
 * backing MOB eviction mechanism, that is used to read back the COTable
 * whenever the backing MOB is evicted.
 */

#include "vmwgfx_bo.h"
#include "vmwgfx_drv.h"
#include "vmwgfx_mksstat.h"
#include "vmwgfx_resource_priv.h"
#include "vmwgfx_so.h"

#include <drm/ttm/ttm_placement.h>

/**
 * struct vmw_cotable - Context Object Table resource
 *
 * @res: struct vmw_resource we are deriving from.
 * @ctx: non-refcounted pointer to the owning context.
 * @size_read_back: Size of data read back during eviction.
 * @seen_entries: Seen entries in command stream for this cotable.
 * @type: The cotable type.
 * @scrubbed: Whether the cotable has been scrubbed.
 * @resource_list: List of resources in the cotable.
 */
struct vmw_cotable {};

/**
 * struct vmw_cotable_info - Static info about cotable types
 *
 * @min_initial_entries: Min number of initial intries at cotable allocation
 * for this cotable type.
 * @size: Size of each entry.
 * @unbind_func: Unbind call-back function.
 */
struct vmw_cotable_info {};


/*
 * Getting the initial size right is difficult because it all depends
 * on what the userspace is doing. The sizes will be aligned up to
 * a PAGE_SIZE so we just want to make sure that for majority of apps
 * the initial number of entries doesn't require an immediate resize.
 * For all cotables except SVGACOTableDXElementLayoutEntry and
 * SVGACOTableDXBlendStateEntry the initial number of entries fits
 * within the PAGE_SIZE. For SVGACOTableDXElementLayoutEntry and
 * SVGACOTableDXBlendStateEntry we want to reserve two pages,
 * because that's what all apps will require initially.
 */
static const struct vmw_cotable_info co_info[] =;

/*
 * Cotables with bindings that we remove must be scrubbed first,
 * otherwise, the device will swap in an invalid context when we remove
 * bindings before scrubbing a cotable...
 */
const SVGACOTableType vmw_cotable_scrub_order[] =;

static int vmw_cotable_bind(struct vmw_resource *res,
			    struct ttm_validate_buffer *val_buf);
static int vmw_cotable_unbind(struct vmw_resource *res,
			      bool readback,
			      struct ttm_validate_buffer *val_buf);
static int vmw_cotable_create(struct vmw_resource *res);
static int vmw_cotable_destroy(struct vmw_resource *res);

static const struct vmw_res_func vmw_cotable_func =;

/**
 * vmw_cotable - Convert a struct vmw_resource pointer to a struct
 * vmw_cotable pointer
 *
 * @res: Pointer to the resource.
 */
static struct vmw_cotable *vmw_cotable(struct vmw_resource *res)
{}

/**
 * vmw_cotable_destroy - Cotable resource destroy callback
 *
 * @res: Pointer to the cotable resource.
 *
 * There is no device cotable destroy command, so this function only
 * makes sure that the resource id is set to invalid.
 */
static int vmw_cotable_destroy(struct vmw_resource *res)
{}

/**
 * vmw_cotable_unscrub - Undo a cotable unscrub operation
 *
 * @res: Pointer to the cotable resource
 *
 * This function issues commands to (re)bind the cotable to
 * its backing mob, which needs to be validated and reserved at this point.
 * This is identical to bind() except the function interface looks different.
 */
static int vmw_cotable_unscrub(struct vmw_resource *res)
{}

/**
 * vmw_cotable_bind - Undo a cotable unscrub operation
 *
 * @res: Pointer to the cotable resource
 * @val_buf: Pointer to a struct ttm_validate_buffer prepared by the caller
 * for convenience / fencing.
 *
 * This function issues commands to (re)bind the cotable to
 * its backing mob, which needs to be validated and reserved at this point.
 */
static int vmw_cotable_bind(struct vmw_resource *res,
			    struct ttm_validate_buffer *val_buf)
{}

/**
 * vmw_cotable_scrub - Scrub the cotable from the device.
 *
 * @res: Pointer to the cotable resource.
 * @readback: Whether initiate a readback of the cotable data to the backup
 * buffer.
 *
 * In some situations (context swapouts) it might be desirable to make the
 * device forget about the cotable without performing a full unbind. A full
 * unbind requires reserved backup buffers and it might not be possible to
 * reserve them due to locking order violation issues. The vmw_cotable_scrub
 * function implements a partial unbind() without that requirement but with the
 * following restrictions.
 * 1) Before the cotable is again used by the GPU, vmw_cotable_unscrub() must
 *    be called.
 * 2) Before the cotable backing buffer is used by the CPU, or during the
 *    resource destruction, vmw_cotable_unbind() must be called.
 */
int vmw_cotable_scrub(struct vmw_resource *res, bool readback)
{}

/**
 * vmw_cotable_unbind - Cotable resource unbind callback
 *
 * @res: Pointer to the cotable resource.
 * @readback: Whether to read back cotable data to the backup buffer.
 * @val_buf: Pointer to a struct ttm_validate_buffer prepared by the caller
 * for convenience / fencing.
 *
 * Unbinds the cotable from the device and fences the backup buffer.
 */
static int vmw_cotable_unbind(struct vmw_resource *res,
			      bool readback,
			      struct ttm_validate_buffer *val_buf)
{}

/**
 * vmw_cotable_readback - Read back a cotable without unbinding.
 *
 * @res: The cotable resource.
 *
 * Reads back a cotable to its backing mob without scrubbing the MOB from
 * the cotable. The MOB is fenced for subsequent CPU access.
 */
static int vmw_cotable_readback(struct vmw_resource *res)
{}

/**
 * vmw_cotable_resize - Resize a cotable.
 *
 * @res: The cotable resource.
 * @new_size: The new size.
 *
 * Resizes a cotable and binds the new backup buffer.
 * On failure the cotable is left intact.
 * Important! This function may not fail once the MOB switch has been
 * committed to hardware. That would put the device context in an
 * invalid state which we can't currently recover from.
 */
static int vmw_cotable_resize(struct vmw_resource *res, size_t new_size)
{}

/**
 * vmw_cotable_create - Cotable resource create callback
 *
 * @res: Pointer to a cotable resource.
 *
 * There is no separate create command for cotables, so this callback, which
 * is called before bind() in the validation sequence is instead used for two
 * things.
 * 1) Unscrub the cotable if it is scrubbed and still attached to a backup
 *    buffer.
 * 2) Resize the cotable if needed.
 */
static int vmw_cotable_create(struct vmw_resource *res)
{}

/**
 * vmw_hw_cotable_destroy - Cotable hw_destroy callback
 *
 * @res: Pointer to a cotable resource.
 *
 * The final (part of resource destruction) destroy callback.
 */
static void vmw_hw_cotable_destroy(struct vmw_resource *res)
{}

/**
 * vmw_cotable_free - Cotable resource destructor
 *
 * @res: Pointer to a cotable resource.
 */
static void vmw_cotable_free(struct vmw_resource *res)
{}

/**
 * vmw_cotable_alloc - Create a cotable resource
 *
 * @dev_priv: Pointer to a device private struct.
 * @ctx: Pointer to the context resource.
 * The cotable resource will not add a refcount.
 * @type: The cotable type.
 */
struct vmw_resource *vmw_cotable_alloc(struct vmw_private *dev_priv,
				       struct vmw_resource *ctx,
				       u32 type)
{}

/**
 * vmw_cotable_notify - Notify the cotable about an item creation
 *
 * @res: Pointer to a cotable resource.
 * @id: Item id.
 */
int vmw_cotable_notify(struct vmw_resource *res, int id)
{}

/**
 * vmw_cotable_add_resource - add a view to the cotable's list of active views.
 *
 * @res: pointer struct vmw_resource representing the cotable.
 * @head: pointer to the struct list_head member of the resource, dedicated
 * to the cotable active resource list.
 */
void vmw_cotable_add_resource(struct vmw_resource *res, struct list_head *head)
{}