From 7c1c2871a6a3a114853ec6836e9035ac1c0c7f7a Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 28 Nov 2008 14:22:24 +1000 Subject: drm: move to kref per-master structures. This is step one towards having multiple masters sharing a drm device in order to get fast-user-switching to work. It splits out the information associated with the drm master into a separate kref counted structure, and allocates this when a master opens the device node. It also allows the current master to abdicate (say while VT switched), and a new master to take over the hardware. It moves the Intel and radeon drivers to using the sarea from within the new master structures. Signed-off-by: Dave Airlie --- include/drm/drm.h | 3 +++ include/drm/drmP.h | 64 ++++++++++++++++++++++++++++++++++++------------- include/drm/drm_sarea.h | 6 ++--- 3 files changed, 54 insertions(+), 19 deletions(-) (limited to 'include/drm') diff --git a/include/drm/drm.h b/include/drm/drm.h index f46ba4b57da..3fb173c5af3 100644 --- a/include/drm/drm.h +++ b/include/drm/drm.h @@ -634,6 +634,9 @@ struct drm_gem_open { #define DRM_IOCTL_SET_SAREA_CTX DRM_IOW( 0x1c, struct drm_ctx_priv_map) #define DRM_IOCTL_GET_SAREA_CTX DRM_IOWR(0x1d, struct drm_ctx_priv_map) +#define DRM_IOCTL_SET_MASTER DRM_IO(0x1e) +#define DRM_IOCTL_DROP_MASTER DRM_IO(0x1f) + #define DRM_IOCTL_ADD_CTX DRM_IOWR(0x20, struct drm_ctx) #define DRM_IOCTL_RM_CTX DRM_IOWR(0x21, struct drm_ctx) #define DRM_IOCTL_MOD_CTX DRM_IOW( 0x22, struct drm_ctx) diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 08b8539e7b3..4c6e8298b42 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -238,11 +238,11 @@ struct drm_device; */ #define LOCK_TEST_WITH_RETURN( dev, file_priv ) \ do { \ - if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || \ - dev->lock.file_priv != file_priv ) { \ + if (!_DRM_LOCK_IS_HELD(file_priv->master->lock.hw_lock->lock) || \ + file_priv->master->lock.file_priv != file_priv) { \ DRM_ERROR( "%s called without lock held, held %d owner %p %p\n",\ - __func__, _DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ),\ - dev->lock.file_priv, file_priv ); \ + __func__, _DRM_LOCK_IS_HELD(file_priv->master->lock.hw_lock->lock),\ + file_priv->master->lock.file_priv, file_priv); \ return -EINVAL; \ } \ } while (0) @@ -379,21 +379,25 @@ struct drm_buf_entry { /** File private data */ struct drm_file { int authenticated; - int master; pid_t pid; uid_t uid; drm_magic_t magic; unsigned long ioctl_count; struct list_head lhead; struct drm_minor *minor; - int remove_auth_on_close; unsigned long lock_count; + /** Mapping of mm object handles to object pointers. */ struct idr object_idr; /** Lock for synchronization of access to object_idr. */ spinlock_t table_lock; + struct file *filp; void *driver_priv; + + int is_master; /* this file private is a master for a minor */ + struct drm_master *master; /* master this node is currently associated with + N.B. not always minor->master */ }; /** Wait queue */ @@ -523,6 +527,7 @@ struct drm_map_list { struct drm_hash_item hash; struct drm_map *map; /**< mapping */ uint64_t user_token; + struct drm_master *master; }; typedef struct drm_map drm_local_map_t; @@ -612,6 +617,30 @@ struct drm_gem_object { void *driver_private; }; +/* per-master structure */ +struct drm_master { + + struct kref refcount; /* refcount for this master */ + + struct list_head head; /**< each minor contains a list of masters */ + struct drm_minor *minor; /**< link back to minor we are a master for */ + + char *unique; /**< Unique identifier: e.g., busid */ + int unique_len; /**< Length of unique field */ + + int blocked; /**< Blocked due to VC switch? */ + + /** \name Authentication */ + /*@{ */ + struct drm_open_hash magiclist; + struct list_head magicfree; + /*@} */ + + struct drm_lock_data lock; /**< Information on hardware lock */ + + void *driver_priv; /**< Private structure for driver to use */ +}; + /** * DRM driver structure. This structure represent the common code for * a family of cards. There will one drm_device for each card present @@ -712,6 +741,10 @@ struct drm_driver { 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); + void (*master_destroy)(struct drm_device *dev, struct drm_master *master); + int (*proc_init)(struct drm_minor *minor); void (*proc_cleanup)(struct drm_minor *minor); @@ -754,6 +787,8 @@ struct drm_minor { struct device kdev; /**< Linux device */ struct drm_device *dev; struct proc_dir_entry *dev_root; /**< proc directory entry */ + struct drm_master *master; /* currently active master for this node */ + struct list_head master_list; }; /** @@ -762,13 +797,9 @@ struct drm_minor { */ struct drm_device { struct list_head driver_item; /**< list of devices per driver */ - char *unique; /**< Unique identifier: e.g., busid */ - int unique_len; /**< Length of unique field */ char *devname; /**< For /proc/interrupts */ int if_version; /**< Highest interface version set */ - int blocked; /**< Blocked due to VC switch? */ - /** \name Locks */ /*@{ */ spinlock_t count_lock; /**< For inuse, drm_device::open_count, drm_device::buf_use */ @@ -791,12 +822,7 @@ struct drm_device { atomic_t counts[15]; /*@} */ - /** \name Authentication */ - /*@{ */ struct list_head filelist; - struct drm_open_hash magiclist; /**< magic hash table */ - struct list_head magicfree; - /*@} */ /** \name Memory management */ /*@{ */ @@ -813,7 +839,6 @@ struct drm_device { struct idr ctx_idr; struct list_head vmalist; /**< List of vmas (for debugging) */ - struct drm_lock_data lock; /**< Information on hardware lock */ /*@} */ /** \name DMA queues (contexts) */ @@ -1192,6 +1217,13 @@ extern int drm_agp_unbind_memory(DRM_AGP_MEM * handle); extern void drm_agp_chipset_flush(struct drm_device *dev); /* Stub support (drm_stub.h) */ +extern int drm_setmaster_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); +extern int drm_dropmaster_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); +struct drm_master *drm_master_create(struct drm_minor *minor); +extern struct drm_master *drm_master_get(struct drm_master *master); +extern void drm_master_put(struct drm_master **master); extern int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent, struct drm_driver *driver); extern int drm_put_dev(struct drm_device *dev); diff --git a/include/drm/drm_sarea.h b/include/drm/drm_sarea.h index 480037331e4..ee5389d22c6 100644 --- a/include/drm/drm_sarea.h +++ b/include/drm/drm_sarea.h @@ -36,12 +36,12 @@ /* SAREA area needs to be at least a page */ #if defined(__alpha__) -#define SAREA_MAX 0x2000 +#define SAREA_MAX 0x2000U #elif defined(__ia64__) -#define SAREA_MAX 0x10000 /* 64kB */ +#define SAREA_MAX 0x10000U /* 64kB */ #else /* Intel 830M driver needs at least 8k SAREA */ -#define SAREA_MAX 0x2000 +#define SAREA_MAX 0x2000U #endif /** Maximum number of drawables in the SAREA */ -- cgit v1.2.3