root/drivers/gpu/drm/vmwgfx/vmwgfx_simple_resource.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. vmw_simple_resource_init
  2. vmw_simple_resource_free
  3. vmw_simple_resource_base_release
  4. vmw_simple_resource_create_ioctl
  5. vmw_simple_resource_lookup

   1 // SPDX-License-Identifier: GPL-2.0 OR MIT
   2 /**************************************************************************
   3  *
   4  * Copyright 2016 VMware, Inc., Palo Alto, CA., USA
   5  *
   6  * Permission is hereby granted, free of charge, to any person obtaining a
   7  * copy of this software and associated documentation files (the
   8  * "Software"), to deal in the Software without restriction, including
   9  * without limitation the rights to use, copy, modify, merge, publish,
  10  * distribute, sub license, and/or sell copies of the Software, and to
  11  * permit persons to whom the Software is furnished to do so, subject to
  12  * the following conditions:
  13  *
  14  * The above copyright notice and this permission notice (including the
  15  * next paragraph) shall be included in all copies or substantial portions
  16  * of the Software.
  17  *
  18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  20  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
  21  * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
  22  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  23  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
  24  * USE OR OTHER DEALINGS IN THE SOFTWARE.
  25  *
  26  **************************************************************************/
  27 
  28 #include "vmwgfx_drv.h"
  29 #include "vmwgfx_resource_priv.h"
  30 
  31 /**
  32  * struct vmw_user_simple_resource - User-space simple resource struct
  33  *
  34  * @base: The TTM base object implementing user-space visibility.
  35  * @account_size: How much memory was accounted for this object.
  36  * @simple: The embedded struct vmw_simple_resource.
  37  */
  38 struct vmw_user_simple_resource {
  39         struct ttm_base_object base;
  40         size_t account_size;
  41         struct vmw_simple_resource simple;
  42 /*
  43  * Nothing to be placed after @simple, since size of @simple is
  44  * unknown.
  45  */
  46 };
  47 
  48 
  49 /**
  50  * vmw_simple_resource_init - Initialize a simple resource object.
  51  *
  52  * @dev_priv: Pointer to a struct device private.
  53  * @simple: The struct vmw_simple_resource to initialize.
  54  * @data: Data passed to the information initialization function.
  55  * @res_free: Function pointer to destroy the simple resource.
  56  *
  57  * Returns:
  58  *   0 if succeeded.
  59  *   Negative error value if error, in which case the resource will have been
  60  * freed.
  61  */
  62 static int vmw_simple_resource_init(struct vmw_private *dev_priv,
  63                                     struct vmw_simple_resource *simple,
  64                                     void *data,
  65                                     void (*res_free)(struct vmw_resource *res))
  66 {
  67         struct vmw_resource *res = &simple->res;
  68         int ret;
  69 
  70         ret = vmw_resource_init(dev_priv, res, false, res_free,
  71                                 &simple->func->res_func);
  72 
  73         if (ret) {
  74                 res_free(res);
  75                 return ret;
  76         }
  77 
  78         ret = simple->func->init(res, data);
  79         if (ret) {
  80                 vmw_resource_unreference(&res);
  81                 return ret;
  82         }
  83 
  84         simple->res.hw_destroy = simple->func->hw_destroy;
  85 
  86         return 0;
  87 }
  88 
  89 /**
  90  * vmw_simple_resource_free - Free a simple resource object.
  91  *
  92  * @res: The struct vmw_resource member of the simple resource object.
  93  *
  94  * Frees memory and memory accounting for the object.
  95  */
  96 static void vmw_simple_resource_free(struct vmw_resource *res)
  97 {
  98         struct vmw_user_simple_resource *usimple =
  99                 container_of(res, struct vmw_user_simple_resource,
 100                              simple.res);
 101         struct vmw_private *dev_priv = res->dev_priv;
 102         size_t size = usimple->account_size;
 103 
 104         ttm_base_object_kfree(usimple, base);
 105         ttm_mem_global_free(vmw_mem_glob(dev_priv), size);
 106 }
 107 
 108 /**
 109  * vmw_simple_resource_base_release - TTM object release callback
 110  *
 111  * @p_base: The struct ttm_base_object member of the simple resource object.
 112  *
 113  * Called when the last reference to the embedded struct ttm_base_object is
 114  * gone. Typically results in an object free, unless there are other
 115  * references to the embedded struct vmw_resource.
 116  */
 117 static void vmw_simple_resource_base_release(struct ttm_base_object **p_base)
 118 {
 119         struct ttm_base_object *base = *p_base;
 120         struct vmw_user_simple_resource *usimple =
 121                 container_of(base, struct vmw_user_simple_resource, base);
 122         struct vmw_resource *res = &usimple->simple.res;
 123 
 124         *p_base = NULL;
 125         vmw_resource_unreference(&res);
 126 }
 127 
 128 /**
 129  * vmw_simple_resource_create_ioctl - Helper to set up an ioctl function to
 130  * create a struct vmw_simple_resource.
 131  *
 132  * @dev: Pointer to a struct drm device.
 133  * @data: Ioctl argument.
 134  * @file_priv: Pointer to a struct drm_file identifying the caller.
 135  * @func: Pointer to a struct vmw_simple_resource_func identifying the
 136  * simple resource type.
 137  *
 138  * Returns:
 139  *   0 if success,
 140  *   Negative error value on error.
 141  */
 142 int
 143 vmw_simple_resource_create_ioctl(struct drm_device *dev, void *data,
 144                                  struct drm_file *file_priv,
 145                                  const struct vmw_simple_resource_func *func)
 146 {
 147         struct vmw_private *dev_priv = vmw_priv(dev);
 148         struct vmw_user_simple_resource *usimple;
 149         struct vmw_resource *res;
 150         struct vmw_resource *tmp;
 151         struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
 152         struct ttm_operation_ctx ctx = {
 153                 .interruptible = true,
 154                 .no_wait_gpu = false
 155         };
 156         size_t alloc_size;
 157         size_t account_size;
 158         int ret;
 159 
 160         alloc_size = offsetof(struct vmw_user_simple_resource, simple) +
 161           func->size;
 162         account_size = ttm_round_pot(alloc_size) + VMW_IDA_ACC_SIZE +
 163                 TTM_OBJ_EXTRA_SIZE;
 164 
 165         ret = ttm_read_lock(&dev_priv->reservation_sem, true);
 166         if (ret)
 167                 return ret;
 168 
 169         ret = ttm_mem_global_alloc(vmw_mem_glob(dev_priv), account_size,
 170                                    &ctx);
 171         ttm_read_unlock(&dev_priv->reservation_sem);
 172         if (ret) {
 173                 if (ret != -ERESTARTSYS)
 174                         DRM_ERROR("Out of graphics memory for %s"
 175                                   " creation.\n", func->res_func.type_name);
 176 
 177                 goto out_ret;
 178         }
 179 
 180         usimple = kzalloc(alloc_size, GFP_KERNEL);
 181         if (!usimple) {
 182                 ttm_mem_global_free(vmw_mem_glob(dev_priv),
 183                                     account_size);
 184                 ret = -ENOMEM;
 185                 goto out_ret;
 186         }
 187 
 188         usimple->simple.func = func;
 189         usimple->account_size = account_size;
 190         res = &usimple->simple.res;
 191         usimple->base.shareable = false;
 192         usimple->base.tfile = NULL;
 193 
 194         /*
 195          * From here on, the destructor takes over resource freeing.
 196          */
 197         ret = vmw_simple_resource_init(dev_priv, &usimple->simple,
 198                                        data, vmw_simple_resource_free);
 199         if (ret)
 200                 goto out_ret;
 201 
 202         tmp = vmw_resource_reference(res);
 203         ret = ttm_base_object_init(tfile, &usimple->base, false,
 204                                    func->ttm_res_type,
 205                                    &vmw_simple_resource_base_release, NULL);
 206 
 207         if (ret) {
 208                 vmw_resource_unreference(&tmp);
 209                 goto out_err;
 210         }
 211 
 212         func->set_arg_handle(data, usimple->base.handle);
 213 out_err:
 214         vmw_resource_unreference(&res);
 215 out_ret:
 216         return ret;
 217 }
 218 
 219 /**
 220  * vmw_simple_resource_lookup - Look up a simple resource from its user-space
 221  * handle.
 222  *
 223  * @tfile: struct ttm_object_file identifying the caller.
 224  * @handle: The user-space handle.
 225  * @func: The struct vmw_simple_resource_func identifying the simple resource
 226  * type.
 227  *
 228  * Returns: Refcounted pointer to the embedded struct vmw_resource if
 229  * successfule. Error pointer otherwise.
 230  */
 231 struct vmw_resource *
 232 vmw_simple_resource_lookup(struct ttm_object_file *tfile,
 233                            uint32_t handle,
 234                            const struct vmw_simple_resource_func *func)
 235 {
 236         struct vmw_user_simple_resource *usimple;
 237         struct ttm_base_object *base;
 238         struct vmw_resource *res;
 239 
 240         base = ttm_base_object_lookup(tfile, handle);
 241         if (!base) {
 242                 VMW_DEBUG_USER("Invalid %s handle 0x%08lx.\n",
 243                                func->res_func.type_name,
 244                                (unsigned long) handle);
 245                 return ERR_PTR(-ESRCH);
 246         }
 247 
 248         if (ttm_base_object_type(base) != func->ttm_res_type) {
 249                 ttm_base_object_unref(&base);
 250                 VMW_DEBUG_USER("Invalid type of %s handle 0x%08lx.\n",
 251                                func->res_func.type_name,
 252                                (unsigned long) handle);
 253                 return ERR_PTR(-EINVAL);
 254         }
 255 
 256         usimple = container_of(base, typeof(*usimple), base);
 257         res = vmw_resource_reference(&usimple->simple.res);
 258         ttm_base_object_unref(&base);
 259 
 260         return res;
 261 }

/* [<][>][^][v][top][bottom][index][help] */