mirror of
https://gitlab.freedesktop.org/mesa/drm.git
synced 2025-12-24 21:50:20 +01:00
Fix panic on module unload and a panic when exiting dri clients sometimes.
Allow module unloading when not in use. Mostly from FreeBSD CVS.
This commit is contained in:
parent
5c8bf3796e
commit
a043b05c90
4 changed files with 108 additions and 120 deletions
|
|
@ -851,24 +851,18 @@ int DRM(open)(dev_t kdev, int flags, int fmt, DRM_STRUCTPROC *p)
|
|||
|
||||
DRM_DEBUG( "open_count = %d\n", dev->open_count );
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
device_busy(dev->device);
|
||||
#endif
|
||||
retcode = DRM(open_helper)(kdev, flags, fmt, p, dev);
|
||||
|
||||
if ( !retcode ) {
|
||||
atomic_inc( &dev->counts[_DRM_STAT_OPENS] );
|
||||
DRM_SPINLOCK( &dev->count_lock );
|
||||
if ( !dev->open_count++ ) {
|
||||
#ifdef __FreeBSD__
|
||||
device_busy(dev->device);
|
||||
#endif
|
||||
if ( !dev->open_count++ )
|
||||
retcode = DRM(setup)( dev );
|
||||
DRM_SPINUNLOCK( &dev->count_lock );
|
||||
return retcode;
|
||||
}
|
||||
DRM_SPINUNLOCK( &dev->count_lock );
|
||||
}
|
||||
#ifdef __FreeBSD__
|
||||
device_unbusy(dev->device);
|
||||
#endif
|
||||
|
||||
return retcode;
|
||||
}
|
||||
|
|
@ -923,7 +917,7 @@ int DRM(close)(dev_t kdev, int flags, int fmt, DRM_STRUCTPROC *p)
|
|||
for (;;) {
|
||||
if ( !dev->lock.hw_lock ) {
|
||||
/* Device has been unregistered */
|
||||
retcode = EINTR;
|
||||
retcode = DRM_ERR(EINTR);
|
||||
break;
|
||||
}
|
||||
if ( DRM(lock_take)( &dev->lock.hw_lock->lock,
|
||||
|
|
@ -980,6 +974,9 @@ int DRM(close)(dev_t kdev, int flags, int fmt, DRM_STRUCTPROC *p)
|
|||
|
||||
atomic_inc( &dev->counts[_DRM_STAT_CLOSES] );
|
||||
DRM_SPINLOCK( &dev->count_lock );
|
||||
#ifdef __FreeBSD__
|
||||
device_unbusy(dev->device);
|
||||
#endif
|
||||
if ( !--dev->open_count ) {
|
||||
if ( atomic_read( &dev->ioctl_count ) || dev->blocked ) {
|
||||
DRM_ERROR( "Device busy: %ld %d\n",
|
||||
|
|
@ -992,11 +989,8 @@ int DRM(close)(dev_t kdev, int flags, int fmt, DRM_STRUCTPROC *p)
|
|||
return DRM(takedown)( dev );
|
||||
}
|
||||
DRM_SPINUNLOCK( &dev->count_lock );
|
||||
#ifdef __FreeBSD__
|
||||
device_unbusy(dev->device);
|
||||
#endif
|
||||
|
||||
return DRM_ERR(retcode);
|
||||
return retcode;
|
||||
}
|
||||
|
||||
/* DRM(ioctl) is called whenever a process performs an ioctl on /dev/drm.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,10 @@
|
|||
/*
|
||||
* $FreeBSD: src/sys/dev/drm/drm_sysctl.h,v 1.1 2002/04/27 20:47:57 anholt Exp $
|
||||
*/
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
SYSCTL_NODE(_hw, OID_AUTO, dri, CTLFLAG_RW, 0, "DRI Graphics");
|
||||
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
static int DRM(name_info)DRM_SYSCTL_HANDLER_ARGS;
|
||||
static int DRM(vm_info)DRM_SYSCTL_HANDLER_ARGS;
|
||||
|
|
@ -34,8 +38,7 @@ struct DRM(sysctl_list) {
|
|||
#define DRM_SYSCTL_ENTRIES (sizeof(DRM(sysctl_list))/sizeof(DRM(sysctl_list)[0]))
|
||||
|
||||
struct drm_sysctl_info {
|
||||
struct sysctl_oid oids[DRM_SYSCTL_ENTRIES + 1];
|
||||
struct sysctl_oid_list list;
|
||||
struct sysctl_ctx_list ctx;
|
||||
char name[2];
|
||||
};
|
||||
|
||||
|
|
@ -43,65 +46,62 @@ int DRM(sysctl_init)(drm_device_t *dev)
|
|||
{
|
||||
struct drm_sysctl_info *info;
|
||||
struct sysctl_oid *oid;
|
||||
struct sysctl_oid *top;
|
||||
struct sysctl_oid *top, *drioid;
|
||||
int i;
|
||||
|
||||
/* Find the next free slot under hw.graphics */
|
||||
info = DRM(alloc)(sizeof *info, DRM_MEM_DRIVER);
|
||||
if ( !info )
|
||||
return 1;
|
||||
bzero(info, sizeof *info);
|
||||
dev->sysctl = info;
|
||||
|
||||
/* Add the sysctl node for DRI if it doesn't already exist */
|
||||
drioid = SYSCTL_ADD_NODE( &info->ctx, &sysctl__hw_children, OID_AUTO, "dri", CTLFLAG_RW, NULL, "DRI Graphics");
|
||||
if (!drioid)
|
||||
return 1;
|
||||
|
||||
/* Find the next free slot under hw.dri */
|
||||
i = 0;
|
||||
SLIST_FOREACH(oid, &sysctl__hw_dri_children, oid_link) {
|
||||
SLIST_FOREACH(oid, SYSCTL_CHILDREN(drioid), oid_link) {
|
||||
if (i <= oid->oid_arg2)
|
||||
i = oid->oid_arg2 + 1;
|
||||
}
|
||||
if (i>9)
|
||||
return 1;
|
||||
|
||||
info = DRM(alloc)(sizeof *info, DRM_MEM_DRIVER);
|
||||
dev->sysctl = info;
|
||||
|
||||
/* Construct the node under hw.graphics */
|
||||
/* Add the hw.dri.x for our device */
|
||||
info->name[0] = '0' + i;
|
||||
info->name[1] = 0;
|
||||
oid = &info->oids[DRM_SYSCTL_ENTRIES];
|
||||
bzero(oid, sizeof(*oid));
|
||||
oid->oid_parent = &sysctl__hw_dri_children;
|
||||
oid->oid_number = OID_AUTO;
|
||||
oid->oid_kind = CTLTYPE_NODE | CTLFLAG_RW;
|
||||
oid->oid_arg1 = &info->list;
|
||||
oid->oid_arg2 = i;
|
||||
oid->oid_name = info->name;
|
||||
oid->oid_handler = 0;
|
||||
oid->oid_fmt = "N";
|
||||
SLIST_INIT(&info->list);
|
||||
sysctl_register_oid(oid);
|
||||
top = oid;
|
||||
|
||||
top = SYSCTL_ADD_NODE( &info->ctx, SYSCTL_CHILDREN(drioid), OID_AUTO, info->name, CTLFLAG_RW, NULL, NULL);
|
||||
if (!top)
|
||||
return 1;
|
||||
|
||||
for (i = 0; i < DRM_SYSCTL_ENTRIES; i++) {
|
||||
oid = &info->oids[i];
|
||||
bzero(oid, sizeof(*oid));
|
||||
oid->oid_parent = top->oid_arg1;
|
||||
oid->oid_number = OID_AUTO;
|
||||
oid->oid_kind = CTLTYPE_INT | CTLFLAG_RD;
|
||||
oid->oid_arg1 = dev;
|
||||
oid->oid_arg2 = 0;
|
||||
oid->oid_name = DRM(sysctl_list)[i].name;
|
||||
oid->oid_handler = DRM(sysctl_list[)i].f;
|
||||
oid->oid_fmt = "A";
|
||||
sysctl_register_oid(oid);
|
||||
oid = sysctl_add_oid( &info->ctx,
|
||||
SYSCTL_CHILDREN(top),
|
||||
OID_AUTO,
|
||||
DRM(sysctl_list)[i].name,
|
||||
CTLTYPE_INT | CTLFLAG_RD,
|
||||
dev,
|
||||
0,
|
||||
DRM(sysctl_list)[i].f,
|
||||
"A",
|
||||
NULL);
|
||||
if (!oid)
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int DRM(sysctl_cleanup)(drm_device_t *dev)
|
||||
{
|
||||
int i;
|
||||
|
||||
DRM_DEBUG("dev->sysctl=%p\n", dev->sysctl);
|
||||
for (i = 0; i < DRM_SYSCTL_ENTRIES + 1; i++)
|
||||
sysctl_unregister_oid(&dev->sysctl->oids[i]);
|
||||
int error;
|
||||
error = sysctl_ctx_free( &dev->sysctl->ctx );
|
||||
|
||||
DRM(free)(dev->sysctl, sizeof *dev->sysctl, DRM_MEM_DRIVER);
|
||||
dev->sysctl = NULL;
|
||||
|
||||
return 0;
|
||||
return error;
|
||||
}
|
||||
|
||||
static int DRM(name_info)DRM_SYSCTL_HANDLER_ARGS
|
||||
|
|
@ -191,8 +191,8 @@ static int DRM(_queues_info)DRM_SYSCTL_HANDLER_ARGS
|
|||
q = dev->queuelist[i];
|
||||
atomic_inc(&q->use_count);
|
||||
DRM_SYSCTL_PRINT_RET(atomic_dec(&q->use_count),
|
||||
"%5d/0x%03x %5d %5d"
|
||||
" %5d/%c%c/%c%c%c %5d %10d %10d %10d\n",
|
||||
"%5d/0x%03x %5ld %5ld"
|
||||
" %5ld/%c%c/%c%c%c %5d %10ld %10ld %10ld\n",
|
||||
i,
|
||||
q->flags,
|
||||
atomic_read(&q->use_count),
|
||||
|
|
@ -240,7 +240,7 @@ static int DRM(_bufs_info) DRM_SYSCTL_HANDLER_ARGS
|
|||
DRM_SYSCTL_PRINT(" o size count free segs pages kB\n\n");
|
||||
for (i = 0; i <= DRM_MAX_ORDER; i++) {
|
||||
if (dma->bufs[i].buf_count)
|
||||
DRM_SYSCTL_PRINT("%2d %8d %5d %5d %5d %5d %5d\n",
|
||||
DRM_SYSCTL_PRINT("%2d %8d %5d %5ld %5d %5d %5d\n",
|
||||
i,
|
||||
dma->bufs[i].buf_size,
|
||||
dma->bufs[i].buf_count,
|
||||
|
|
|
|||
|
|
@ -851,24 +851,18 @@ int DRM(open)(dev_t kdev, int flags, int fmt, DRM_STRUCTPROC *p)
|
|||
|
||||
DRM_DEBUG( "open_count = %d\n", dev->open_count );
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
device_busy(dev->device);
|
||||
#endif
|
||||
retcode = DRM(open_helper)(kdev, flags, fmt, p, dev);
|
||||
|
||||
if ( !retcode ) {
|
||||
atomic_inc( &dev->counts[_DRM_STAT_OPENS] );
|
||||
DRM_SPINLOCK( &dev->count_lock );
|
||||
if ( !dev->open_count++ ) {
|
||||
#ifdef __FreeBSD__
|
||||
device_busy(dev->device);
|
||||
#endif
|
||||
if ( !dev->open_count++ )
|
||||
retcode = DRM(setup)( dev );
|
||||
DRM_SPINUNLOCK( &dev->count_lock );
|
||||
return retcode;
|
||||
}
|
||||
DRM_SPINUNLOCK( &dev->count_lock );
|
||||
}
|
||||
#ifdef __FreeBSD__
|
||||
device_unbusy(dev->device);
|
||||
#endif
|
||||
|
||||
return retcode;
|
||||
}
|
||||
|
|
@ -923,7 +917,7 @@ int DRM(close)(dev_t kdev, int flags, int fmt, DRM_STRUCTPROC *p)
|
|||
for (;;) {
|
||||
if ( !dev->lock.hw_lock ) {
|
||||
/* Device has been unregistered */
|
||||
retcode = EINTR;
|
||||
retcode = DRM_ERR(EINTR);
|
||||
break;
|
||||
}
|
||||
if ( DRM(lock_take)( &dev->lock.hw_lock->lock,
|
||||
|
|
@ -980,6 +974,9 @@ int DRM(close)(dev_t kdev, int flags, int fmt, DRM_STRUCTPROC *p)
|
|||
|
||||
atomic_inc( &dev->counts[_DRM_STAT_CLOSES] );
|
||||
DRM_SPINLOCK( &dev->count_lock );
|
||||
#ifdef __FreeBSD__
|
||||
device_unbusy(dev->device);
|
||||
#endif
|
||||
if ( !--dev->open_count ) {
|
||||
if ( atomic_read( &dev->ioctl_count ) || dev->blocked ) {
|
||||
DRM_ERROR( "Device busy: %ld %d\n",
|
||||
|
|
@ -992,11 +989,8 @@ int DRM(close)(dev_t kdev, int flags, int fmt, DRM_STRUCTPROC *p)
|
|||
return DRM(takedown)( dev );
|
||||
}
|
||||
DRM_SPINUNLOCK( &dev->count_lock );
|
||||
#ifdef __FreeBSD__
|
||||
device_unbusy(dev->device);
|
||||
#endif
|
||||
|
||||
return DRM_ERR(retcode);
|
||||
return retcode;
|
||||
}
|
||||
|
||||
/* DRM(ioctl) is called whenever a process performs an ioctl on /dev/drm.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,10 @@
|
|||
/*
|
||||
* $FreeBSD: src/sys/dev/drm/drm_sysctl.h,v 1.1 2002/04/27 20:47:57 anholt Exp $
|
||||
*/
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
SYSCTL_NODE(_hw, OID_AUTO, dri, CTLFLAG_RW, 0, "DRI Graphics");
|
||||
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
static int DRM(name_info)DRM_SYSCTL_HANDLER_ARGS;
|
||||
static int DRM(vm_info)DRM_SYSCTL_HANDLER_ARGS;
|
||||
|
|
@ -34,8 +38,7 @@ struct DRM(sysctl_list) {
|
|||
#define DRM_SYSCTL_ENTRIES (sizeof(DRM(sysctl_list))/sizeof(DRM(sysctl_list)[0]))
|
||||
|
||||
struct drm_sysctl_info {
|
||||
struct sysctl_oid oids[DRM_SYSCTL_ENTRIES + 1];
|
||||
struct sysctl_oid_list list;
|
||||
struct sysctl_ctx_list ctx;
|
||||
char name[2];
|
||||
};
|
||||
|
||||
|
|
@ -43,65 +46,62 @@ int DRM(sysctl_init)(drm_device_t *dev)
|
|||
{
|
||||
struct drm_sysctl_info *info;
|
||||
struct sysctl_oid *oid;
|
||||
struct sysctl_oid *top;
|
||||
struct sysctl_oid *top, *drioid;
|
||||
int i;
|
||||
|
||||
/* Find the next free slot under hw.graphics */
|
||||
info = DRM(alloc)(sizeof *info, DRM_MEM_DRIVER);
|
||||
if ( !info )
|
||||
return 1;
|
||||
bzero(info, sizeof *info);
|
||||
dev->sysctl = info;
|
||||
|
||||
/* Add the sysctl node for DRI if it doesn't already exist */
|
||||
drioid = SYSCTL_ADD_NODE( &info->ctx, &sysctl__hw_children, OID_AUTO, "dri", CTLFLAG_RW, NULL, "DRI Graphics");
|
||||
if (!drioid)
|
||||
return 1;
|
||||
|
||||
/* Find the next free slot under hw.dri */
|
||||
i = 0;
|
||||
SLIST_FOREACH(oid, &sysctl__hw_dri_children, oid_link) {
|
||||
SLIST_FOREACH(oid, SYSCTL_CHILDREN(drioid), oid_link) {
|
||||
if (i <= oid->oid_arg2)
|
||||
i = oid->oid_arg2 + 1;
|
||||
}
|
||||
if (i>9)
|
||||
return 1;
|
||||
|
||||
info = DRM(alloc)(sizeof *info, DRM_MEM_DRIVER);
|
||||
dev->sysctl = info;
|
||||
|
||||
/* Construct the node under hw.graphics */
|
||||
/* Add the hw.dri.x for our device */
|
||||
info->name[0] = '0' + i;
|
||||
info->name[1] = 0;
|
||||
oid = &info->oids[DRM_SYSCTL_ENTRIES];
|
||||
bzero(oid, sizeof(*oid));
|
||||
oid->oid_parent = &sysctl__hw_dri_children;
|
||||
oid->oid_number = OID_AUTO;
|
||||
oid->oid_kind = CTLTYPE_NODE | CTLFLAG_RW;
|
||||
oid->oid_arg1 = &info->list;
|
||||
oid->oid_arg2 = i;
|
||||
oid->oid_name = info->name;
|
||||
oid->oid_handler = 0;
|
||||
oid->oid_fmt = "N";
|
||||
SLIST_INIT(&info->list);
|
||||
sysctl_register_oid(oid);
|
||||
top = oid;
|
||||
|
||||
top = SYSCTL_ADD_NODE( &info->ctx, SYSCTL_CHILDREN(drioid), OID_AUTO, info->name, CTLFLAG_RW, NULL, NULL);
|
||||
if (!top)
|
||||
return 1;
|
||||
|
||||
for (i = 0; i < DRM_SYSCTL_ENTRIES; i++) {
|
||||
oid = &info->oids[i];
|
||||
bzero(oid, sizeof(*oid));
|
||||
oid->oid_parent = top->oid_arg1;
|
||||
oid->oid_number = OID_AUTO;
|
||||
oid->oid_kind = CTLTYPE_INT | CTLFLAG_RD;
|
||||
oid->oid_arg1 = dev;
|
||||
oid->oid_arg2 = 0;
|
||||
oid->oid_name = DRM(sysctl_list)[i].name;
|
||||
oid->oid_handler = DRM(sysctl_list[)i].f;
|
||||
oid->oid_fmt = "A";
|
||||
sysctl_register_oid(oid);
|
||||
oid = sysctl_add_oid( &info->ctx,
|
||||
SYSCTL_CHILDREN(top),
|
||||
OID_AUTO,
|
||||
DRM(sysctl_list)[i].name,
|
||||
CTLTYPE_INT | CTLFLAG_RD,
|
||||
dev,
|
||||
0,
|
||||
DRM(sysctl_list)[i].f,
|
||||
"A",
|
||||
NULL);
|
||||
if (!oid)
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int DRM(sysctl_cleanup)(drm_device_t *dev)
|
||||
{
|
||||
int i;
|
||||
|
||||
DRM_DEBUG("dev->sysctl=%p\n", dev->sysctl);
|
||||
for (i = 0; i < DRM_SYSCTL_ENTRIES + 1; i++)
|
||||
sysctl_unregister_oid(&dev->sysctl->oids[i]);
|
||||
int error;
|
||||
error = sysctl_ctx_free( &dev->sysctl->ctx );
|
||||
|
||||
DRM(free)(dev->sysctl, sizeof *dev->sysctl, DRM_MEM_DRIVER);
|
||||
dev->sysctl = NULL;
|
||||
|
||||
return 0;
|
||||
return error;
|
||||
}
|
||||
|
||||
static int DRM(name_info)DRM_SYSCTL_HANDLER_ARGS
|
||||
|
|
@ -191,8 +191,8 @@ static int DRM(_queues_info)DRM_SYSCTL_HANDLER_ARGS
|
|||
q = dev->queuelist[i];
|
||||
atomic_inc(&q->use_count);
|
||||
DRM_SYSCTL_PRINT_RET(atomic_dec(&q->use_count),
|
||||
"%5d/0x%03x %5d %5d"
|
||||
" %5d/%c%c/%c%c%c %5d %10d %10d %10d\n",
|
||||
"%5d/0x%03x %5ld %5ld"
|
||||
" %5ld/%c%c/%c%c%c %5d %10ld %10ld %10ld\n",
|
||||
i,
|
||||
q->flags,
|
||||
atomic_read(&q->use_count),
|
||||
|
|
@ -240,7 +240,7 @@ static int DRM(_bufs_info) DRM_SYSCTL_HANDLER_ARGS
|
|||
DRM_SYSCTL_PRINT(" o size count free segs pages kB\n\n");
|
||||
for (i = 0; i <= DRM_MAX_ORDER; i++) {
|
||||
if (dma->bufs[i].buf_count)
|
||||
DRM_SYSCTL_PRINT("%2d %8d %5d %5d %5d %5d %5d\n",
|
||||
DRM_SYSCTL_PRINT("%2d %8d %5d %5ld %5d %5d %5d\n",
|
||||
i,
|
||||
dma->bufs[i].buf_size,
|
||||
dma->bufs[i].buf_count,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue