Back to home page

OSCL-LXR

 
 

    


0001 /**************************************************************************
0002  *
0003  * Copyright (c) 2006-2009 VMware, Inc., Palo Alto, CA., USA
0004  * All Rights Reserved.
0005  *
0006  * Permission is hereby granted, free of charge, to any person obtaining a
0007  * copy of this software and associated documentation files (the
0008  * "Software"), to deal in the Software without restriction, including
0009  * without limitation the rights to use, copy, modify, merge, publish,
0010  * distribute, sub license, and/or sell copies of the Software, and to
0011  * permit persons to whom the Software is furnished to do so, subject to
0012  * the following conditions:
0013  *
0014  * The above copyright notice and this permission notice (including the
0015  * next paragraph) shall be included in all copies or substantial portions
0016  * of the Software.
0017  *
0018  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0019  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0020  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
0021  * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
0022  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
0023  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
0024  * USE OR OTHER DEALINGS IN THE SOFTWARE.
0025  *
0026  **************************************************************************/
0027 /*
0028  * Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com>
0029  */
0030 /** @file ttm_object.h
0031  *
0032  * Base- and reference object implementation for the various
0033  * ttm objects. Implements reference counting, minimal security checks
0034  * and release on file close.
0035  */
0036 
0037 #ifndef _TTM_OBJECT_H_
0038 #define _TTM_OBJECT_H_
0039 
0040 #include <linux/dma-buf.h>
0041 #include <linux/kref.h>
0042 #include <linux/list.h>
0043 #include <linux/rcupdate.h>
0044 
0045 #include "vmwgfx_hashtab.h"
0046 
0047 /**
0048  * enum ttm_object_type
0049  *
0050  * One entry per ttm object type.
0051  * Device-specific types should use the
0052  * ttm_driver_typex types.
0053  */
0054 
0055 enum ttm_object_type {
0056     ttm_fence_type,
0057     ttm_lock_type,
0058     ttm_prime_type,
0059     ttm_driver_type0 = 256,
0060     ttm_driver_type1,
0061     ttm_driver_type2,
0062     ttm_driver_type3,
0063     ttm_driver_type4,
0064     ttm_driver_type5
0065 };
0066 
0067 struct ttm_object_file;
0068 struct ttm_object_device;
0069 
0070 /**
0071  * struct ttm_base_object
0072  *
0073  * @hash: hash entry for the per-device object hash.
0074  * @type: derived type this object is base class for.
0075  * @shareable: Other ttm_object_files can access this object.
0076  *
0077  * @tfile: Pointer to ttm_object_file of the creator.
0078  * NULL if the object was not created by a user request.
0079  * (kernel object).
0080  *
0081  * @refcount: Number of references to this object, not
0082  * including the hash entry. A reference to a base object can
0083  * only be held by a ref object.
0084  *
0085  * @refcount_release: A function to be called when there are
0086  * no more references to this object. This function should
0087  * destroy the object (or make sure destruction eventually happens),
0088  * and when it is called, the object has
0089  * already been taken out of the per-device hash. The parameter
0090  * "base" should be set to NULL by the function.
0091  *
0092  * @ref_obj_release: A function to be called when a reference object
0093  * with another ttm_ref_type than TTM_REF_USAGE is deleted.
0094  * This function may, for example, release a lock held by a user-space
0095  * process.
0096  *
0097  * This struct is intended to be used as a base struct for objects that
0098  * are visible to user-space. It provides a global name, race-safe
0099  * access and refcounting, minimal access contol and hooks for unref actions.
0100  */
0101 
0102 struct ttm_base_object {
0103     struct rcu_head rhead;
0104     struct ttm_object_file *tfile;
0105     struct kref refcount;
0106     void (*refcount_release) (struct ttm_base_object **base);
0107     u32 handle;
0108     enum ttm_object_type object_type;
0109     u32 shareable;
0110 };
0111 
0112 
0113 /**
0114  * struct ttm_prime_object - Modified base object that is prime-aware
0115  *
0116  * @base: struct ttm_base_object that we derive from
0117  * @mutex: Mutex protecting the @dma_buf member.
0118  * @size: Size of the dma_buf associated with this object
0119  * @real_type: Type of the underlying object. Needed since we're setting
0120  * the value of @base::object_type to ttm_prime_type
0121  * @dma_buf: Non ref-coutned pointer to a struct dma_buf created from this
0122  * object.
0123  * @refcount_release: The underlying object's release method. Needed since
0124  * we set @base::refcount_release to our own release method.
0125  */
0126 
0127 struct ttm_prime_object {
0128     struct ttm_base_object base;
0129     struct mutex mutex;
0130     size_t size;
0131     enum ttm_object_type real_type;
0132     struct dma_buf *dma_buf;
0133     void (*refcount_release) (struct ttm_base_object **);
0134 };
0135 
0136 /**
0137  * ttm_base_object_init
0138  *
0139  * @tfile: Pointer to a struct ttm_object_file.
0140  * @base: The struct ttm_base_object to initialize.
0141  * @shareable: This object is shareable with other applcations.
0142  * (different @tfile pointers.)
0143  * @type: The object type.
0144  * @refcount_release: See the struct ttm_base_object description.
0145  * @ref_obj_release: See the struct ttm_base_object description.
0146  *
0147  * Initializes a struct ttm_base_object.
0148  */
0149 
0150 extern int ttm_base_object_init(struct ttm_object_file *tfile,
0151                 struct ttm_base_object *base,
0152                 bool shareable,
0153                 enum ttm_object_type type,
0154                 void (*refcount_release) (struct ttm_base_object
0155                               **));
0156 
0157 /**
0158  * ttm_base_object_lookup
0159  *
0160  * @tfile: Pointer to a struct ttm_object_file.
0161  * @key: Hash key
0162  *
0163  * Looks up a struct ttm_base_object with the key @key.
0164  */
0165 
0166 extern struct ttm_base_object *ttm_base_object_lookup(struct ttm_object_file
0167                               *tfile, uint32_t key);
0168 
0169 /**
0170  * ttm_base_object_lookup_for_ref
0171  *
0172  * @tdev: Pointer to a struct ttm_object_device.
0173  * @key: Hash key
0174  *
0175  * Looks up a struct ttm_base_object with the key @key.
0176  * This function should only be used when the struct tfile associated with the
0177  * caller doesn't yet have a reference to the base object.
0178  */
0179 
0180 extern struct ttm_base_object *
0181 ttm_base_object_lookup_for_ref(struct ttm_object_device *tdev, uint32_t key);
0182 
0183 /**
0184  * ttm_base_object_unref
0185  *
0186  * @p_base: Pointer to a pointer referencing a struct ttm_base_object.
0187  *
0188  * Decrements the base object refcount and clears the pointer pointed to by
0189  * p_base.
0190  */
0191 
0192 extern void ttm_base_object_unref(struct ttm_base_object **p_base);
0193 
0194 /**
0195  * ttm_ref_object_add.
0196  *
0197  * @tfile: A struct ttm_object_file representing the application owning the
0198  * ref_object.
0199  * @base: The base object to reference.
0200  * @ref_type: The type of reference.
0201  * @existed: Upon completion, indicates that an identical reference object
0202  * already existed, and the refcount was upped on that object instead.
0203  * @require_existed: Fail with -EPERM if an identical ref object didn't
0204  * already exist.
0205  *
0206  * Checks that the base object is shareable and adds a ref object to it.
0207  *
0208  * Adding a ref object to a base object is basically like referencing the
0209  * base object, but a user-space application holds the reference. When the
0210  * file corresponding to @tfile is closed, all its reference objects are
0211  * deleted. A reference object can have different types depending on what
0212  * it's intended for. It can be refcounting to prevent object destruction,
0213  * When user-space takes a lock, it can add a ref object to that lock to
0214  * make sure the lock is released if the application dies. A ref object
0215  * will hold a single reference on a base object.
0216  */
0217 extern int ttm_ref_object_add(struct ttm_object_file *tfile,
0218                   struct ttm_base_object *base,
0219                   bool *existed,
0220                   bool require_existed);
0221 
0222 /**
0223  * ttm_ref_object_base_unref
0224  *
0225  * @key: Key representing the base object.
0226  * @ref_type: Ref type of the ref object to be dereferenced.
0227  *
0228  * Unreference a ref object with type @ref_type
0229  * on the base object identified by @key. If there are no duplicate
0230  * references, the ref object will be destroyed and the base object
0231  * will be unreferenced.
0232  */
0233 extern int ttm_ref_object_base_unref(struct ttm_object_file *tfile,
0234                      unsigned long key);
0235 
0236 /**
0237  * ttm_object_file_init - initialize a struct ttm_object file
0238  *
0239  * @tdev: A struct ttm_object device this file is initialized on.
0240  * @hash_order: Order of the hash table used to hold the reference objects.
0241  *
0242  * This is typically called by the file_ops::open function.
0243  */
0244 
0245 extern struct ttm_object_file *ttm_object_file_init(struct ttm_object_device
0246                             *tdev,
0247                             unsigned int hash_order);
0248 
0249 /**
0250  * ttm_object_file_release - release data held by a ttm_object_file
0251  *
0252  * @p_tfile: Pointer to pointer to the ttm_object_file object to release.
0253  * *p_tfile will be set to NULL by this function.
0254  *
0255  * Releases all data associated by a ttm_object_file.
0256  * Typically called from file_ops::release. The caller must
0257  * ensure that there are no concurrent users of tfile.
0258  */
0259 
0260 extern void ttm_object_file_release(struct ttm_object_file **p_tfile);
0261 
0262 /**
0263  * ttm_object device init - initialize a struct ttm_object_device
0264  *
0265  * @hash_order: Order of hash table used to hash the base objects.
0266  * @ops: DMA buf ops for prime objects of this device.
0267  *
0268  * This function is typically called on device initialization to prepare
0269  * data structures needed for ttm base and ref objects.
0270  */
0271 
0272 extern struct ttm_object_device *
0273 ttm_object_device_init(unsigned int hash_order,
0274                const struct dma_buf_ops *ops);
0275 
0276 /**
0277  * ttm_object_device_release - release data held by a ttm_object_device
0278  *
0279  * @p_tdev: Pointer to pointer to the ttm_object_device object to release.
0280  * *p_tdev will be set to NULL by this function.
0281  *
0282  * Releases all data associated by a ttm_object_device.
0283  * Typically called from driver::unload before the destruction of the
0284  * device private data structure.
0285  */
0286 
0287 extern void ttm_object_device_release(struct ttm_object_device **p_tdev);
0288 
0289 #define ttm_base_object_kfree(__object, __base)\
0290     kfree_rcu(__object, __base.rhead)
0291 
0292 extern int ttm_prime_object_init(struct ttm_object_file *tfile,
0293                  size_t size,
0294                  struct ttm_prime_object *prime,
0295                  bool shareable,
0296                  enum ttm_object_type type,
0297                  void (*refcount_release)
0298                  (struct ttm_base_object **));
0299 
0300 static inline enum ttm_object_type
0301 ttm_base_object_type(struct ttm_base_object *base)
0302 {
0303     return (base->object_type == ttm_prime_type) ?
0304         container_of(base, struct ttm_prime_object, base)->real_type :
0305         base->object_type;
0306 }
0307 extern int ttm_prime_fd_to_handle(struct ttm_object_file *tfile,
0308                   int fd, u32 *handle);
0309 extern int ttm_prime_handle_to_fd(struct ttm_object_file *tfile,
0310                   uint32_t handle, uint32_t flags,
0311                   int *prime_fd);
0312 
0313 #define ttm_prime_object_kfree(__obj, __prime)      \
0314     kfree_rcu(__obj, __prime.base.rhead)
0315 
0316 struct ttm_base_object *
0317 ttm_base_object_noref_lookup(struct ttm_object_file *tfile, uint32_t key);
0318 
0319 /**
0320  * ttm_base_object_noref_release - release a base object pointer looked up
0321  * without reference
0322  *
0323  * Releases a base object pointer looked up with ttm_base_object_noref_lookup().
0324  */
0325 static inline void ttm_base_object_noref_release(void)
0326 {
0327     __acquire(RCU);
0328     rcu_read_unlock();
0329 }
0330 #endif