drm/prime: proper locking+refcounting for obj->dma_buf link
[deliverable/linux.git] / include / drm / drmP.h
index 3ecdde6274be019eecca6cd106344ae623b7d936..a95db49b3f9e0cb63584ce066162878332635128 100644 (file)
@@ -45,7 +45,6 @@
 #include <linux/kernel.h>
 #include <linux/miscdevice.h>
 #include <linux/fs.h>
-#include <linux/proc_fs.h>
 #include <linux/init.h>
 #include <linux/file.h>
 #include <linux/platform_device.h>
@@ -74,7 +73,6 @@
 #include <linux/idr.h>
 
 #define __OS_HAS_AGP (defined(CONFIG_AGP) || (defined(CONFIG_AGP_MODULE) && defined(MODULE)))
-#define __OS_HAS_MTRR (defined(CONFIG_MTRR))
 
 struct module;
 
@@ -139,16 +137,11 @@ int drm_err(const char *func, const char *format, ...);
 /* driver capabilities and requirements mask */
 #define DRIVER_USE_AGP     0x1
 #define DRIVER_REQUIRE_AGP 0x2
-#define DRIVER_USE_MTRR    0x4
 #define DRIVER_PCI_DMA     0x8
 #define DRIVER_SG          0x10
 #define DRIVER_HAVE_DMA    0x20
 #define DRIVER_HAVE_IRQ    0x40
 #define DRIVER_IRQ_SHARED  0x80
-#define DRIVER_IRQ_VBL     0x100
-#define DRIVER_DMA_QUEUE   0x200
-#define DRIVER_FB_DMA      0x400
-#define DRIVER_IRQ_VBL2    0x800
 #define DRIVER_GEM         0x1000
 #define DRIVER_MODESET     0x2000
 #define DRIVER_PRIME       0x4000
@@ -167,13 +160,7 @@ int drm_err(const char *func, const char *format, ...);
 #define DRM_MAGIC_HASH_ORDER  4  /**< Size of key hash table. Must be power of 2. */
 #define DRM_KERNEL_CONTEXT    0         /**< Change drm_resctx if changed */
 #define DRM_RESERVED_CONTEXTS 1         /**< Change drm_resctx if changed */
-#define DRM_LOOPING_LIMIT     5000000
-#define DRM_TIME_SLICE       (HZ/20)  /**< Time slice for GLXContexts */
-#define DRM_LOCK_SLICE       1 /**< Time slice for lock, in jiffies */
 
-#define DRM_FLAG_DEBUG   0x01
-
-#define DRM_MAX_CTXBITMAP (PAGE_SIZE * 8)
 #define DRM_MAP_HASH_OFFSET 0x10000000
 
 /*@}*/
@@ -262,9 +249,6 @@ int drm_err(const char *func, const char *format, ...);
 
 #define DRM_ARRAY_SIZE(x) ARRAY_SIZE(x)
 
-#define DRM_LEFTCOUNT(x) (((x)->rp + (x)->count - (x)->wp) % ((x)->count + 1))
-#define DRM_BUFCOUNT(x) ((x)->count - DRM_LEFTCOUNT(x))
-
 #define DRM_IF_VERSION(maj, min) (maj << 16 | min)
 
 /**
@@ -631,8 +615,16 @@ struct drm_gem_object {
        /** Reference count of this object */
        struct kref refcount;
 
-       /** Handle count of this object. Each handle also holds a reference */
-       atomic_t handle_count; /* number of handles on this object */
+       /**
+        * handle_count - gem file_priv handle count of this object
+        *
+        * Each handle also holds a reference. Note that when the handle_count
+        * drops to 0 any global names (e.g. the id in the flink namespace) will
+        * be cleared.
+        *
+        * Protected by dev->object_name_lock.
+        * */
+       unsigned handle_count;
 
        /** Related drm device */
        struct drm_device *dev;
@@ -675,10 +667,27 @@ struct drm_gem_object {
 
        void *driver_private;
 
-       /* dma buf exported from this GEM object */
-       struct dma_buf *export_dma_buf;
+       /**
+        * dma_buf - dma buf associated with this GEM object
+        *
+        * Pointer to the dma-buf associated with this gem object (either
+        * through importing or exporting). We break the resulting reference
+        * loop when the last gem handle for this object is released.
+        *
+        * Protected by obj->object_name_lock
+        */
+       struct dma_buf *dma_buf;
 
-       /* dma buf attachment backing this object */
+       /**
+        * import_attach - dma buf attachment backing this object
+        *
+        * Any foreign dma_buf imported as a gem object has this set to the
+        * attachment point for the device. This is invariant over the lifetime
+        * of a gem object.
+        *
+        * The driver's ->gem_free_object callback is responsible for cleaning
+        * up the dma_buf attachment and references acquired at import time.
+        */
        struct dma_buf_attachment *import_attach;
 };
 
@@ -883,8 +892,6 @@ struct drm_driver {
        void (*irq_preinstall) (struct drm_device *dev);
        int (*irq_postinstall) (struct drm_device *dev);
        void (*irq_uninstall) (struct drm_device *dev);
-       void (*set_version) (struct drm_device *dev,
-                            struct drm_set_version *sv);
 
        /* Master routines */
        int (*master_create)(struct drm_device *dev, struct drm_master *master);
@@ -1035,8 +1042,6 @@ struct drm_minor {
        struct device kdev;             /**< Linux device */
        struct drm_device *dev;
 
-       struct proc_dir_entry *proc_root;  /**< proc directory entry */
-       struct drm_info_node proc_nodes;
        struct dentry *debugfs_root;
 
        struct list_head debugfs_list;
@@ -1168,8 +1173,6 @@ struct drm_device {
 
        /*@} */
 
-       struct fasync_struct *buf_async;/**< Processes waiting for SIGIO */
-
        struct drm_agp_head *agp;       /**< AGP data */
 
        struct device *dev;             /**< Device structure */
@@ -1201,7 +1204,7 @@ struct drm_device {
 
        /** \name GEM information */
        /*@{ */
-       spinlock_t object_name_lock;
+       struct mutex object_name_lock;
        struct idr object_name_idr;
        /*@} */
        int switch_power_state;
@@ -1224,15 +1227,6 @@ static inline int drm_dev_to_irq(struct drm_device *dev)
        return dev->driver->bus->get_irq(dev);
 }
 
-#if __OS_HAS_MTRR
-static inline int drm_core_has_MTRR(struct drm_device *dev)
-{
-       return drm_core_check_feature(dev, DRIVER_USE_MTRR);
-}
-#else
-#define drm_core_has_MTRR(dev) (0)
-#endif
-
 static inline void drm_device_set_unplugged(struct drm_device *dev)
 {
        smp_wmb();
@@ -1266,7 +1260,6 @@ extern int drm_lastclose(struct drm_device *dev);
 extern struct mutex drm_global_mutex;
 extern int drm_open(struct inode *inode, struct file *filp);
 extern int drm_stub_open(struct inode *inode, struct file *filp);
-extern int drm_fasync(int fd, struct file *filp, int on);
 extern ssize_t drm_read(struct file *filp, char __user *buffer,
                        size_t count, loff_t *offset);
 extern int drm_release(struct inode *inode, struct file *filp);
@@ -1315,9 +1308,10 @@ extern int drm_newctx(struct drm_device *dev, void *data,
 extern int drm_rmctx(struct drm_device *dev, void *data,
                     struct drm_file *file_priv);
 
-extern int drm_ctxbitmap_init(struct drm_device *dev);
-extern void drm_ctxbitmap_cleanup(struct drm_device *dev);
-extern void drm_ctxbitmap_free(struct drm_device *dev, int ctx_handle);
+extern void drm_legacy_ctxbitmap_init(struct drm_device *dev);
+extern void drm_legacy_ctxbitmap_cleanup(struct drm_device *dev);
+extern void drm_legacy_ctxbitmap_release(struct drm_device *dev,
+                                        struct drm_file *file_priv);
 
 extern int drm_setsareactx(struct drm_device *dev, void *data,
                           struct drm_file *file_priv);
@@ -1374,10 +1368,12 @@ extern int drm_freebufs(struct drm_device *dev, void *data,
                        struct drm_file *file_priv);
 extern int drm_mapbufs(struct drm_device *dev, void *data,
                       struct drm_file *file_priv);
+extern int drm_dma_ioctl(struct drm_device *dev, void *data,
+                        struct drm_file *file_priv);
 
                                /* DMA support (drm_dma.h) */
-extern int drm_dma_setup(struct drm_device *dev);
-extern void drm_dma_takedown(struct drm_device *dev);
+extern int drm_legacy_dma_setup(struct drm_device *dev);
+extern void drm_legacy_dma_takedown(struct drm_device *dev);
 extern void drm_free_buffer(struct drm_device *dev, struct drm_buf * buf);
 extern void drm_core_reclaim_buffers(struct drm_device *dev,
                                     struct drm_file *filp);
@@ -1391,7 +1387,6 @@ extern int drm_irq_uninstall(struct drm_device *dev);
 extern int drm_vblank_init(struct drm_device *dev, int num_crtcs);
 extern int drm_wait_vblank(struct drm_device *dev, void *data,
                           struct drm_file *filp);
-extern int drm_vblank_wait(struct drm_device *dev, unsigned int *vbl_seq);
 extern u32 drm_vblank_count(struct drm_device *dev, int crtc);
 extern u32 drm_vblank_count_and_time(struct drm_device *dev, int crtc,
                                     struct timeval *vblanktime);
@@ -1455,17 +1450,12 @@ extern unsigned int drm_timestamp_precision;
 extern unsigned int drm_timestamp_monotonic;
 
 extern struct class *drm_class;
-extern struct proc_dir_entry *drm_proc_root;
 extern struct dentry *drm_debugfs_root;
 
 extern struct idr drm_minors_idr;
 
 extern struct drm_local_map *drm_getsarea(struct drm_device *dev);
 
-                               /* Proc support (drm_proc.h) */
-extern int drm_proc_init(struct drm_minor *minor, struct proc_dir_entry *root);
-extern int drm_proc_cleanup(struct drm_minor *minor, struct proc_dir_entry *root);
-
                                /* Debugfs support */
 #if defined(CONFIG_DEBUG_FS)
 extern int drm_debugfs_init(struct drm_minor *minor, int minor_id,
@@ -1495,6 +1485,7 @@ extern struct drm_gem_object *drm_gem_prime_import(struct drm_device *dev,
                struct dma_buf *dma_buf);
 extern int drm_gem_prime_fd_to_handle(struct drm_device *dev,
                struct drm_file *file_priv, int prime_fd, uint32_t *handle);
+extern void drm_gem_dmabuf_release(struct dma_buf *dma_buf);
 
 extern int drm_prime_handle_to_fd_ioctl(struct drm_device *dev, void *data,
                                        struct drm_file *file_priv);
@@ -1515,16 +1506,12 @@ void drm_prime_destroy_file_private(struct drm_prime_file_private *prime_fpriv);
 int drm_prime_lookup_buf_handle(struct drm_prime_file_private *prime_fpriv, struct dma_buf *dma_buf, uint32_t *handle);
 void drm_prime_remove_buf_handle(struct drm_prime_file_private *prime_fpriv, struct dma_buf *dma_buf);
 
-int drm_prime_add_dma_buf(struct drm_device *dev, struct drm_gem_object *obj);
-int drm_prime_lookup_obj(struct drm_device *dev, struct dma_buf *buf,
-                        struct drm_gem_object **obj);
-
 #if DRM_DEBUG_CODE
 extern int drm_vma_info(struct seq_file *m, void *data);
 #endif
 
                                /* Scatter Gather Support (drm_scatter.h) */
-extern void drm_sg_cleanup(struct drm_sg_mem * entry);
+extern void drm_legacy_sg_cleanup(struct drm_device *dev);
 extern int drm_sg_alloc(struct drm_device *dev, void *data,
                        struct drm_file *file_priv);
 extern int drm_sg_free(struct drm_device *dev, void *data,
@@ -1562,7 +1549,6 @@ int drm_gem_object_init(struct drm_device *dev,
                        struct drm_gem_object *obj, size_t size);
 void drm_gem_private_object_init(struct drm_device *dev,
                                 struct drm_gem_object *obj, size_t size);
-void drm_gem_object_handle_free(struct drm_gem_object *obj);
 void drm_gem_vm_open(struct vm_area_struct *vma);
 void drm_gem_vm_close(struct vm_area_struct *vma);
 int drm_gem_mmap_obj(struct drm_gem_object *obj, unsigned long obj_size,
@@ -1597,40 +1583,22 @@ drm_gem_object_unreference_unlocked(struct drm_gem_object *obj)
        }
 }
 
+int drm_gem_handle_create_tail(struct drm_file *file_priv,
+                              struct drm_gem_object *obj,
+                              u32 *handlep);
 int drm_gem_handle_create(struct drm_file *file_priv,
                          struct drm_gem_object *obj,
                          u32 *handlep);
 int drm_gem_handle_delete(struct drm_file *filp, u32 handle);
 
-static inline void
-drm_gem_object_handle_reference(struct drm_gem_object *obj)
-{
-       drm_gem_object_reference(obj);
-       atomic_inc(&obj->handle_count);
-}
-
-static inline void
-drm_gem_object_handle_unreference_unlocked(struct drm_gem_object *obj)
-{
-       if (obj == NULL)
-               return;
-
-       if (atomic_read(&obj->handle_count) == 0)
-               return;
-
-       /*
-       * Must bump handle count first as this may be the last
-       * ref, in which case the object would disappear before we
-       * checked for a name
-       */
-
-       if (atomic_dec_and_test(&obj->handle_count))
-               drm_gem_object_handle_free(obj);
-       drm_gem_object_unreference_unlocked(obj);
-}
 
 void drm_gem_free_mmap_offset(struct drm_gem_object *obj);
 int drm_gem_create_mmap_offset(struct drm_gem_object *obj);
+int drm_gem_create_mmap_offset_size(struct drm_gem_object *obj, size_t size);
+
+struct page **drm_gem_get_pages(struct drm_gem_object *obj, gfp_t gfpmask);
+void drm_gem_put_pages(struct drm_gem_object *obj, struct page **pages,
+               bool dirty, bool accessed);
 
 struct drm_gem_object *drm_gem_object_lookup(struct drm_device *dev,
                                             struct drm_file *filp,
@@ -1700,9 +1668,6 @@ extern int drm_pcie_get_speed_cap_mask(struct drm_device *dev, u32 *speed_mask);
 extern int drm_platform_init(struct drm_driver *driver, struct platform_device *platform_device);
 extern void drm_platform_exit(struct drm_driver *driver, struct platform_device *platform_device);
 
-extern int drm_get_platform_dev(struct platform_device *pdev,
-                               struct drm_driver *driver);
-
 /* returns true if currently okay to sleep */
 static __inline__ bool drm_can_sleep(void)
 {
This page took 0.035419 seconds and 5 git commands to generate.