drm_ctx_dtor.patch Submitted by: Erdi Chen
parent
213247a441
commit
82157579b5
|
@ -158,6 +158,7 @@
|
||||||
#define DRM_MEM_CTXBITMAP 18
|
#define DRM_MEM_CTXBITMAP 18
|
||||||
#define DRM_MEM_STUB 19
|
#define DRM_MEM_STUB 19
|
||||||
#define DRM_MEM_SGLISTS 20
|
#define DRM_MEM_SGLISTS 20
|
||||||
|
#define DRM_MEM_CTXLIST 21
|
||||||
|
|
||||||
#define DRM_MAX_CTXBITMAP (PAGE_SIZE * 8)
|
#define DRM_MAX_CTXBITMAP (PAGE_SIZE * 8)
|
||||||
|
|
||||||
|
@ -651,6 +652,15 @@ typedef struct drm_map_list {
|
||||||
|
|
||||||
typedef drm_map_t drm_local_map_t;
|
typedef drm_map_t drm_local_map_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Context handle list
|
||||||
|
*/
|
||||||
|
typedef struct drm_ctx_list {
|
||||||
|
struct list_head head; /**< list head */
|
||||||
|
drm_context_t handle; /**< context handle */
|
||||||
|
drm_file_t *tag; /**< associated fd private data */
|
||||||
|
} drm_ctx_list_t;
|
||||||
|
|
||||||
#if __HAVE_VBL_IRQ
|
#if __HAVE_VBL_IRQ
|
||||||
|
|
||||||
typedef struct drm_vbl_sig {
|
typedef struct drm_vbl_sig {
|
||||||
|
@ -711,6 +721,12 @@ typedef struct drm_device {
|
||||||
drm_map_list_t *maplist; /**< Linked list of regions */
|
drm_map_list_t *maplist; /**< Linked list of regions */
|
||||||
int map_count; /**< Number of mappable regions */
|
int map_count; /**< Number of mappable regions */
|
||||||
|
|
||||||
|
/** \name Context handle management */
|
||||||
|
/*@{*/
|
||||||
|
drm_ctx_list_t *ctxlist; /**< Linked list of context handles */
|
||||||
|
int ctx_count; /**< Number of context handles */
|
||||||
|
struct semaphore ctxlist_sem; /**< For ctxlist */
|
||||||
|
|
||||||
drm_map_t **context_sareas; /**< per-context SAREA's */
|
drm_map_t **context_sareas; /**< per-context SAREA's */
|
||||||
int max_context;
|
int max_context;
|
||||||
|
|
||||||
|
|
|
@ -402,6 +402,7 @@ int DRM(addctx)( struct inode *inode, struct file *filp,
|
||||||
{
|
{
|
||||||
drm_file_t *priv = filp->private_data;
|
drm_file_t *priv = filp->private_data;
|
||||||
drm_device_t *dev = priv->dev;
|
drm_device_t *dev = priv->dev;
|
||||||
|
drm_ctx_list_t * ctx_entry;
|
||||||
drm_ctx_t ctx;
|
drm_ctx_t ctx;
|
||||||
|
|
||||||
if ( copy_from_user( &ctx, (drm_ctx_t *)arg, sizeof(ctx) ) )
|
if ( copy_from_user( &ctx, (drm_ctx_t *)arg, sizeof(ctx) ) )
|
||||||
|
@ -422,6 +423,20 @@ int DRM(addctx)( struct inode *inode, struct file *filp,
|
||||||
if ( ctx.handle != DRM_KERNEL_CONTEXT )
|
if ( ctx.handle != DRM_KERNEL_CONTEXT )
|
||||||
DRIVER_CTX_CTOR(ctx.handle); /* XXX: also pass dev ? */
|
DRIVER_CTX_CTOR(ctx.handle); /* XXX: also pass dev ? */
|
||||||
#endif
|
#endif
|
||||||
|
ctx_entry = DRM(alloc)( sizeof(*ctx_entry), DRM_MEM_CTXLIST );
|
||||||
|
if ( !ctx_entry ) {
|
||||||
|
DRM_DEBUG("out of memory\n");
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
INIT_LIST_HEAD( &ctx_entry->head );
|
||||||
|
ctx_entry->handle = ctx.handle;
|
||||||
|
ctx_entry->tag = priv;
|
||||||
|
|
||||||
|
down( &dev->ctxlist_sem );
|
||||||
|
list_add( &ctx_entry->head, &dev->ctxlist->head );
|
||||||
|
++dev->ctx_count;
|
||||||
|
up( &dev->ctxlist_sem );
|
||||||
|
|
||||||
if ( copy_to_user( (drm_ctx_t *)arg, &ctx, sizeof(ctx) ) )
|
if ( copy_to_user( (drm_ctx_t *)arg, &ctx, sizeof(ctx) ) )
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
@ -544,6 +559,20 @@ int DRM(rmctx)( struct inode *inode, struct file *filp,
|
||||||
DRM(ctxbitmap_free)( dev, ctx.handle );
|
DRM(ctxbitmap_free)( dev, ctx.handle );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
down( &dev->ctxlist_sem );
|
||||||
|
if ( !list_empty( &dev->ctxlist->head ) ) {
|
||||||
|
drm_ctx_list_t *pos, *n;
|
||||||
|
|
||||||
|
list_for_each_entry_safe( pos, n, &dev->ctxlist->head, head ) {
|
||||||
|
if ( pos->handle == ctx.handle ) {
|
||||||
|
list_del( &pos->head );
|
||||||
|
DRM(free)( pos, sizeof(*pos), DRM_MEM_CTXLIST );
|
||||||
|
--dev->ctx_count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
up( &dev->ctxlist_sem );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -329,6 +329,12 @@ static int DRM(setup)( drm_device_t *dev )
|
||||||
memset(dev->maplist, 0, sizeof(*dev->maplist));
|
memset(dev->maplist, 0, sizeof(*dev->maplist));
|
||||||
INIT_LIST_HEAD(&dev->maplist->head);
|
INIT_LIST_HEAD(&dev->maplist->head);
|
||||||
|
|
||||||
|
dev->ctxlist = DRM(alloc)(sizeof(*dev->ctxlist),
|
||||||
|
DRM_MEM_CTXLIST);
|
||||||
|
if(dev->ctxlist == NULL) return -ENOMEM;
|
||||||
|
memset(dev->ctxlist, 0, sizeof(*dev->ctxlist));
|
||||||
|
INIT_LIST_HEAD(&dev->ctxlist->head);
|
||||||
|
|
||||||
dev->vmalist = NULL;
|
dev->vmalist = NULL;
|
||||||
dev->sigdata.lock = dev->lock.hw_lock = NULL;
|
dev->sigdata.lock = dev->lock.hw_lock = NULL;
|
||||||
init_waitqueue_head( &dev->lock.lock_queue );
|
init_waitqueue_head( &dev->lock.lock_queue );
|
||||||
|
@ -567,6 +573,7 @@ static int DRM(probe)(struct pci_dev *pdev)
|
||||||
dev->count_lock = SPIN_LOCK_UNLOCKED;
|
dev->count_lock = SPIN_LOCK_UNLOCKED;
|
||||||
init_timer( &dev->timer );
|
init_timer( &dev->timer );
|
||||||
sema_init( &dev->struct_sem, 1 );
|
sema_init( &dev->struct_sem, 1 );
|
||||||
|
sema_init( &dev->ctxlist_sem, 1 );
|
||||||
|
|
||||||
if ((dev->minor = DRM(stub_register)(DRIVER_NAME, &DRM(fops),dev)) < 0)
|
if ((dev->minor = DRM(stub_register)(DRIVER_NAME, &DRM(fops),dev)) < 0)
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
|
@ -896,6 +903,25 @@ int DRM(release)( struct inode *inode, struct file *filp )
|
||||||
|
|
||||||
DRM(fasync)( -1, filp, 0 );
|
DRM(fasync)( -1, filp, 0 );
|
||||||
|
|
||||||
|
down( &dev->ctxlist_sem );
|
||||||
|
if ( !list_empty( &dev->ctxlist->head ) ) {
|
||||||
|
drm_ctx_list_t *pos, *n;
|
||||||
|
|
||||||
|
list_for_each_entry_safe( pos, n, &dev->ctxlist->head, head ) {
|
||||||
|
if ( pos->tag == priv &&
|
||||||
|
pos->handle != DRM_KERNEL_CONTEXT ) {
|
||||||
|
#ifdef DRIVER_CTX_DTOR
|
||||||
|
DRIVER_CTX_DTOR(pos->handle);
|
||||||
|
#endif
|
||||||
|
DRM(ctxbitmap_free)( dev, pos->handle );
|
||||||
|
|
||||||
|
list_del( &pos->head );
|
||||||
|
DRM(free)( pos, sizeof(*pos), DRM_MEM_CTXLIST );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
up( &dev->ctxlist_sem );
|
||||||
|
|
||||||
down( &dev->struct_sem );
|
down( &dev->struct_sem );
|
||||||
if ( priv->remove_auth_on_close == 1 ) {
|
if ( priv->remove_auth_on_close == 1 ) {
|
||||||
drm_file_t *temp = dev->file_first;
|
drm_file_t *temp = dev->file_first;
|
||||||
|
|
|
@ -68,6 +68,7 @@ static drm_mem_stats_t DRM(mem_stats)[] = {
|
||||||
[DRM_MEM_TOTALAGP] = { "totalagp" },
|
[DRM_MEM_TOTALAGP] = { "totalagp" },
|
||||||
[DRM_MEM_BOUNDAGP] = { "boundagp" },
|
[DRM_MEM_BOUNDAGP] = { "boundagp" },
|
||||||
[DRM_MEM_CTXBITMAP] = { "ctxbitmap"},
|
[DRM_MEM_CTXBITMAP] = { "ctxbitmap"},
|
||||||
|
[DRM_MEM_CTXLIST] = { "ctxlist" },
|
||||||
[DRM_MEM_STUB] = { "stub" },
|
[DRM_MEM_STUB] = { "stub" },
|
||||||
{ NULL, 0, } /* Last entry must be null */
|
{ NULL, 0, } /* Last entry must be null */
|
||||||
};
|
};
|
||||||
|
|
16
linux/drmP.h
16
linux/drmP.h
|
@ -158,6 +158,7 @@
|
||||||
#define DRM_MEM_CTXBITMAP 18
|
#define DRM_MEM_CTXBITMAP 18
|
||||||
#define DRM_MEM_STUB 19
|
#define DRM_MEM_STUB 19
|
||||||
#define DRM_MEM_SGLISTS 20
|
#define DRM_MEM_SGLISTS 20
|
||||||
|
#define DRM_MEM_CTXLIST 21
|
||||||
|
|
||||||
#define DRM_MAX_CTXBITMAP (PAGE_SIZE * 8)
|
#define DRM_MAX_CTXBITMAP (PAGE_SIZE * 8)
|
||||||
|
|
||||||
|
@ -651,6 +652,15 @@ typedef struct drm_map_list {
|
||||||
|
|
||||||
typedef drm_map_t drm_local_map_t;
|
typedef drm_map_t drm_local_map_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Context handle list
|
||||||
|
*/
|
||||||
|
typedef struct drm_ctx_list {
|
||||||
|
struct list_head head; /**< list head */
|
||||||
|
drm_context_t handle; /**< context handle */
|
||||||
|
drm_file_t *tag; /**< associated fd private data */
|
||||||
|
} drm_ctx_list_t;
|
||||||
|
|
||||||
#if __HAVE_VBL_IRQ
|
#if __HAVE_VBL_IRQ
|
||||||
|
|
||||||
typedef struct drm_vbl_sig {
|
typedef struct drm_vbl_sig {
|
||||||
|
@ -711,6 +721,12 @@ typedef struct drm_device {
|
||||||
drm_map_list_t *maplist; /**< Linked list of regions */
|
drm_map_list_t *maplist; /**< Linked list of regions */
|
||||||
int map_count; /**< Number of mappable regions */
|
int map_count; /**< Number of mappable regions */
|
||||||
|
|
||||||
|
/** \name Context handle management */
|
||||||
|
/*@{*/
|
||||||
|
drm_ctx_list_t *ctxlist; /**< Linked list of context handles */
|
||||||
|
int ctx_count; /**< Number of context handles */
|
||||||
|
struct semaphore ctxlist_sem; /**< For ctxlist */
|
||||||
|
|
||||||
drm_map_t **context_sareas; /**< per-context SAREA's */
|
drm_map_t **context_sareas; /**< per-context SAREA's */
|
||||||
int max_context;
|
int max_context;
|
||||||
|
|
||||||
|
|
|
@ -402,6 +402,7 @@ int DRM(addctx)( struct inode *inode, struct file *filp,
|
||||||
{
|
{
|
||||||
drm_file_t *priv = filp->private_data;
|
drm_file_t *priv = filp->private_data;
|
||||||
drm_device_t *dev = priv->dev;
|
drm_device_t *dev = priv->dev;
|
||||||
|
drm_ctx_list_t * ctx_entry;
|
||||||
drm_ctx_t ctx;
|
drm_ctx_t ctx;
|
||||||
|
|
||||||
if ( copy_from_user( &ctx, (drm_ctx_t *)arg, sizeof(ctx) ) )
|
if ( copy_from_user( &ctx, (drm_ctx_t *)arg, sizeof(ctx) ) )
|
||||||
|
@ -422,6 +423,20 @@ int DRM(addctx)( struct inode *inode, struct file *filp,
|
||||||
if ( ctx.handle != DRM_KERNEL_CONTEXT )
|
if ( ctx.handle != DRM_KERNEL_CONTEXT )
|
||||||
DRIVER_CTX_CTOR(ctx.handle); /* XXX: also pass dev ? */
|
DRIVER_CTX_CTOR(ctx.handle); /* XXX: also pass dev ? */
|
||||||
#endif
|
#endif
|
||||||
|
ctx_entry = DRM(alloc)( sizeof(*ctx_entry), DRM_MEM_CTXLIST );
|
||||||
|
if ( !ctx_entry ) {
|
||||||
|
DRM_DEBUG("out of memory\n");
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
INIT_LIST_HEAD( &ctx_entry->head );
|
||||||
|
ctx_entry->handle = ctx.handle;
|
||||||
|
ctx_entry->tag = priv;
|
||||||
|
|
||||||
|
down( &dev->ctxlist_sem );
|
||||||
|
list_add( &ctx_entry->head, &dev->ctxlist->head );
|
||||||
|
++dev->ctx_count;
|
||||||
|
up( &dev->ctxlist_sem );
|
||||||
|
|
||||||
if ( copy_to_user( (drm_ctx_t *)arg, &ctx, sizeof(ctx) ) )
|
if ( copy_to_user( (drm_ctx_t *)arg, &ctx, sizeof(ctx) ) )
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
@ -544,6 +559,20 @@ int DRM(rmctx)( struct inode *inode, struct file *filp,
|
||||||
DRM(ctxbitmap_free)( dev, ctx.handle );
|
DRM(ctxbitmap_free)( dev, ctx.handle );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
down( &dev->ctxlist_sem );
|
||||||
|
if ( !list_empty( &dev->ctxlist->head ) ) {
|
||||||
|
drm_ctx_list_t *pos, *n;
|
||||||
|
|
||||||
|
list_for_each_entry_safe( pos, n, &dev->ctxlist->head, head ) {
|
||||||
|
if ( pos->handle == ctx.handle ) {
|
||||||
|
list_del( &pos->head );
|
||||||
|
DRM(free)( pos, sizeof(*pos), DRM_MEM_CTXLIST );
|
||||||
|
--dev->ctx_count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
up( &dev->ctxlist_sem );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -329,6 +329,12 @@ static int DRM(setup)( drm_device_t *dev )
|
||||||
memset(dev->maplist, 0, sizeof(*dev->maplist));
|
memset(dev->maplist, 0, sizeof(*dev->maplist));
|
||||||
INIT_LIST_HEAD(&dev->maplist->head);
|
INIT_LIST_HEAD(&dev->maplist->head);
|
||||||
|
|
||||||
|
dev->ctxlist = DRM(alloc)(sizeof(*dev->ctxlist),
|
||||||
|
DRM_MEM_CTXLIST);
|
||||||
|
if(dev->ctxlist == NULL) return -ENOMEM;
|
||||||
|
memset(dev->ctxlist, 0, sizeof(*dev->ctxlist));
|
||||||
|
INIT_LIST_HEAD(&dev->ctxlist->head);
|
||||||
|
|
||||||
dev->vmalist = NULL;
|
dev->vmalist = NULL;
|
||||||
dev->sigdata.lock = dev->lock.hw_lock = NULL;
|
dev->sigdata.lock = dev->lock.hw_lock = NULL;
|
||||||
init_waitqueue_head( &dev->lock.lock_queue );
|
init_waitqueue_head( &dev->lock.lock_queue );
|
||||||
|
@ -567,6 +573,7 @@ static int DRM(probe)(struct pci_dev *pdev)
|
||||||
dev->count_lock = SPIN_LOCK_UNLOCKED;
|
dev->count_lock = SPIN_LOCK_UNLOCKED;
|
||||||
init_timer( &dev->timer );
|
init_timer( &dev->timer );
|
||||||
sema_init( &dev->struct_sem, 1 );
|
sema_init( &dev->struct_sem, 1 );
|
||||||
|
sema_init( &dev->ctxlist_sem, 1 );
|
||||||
|
|
||||||
if ((dev->minor = DRM(stub_register)(DRIVER_NAME, &DRM(fops),dev)) < 0)
|
if ((dev->minor = DRM(stub_register)(DRIVER_NAME, &DRM(fops),dev)) < 0)
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
|
@ -896,6 +903,25 @@ int DRM(release)( struct inode *inode, struct file *filp )
|
||||||
|
|
||||||
DRM(fasync)( -1, filp, 0 );
|
DRM(fasync)( -1, filp, 0 );
|
||||||
|
|
||||||
|
down( &dev->ctxlist_sem );
|
||||||
|
if ( !list_empty( &dev->ctxlist->head ) ) {
|
||||||
|
drm_ctx_list_t *pos, *n;
|
||||||
|
|
||||||
|
list_for_each_entry_safe( pos, n, &dev->ctxlist->head, head ) {
|
||||||
|
if ( pos->tag == priv &&
|
||||||
|
pos->handle != DRM_KERNEL_CONTEXT ) {
|
||||||
|
#ifdef DRIVER_CTX_DTOR
|
||||||
|
DRIVER_CTX_DTOR(pos->handle);
|
||||||
|
#endif
|
||||||
|
DRM(ctxbitmap_free)( dev, pos->handle );
|
||||||
|
|
||||||
|
list_del( &pos->head );
|
||||||
|
DRM(free)( pos, sizeof(*pos), DRM_MEM_CTXLIST );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
up( &dev->ctxlist_sem );
|
||||||
|
|
||||||
down( &dev->struct_sem );
|
down( &dev->struct_sem );
|
||||||
if ( priv->remove_auth_on_close == 1 ) {
|
if ( priv->remove_auth_on_close == 1 ) {
|
||||||
drm_file_t *temp = dev->file_first;
|
drm_file_t *temp = dev->file_first;
|
||||||
|
|
|
@ -68,6 +68,7 @@ static drm_mem_stats_t DRM(mem_stats)[] = {
|
||||||
[DRM_MEM_TOTALAGP] = { "totalagp" },
|
[DRM_MEM_TOTALAGP] = { "totalagp" },
|
||||||
[DRM_MEM_BOUNDAGP] = { "boundagp" },
|
[DRM_MEM_BOUNDAGP] = { "boundagp" },
|
||||||
[DRM_MEM_CTXBITMAP] = { "ctxbitmap"},
|
[DRM_MEM_CTXBITMAP] = { "ctxbitmap"},
|
||||||
|
[DRM_MEM_CTXLIST] = { "ctxlist" },
|
||||||
[DRM_MEM_STUB] = { "stub" },
|
[DRM_MEM_STUB] = { "stub" },
|
||||||
{ NULL, 0, } /* Last entry must be null */
|
{ NULL, 0, } /* Last entry must be null */
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue