Fix the possibility of sleeping with locks held in sysctls by copying the

data into temporary variables with the lock held then outputting to
    sysctls with the lock released. Rearranged a little extra code to aid
    this. Note that drm_memory_debug.h hasn't had this fix applied, but I
    consider that code to be just about dead anyway.
This commit is contained in:
Eric Anholt 2003-10-20 05:09:21 +00:00
parent 6b0424fdcd
commit ea7b4fdc22
9 changed files with 294 additions and 226 deletions

View file

@ -472,11 +472,6 @@ static int DRM(setup)( drm_device_t *dev )
dev->magiclist[i].tail = NULL;
}
dev->maplist = DRM(calloc)(1, sizeof(*dev->maplist), DRM_MEM_MAPS);
if (dev->maplist == NULL)
return DRM_ERR(ENOMEM);
TAILQ_INIT(dev->maplist);
dev->lock.hw_lock = NULL;
dev->lock.lock_queue = 0;
dev->irq = 0;
@ -591,8 +586,6 @@ static int DRM(takedown)( drm_device_t *dev )
DRM(free)(list, sizeof(*list), DRM_MEM_MAPS);
DRM(free)(map, sizeof(*map), DRM_MEM_MAPS);
}
DRM(free)(dev->maplist, sizeof(*dev->maplist), DRM_MEM_MAPS);
dev->maplist = NULL;
}
#if __HAVE_DMA
@ -647,6 +640,14 @@ static int DRM(init)( device_t nbdev )
#elif defined(__NetBSD__)
unit = minor(dev->device.dv_unit);
#endif
dev->maplist = DRM(calloc)(1, sizeof(*dev->maplist), DRM_MEM_MAPS);
if (dev->maplist == NULL) {
retcode = ENOMEM;
goto error;
}
TAILQ_INIT(dev->maplist);
dev->name = DRIVER_NAME;
DRM(mem_init)();
DRM(sysctl_init)(dev);
@ -680,6 +681,7 @@ static int DRM(init)( device_t nbdev )
goto error;
}
#endif
DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d\n",
DRIVER_NAME,
DRIVER_MAJOR,
@ -703,6 +705,7 @@ error:
mtx_destroy(&dev->dev_lock);
#endif
#endif
DRM(free)(dev->maplist, sizeof(*dev->maplist), DRM_MEM_MAPS);
return retcode;
}
@ -749,6 +752,7 @@ static void DRM(cleanup)(drm_device_t *dev)
#if defined(__FreeBSD__) && __FreeBSD_version >= 500000
mtx_destroy(&dev->dev_lock);
#endif
DRM(free)(dev->maplist, sizeof(*dev->maplist), DRM_MEM_MAPS);
}

View file

@ -413,14 +413,6 @@ find_first_zero_bit(volatile void *p, int max)
#define DRM_SYSCTL_HANDLER_ARGS SYSCTL_HANDLER_ARGS
#endif
#define DRM_SYSCTL_PRINT(fmt, arg...) \
do { \
snprintf(buf, sizeof(buf), fmt, ##arg); \
error = SYSCTL_OUT(req, buf, strlen(buf)); \
if (error) return error; \
} while (0)
#define DRM_FIND_MAP(dest, o) \
do { \
drm_map_list_entry_t *listentry; \

View file

@ -342,12 +342,6 @@ do { \
#define DRM_DEBUG(fmt, arg...) do { } while (0)
#endif
#define DRM_SYSCTL_PRINT(fmt, arg...) \
snprintf(buf, sizeof(buf), fmt, ##arg); \
error = SYSCTL_OUT(req, buf, strlen(buf)); \
if (error) return error;
#define DRM_FIND_MAP(dest, o) \
do { \
drm_map_list_entry_t *listentry; \

View file

@ -41,7 +41,9 @@ struct DRM(sysctl_list) {
#endif
{ "vm", DRM(vm_info) },
{ "clients", DRM(clients_info) },
#if __HAVE_DMA
{ "bufs", DRM(bufs_info) },
#endif
};
#define DRM_SYSCTL_ENTRIES (sizeof(DRM(sysctl_list))/sizeof(DRM(sysctl_list)[0]))
@ -112,90 +114,128 @@ int DRM(sysctl_cleanup)(drm_device_t *dev)
return error;
}
#define DRM_SYSCTL_PRINT(fmt, arg...) \
do { \
snprintf(buf, sizeof(buf), fmt, ##arg); \
retcode = SYSCTL_OUT(req, buf, strlen(buf)); \
if (retcode) \
goto done; \
} while (0)
static int DRM(name_info)DRM_SYSCTL_HANDLER_ARGS
{
drm_device_t *dev = arg1;
char buf[128];
int error;
int retcode;
int hasunique = 0;
DRM_SYSCTL_PRINT("%s 0x%x", dev->name, dev2udev(dev->devnode));
DRM_LOCK();
if (dev->unique) {
DRM_SYSCTL_PRINT("%s 0x%x %s",
dev->name, dev2udev(dev->devnode), dev->unique);
} else {
DRM_SYSCTL_PRINT("%s 0x%x", dev->name, dev2udev(dev->devnode));
snprintf(buf, sizeof(buf), " %s", dev->unique);
hasunique = 1;
}
DRM_UNLOCK();
if (hasunique)
SYSCTL_OUT(req, buf, strlen(buf));
SYSCTL_OUT(req, "", 1);
return 0;
}
static int DRM(_vm_info)DRM_SYSCTL_HANDLER_ARGS
{
drm_device_t *dev = arg1;
drm_local_map_t *map;
drm_map_list_entry_t *listentry;
const char *types[] = { "FB", "REG", "SHM", "AGP", "SG" };
const char *type;
int i=0;
char buf[128];
int error;
DRM_SYSCTL_PRINT("\nslot offset size type flags "
"address mtrr\n");
if (dev->maplist != NULL) {
TAILQ_FOREACH(listentry, dev->maplist, link) {
map = listentry->map;
if (map->type < 0 || map->type > 4)
type = "??";
else
type = types[map->type];
DRM_SYSCTL_PRINT("%4d 0x%08lx 0x%08lx %4.4s 0x%02x 0x%08lx ",
i,
map->offset,
map->size,
type,
map->flags,
(unsigned long)map->handle);
if (map->mtrr < 0) {
DRM_SYSCTL_PRINT("no\n");
} else {
DRM_SYSCTL_PRINT("yes\n");
}
i++;
}
}
SYSCTL_OUT(req, "", 1);
return 0;
done:
return retcode;
}
static int DRM(vm_info)DRM_SYSCTL_HANDLER_ARGS
{
drm_device_t __unused *dev = arg1;
int ret;
drm_device_t *dev = arg1;
drm_local_map_t *map, *tempmaps;
drm_map_list_entry_t *listentry;
const char *types[] = { "FB", "REG", "SHM", "AGP", "SG" };
const char *type, *yesno;
int i, mapcount;
char buf[128];
int retcode;
/* We can't hold the lock while doing SYSCTL_OUTs, so allocate a
* temporary copy of all the map entries and then SYSCTL_OUT that.
*/
DRM_LOCK();
ret = DRM(_vm_info)(oidp, arg1, arg2, req);
mapcount = 0;
TAILQ_FOREACH(listentry, dev->maplist, link)
mapcount++;
tempmaps = DRM(alloc)(sizeof(drm_local_map_t) * mapcount, DRM_MEM_MAPS);
if (tempmaps == NULL) {
DRM_UNLOCK();
return ENOMEM;
}
i = 0;
TAILQ_FOREACH(listentry, dev->maplist, link)
tempmaps[i++] = *listentry->map;
DRM_UNLOCK();
return ret;
DRM_SYSCTL_PRINT("\nslot offset size type flags "
"address mtrr\n");
for (i = 0; i < mapcount; i++) {
map = &tempmaps[i];
if (map->type < 0 || map->type > 4)
type = "??";
else
type = types[map->type];
if (map->mtrr <= 0)
yesno = "no";
else
yesno = "yes";
DRM_SYSCTL_PRINT(
"%4d 0x%08lx 0x%08lx %4.4s 0x%02x 0x%08lx %s\n", i,
map->offset, map->size, type, map->flags,
(unsigned long)map->handle, yesno);
}
SYSCTL_OUT(req, "", 1);
done:
DRM(free)(tempmaps, sizeof(drm_local_map_t) * mapcount, DRM_MEM_MAPS);
return retcode;
}
/* drm_bufs_info is called whenever a process reads
hw.dri.0.bufs. */
static int DRM(_bufs_info) DRM_SYSCTL_HANDLER_ARGS
#if __HAVE_DMA
static int DRM(bufs_info) DRM_SYSCTL_HANDLER_ARGS
{
drm_device_t *dev = arg1;
drm_device_dma_t *dma = dev->dma;
int i;
char buf[128];
int error;
drm_device_dma_t tempdma;
int *templists;
int i;
char buf[128];
int retcode;
/* We can't hold the locks around DRM_SYSCTL_PRINT, so make a temporary
* copy of the whole structure and the relevant data from buflist.
*/
DRM_LOCK();
DRM_SPINLOCK(&dev->dma_lock);
if (dma == NULL) {
DRM_SPINUNLOCK(&dev->dma_lock);
DRM_UNLOCK();
return 0;
}
tempdma = *dma;
templists = DRM(alloc)(sizeof(int) * dma->buf_count, DRM_MEM_BUFS);
for (i = 0; i < dma->buf_count; i++)
templists[i] = dma->buflist[i]->list;
dma = &tempdma;
DRM_SPINUNLOCK(&dev->dma_lock);
DRM_UNLOCK();
if (!dma) return 0;
DRM_SYSCTL_PRINT("\n o size count free segs pages kB\n");
for (i = 0; i <= DRM_MAX_ORDER; i++) {
if (dma->bufs[i].buf_count)
@ -215,35 +255,45 @@ static int DRM(_bufs_info) DRM_SYSCTL_HANDLER_ARGS
DRM_SYSCTL_PRINT("\n");
for (i = 0; i < dma->buf_count; i++) {
if (i && !(i%32)) DRM_SYSCTL_PRINT("\n");
DRM_SYSCTL_PRINT(" %d", dma->buflist[i]->list);
DRM_SYSCTL_PRINT(" %d", templists[i]);
}
DRM_SYSCTL_PRINT("\n");
SYSCTL_OUT(req, "", 1);
return 0;
done:
DRM(free)(templists, sizeof(int) * dma->buf_count, DRM_MEM_BUFS);
return retcode;
}
#endif
static int DRM(bufs_info) DRM_SYSCTL_HANDLER_ARGS
{
drm_device_t __unused *dev = arg1;
int ret;
DRM_LOCK();
ret = DRM(_bufs_info)(oidp, arg1, arg2, req);
DRM_UNLOCK();
return ret;
}
static int DRM(_clients_info) DRM_SYSCTL_HANDLER_ARGS
static int DRM(clients_info)DRM_SYSCTL_HANDLER_ARGS
{
drm_device_t *dev = arg1;
drm_file_t *priv;
char buf[128];
int error;
drm_file_t *priv, *tempprivs;
char buf[128];
int retcode;
int privcount, i;
DRM_LOCK();
privcount = 0;
TAILQ_FOREACH(priv, &dev->files, link)
privcount++;
tempprivs = DRM(alloc)(sizeof(drm_file_t) * privcount, DRM_MEM_FILES);
if (tempprivs == NULL) {
DRM_UNLOCK();
return ENOMEM;
}
i = 0;
TAILQ_FOREACH(priv, &dev->files, link)
tempprivs[i++] = *priv;
DRM_UNLOCK();
DRM_SYSCTL_PRINT("\na dev pid uid magic ioctls\n");
TAILQ_FOREACH(priv, &dev->files, link) {
for (i = 0; i < privcount; i++) {
priv = &tempprivs[i];
DRM_SYSCTL_PRINT("%c %3d %5d %5d %10u %10lu\n",
priv->authenticated ? 'y' : 'n',
priv->minor,
@ -254,21 +304,11 @@ static int DRM(_clients_info) DRM_SYSCTL_HANDLER_ARGS
}
SYSCTL_OUT(req, "", 1);
return 0;
done:
DRM(free)(tempprivs, sizeof(drm_file_t) * privcount, DRM_MEM_FILES);
return retcode;
}
static int DRM(clients_info)DRM_SYSCTL_HANDLER_ARGS
{
drm_device_t __unused *dev = arg1;
int ret;
DRM_LOCK();
ret = DRM(_clients_info)(oidp, arg1, arg2, req);
DRM_UNLOCK();
return ret;
}
#elif defined(__NetBSD__)
/* stub it out for now, sysctl is only for debugging */
int DRM(sysctl_init)(drm_device_t *dev)

View file

@ -472,11 +472,6 @@ static int DRM(setup)( drm_device_t *dev )
dev->magiclist[i].tail = NULL;
}
dev->maplist = DRM(calloc)(1, sizeof(*dev->maplist), DRM_MEM_MAPS);
if (dev->maplist == NULL)
return DRM_ERR(ENOMEM);
TAILQ_INIT(dev->maplist);
dev->lock.hw_lock = NULL;
dev->lock.lock_queue = 0;
dev->irq = 0;
@ -591,8 +586,6 @@ static int DRM(takedown)( drm_device_t *dev )
DRM(free)(list, sizeof(*list), DRM_MEM_MAPS);
DRM(free)(map, sizeof(*map), DRM_MEM_MAPS);
}
DRM(free)(dev->maplist, sizeof(*dev->maplist), DRM_MEM_MAPS);
dev->maplist = NULL;
}
#if __HAVE_DMA
@ -647,6 +640,14 @@ static int DRM(init)( device_t nbdev )
#elif defined(__NetBSD__)
unit = minor(dev->device.dv_unit);
#endif
dev->maplist = DRM(calloc)(1, sizeof(*dev->maplist), DRM_MEM_MAPS);
if (dev->maplist == NULL) {
retcode = ENOMEM;
goto error;
}
TAILQ_INIT(dev->maplist);
dev->name = DRIVER_NAME;
DRM(mem_init)();
DRM(sysctl_init)(dev);
@ -680,6 +681,7 @@ static int DRM(init)( device_t nbdev )
goto error;
}
#endif
DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d\n",
DRIVER_NAME,
DRIVER_MAJOR,
@ -703,6 +705,7 @@ error:
mtx_destroy(&dev->dev_lock);
#endif
#endif
DRM(free)(dev->maplist, sizeof(*dev->maplist), DRM_MEM_MAPS);
return retcode;
}
@ -749,6 +752,7 @@ static void DRM(cleanup)(drm_device_t *dev)
#if defined(__FreeBSD__) && __FreeBSD_version >= 500000
mtx_destroy(&dev->dev_lock);
#endif
DRM(free)(dev->maplist, sizeof(*dev->maplist), DRM_MEM_MAPS);
}

View file

@ -32,6 +32,14 @@
#include "drmP.h"
#define DRM_SYSCTL_PRINT(fmt, arg...) \
do { \
snprintf(buf, sizeof(buf), fmt, ##arg); \
error = SYSCTL_OUT(req, buf, strlen(buf)); \
if (error) \
return error; \
} while (0)
typedef struct drm_mem_stats {
const char *name;
int succeed_count;

View file

@ -413,14 +413,6 @@ find_first_zero_bit(volatile void *p, int max)
#define DRM_SYSCTL_HANDLER_ARGS SYSCTL_HANDLER_ARGS
#endif
#define DRM_SYSCTL_PRINT(fmt, arg...) \
do { \
snprintf(buf, sizeof(buf), fmt, ##arg); \
error = SYSCTL_OUT(req, buf, strlen(buf)); \
if (error) return error; \
} while (0)
#define DRM_FIND_MAP(dest, o) \
do { \
drm_map_list_entry_t *listentry; \

View file

@ -342,12 +342,6 @@ do { \
#define DRM_DEBUG(fmt, arg...) do { } while (0)
#endif
#define DRM_SYSCTL_PRINT(fmt, arg...) \
snprintf(buf, sizeof(buf), fmt, ##arg); \
error = SYSCTL_OUT(req, buf, strlen(buf)); \
if (error) return error;
#define DRM_FIND_MAP(dest, o) \
do { \
drm_map_list_entry_t *listentry; \

View file

@ -41,7 +41,9 @@ struct DRM(sysctl_list) {
#endif
{ "vm", DRM(vm_info) },
{ "clients", DRM(clients_info) },
#if __HAVE_DMA
{ "bufs", DRM(bufs_info) },
#endif
};
#define DRM_SYSCTL_ENTRIES (sizeof(DRM(sysctl_list))/sizeof(DRM(sysctl_list)[0]))
@ -112,90 +114,128 @@ int DRM(sysctl_cleanup)(drm_device_t *dev)
return error;
}
#define DRM_SYSCTL_PRINT(fmt, arg...) \
do { \
snprintf(buf, sizeof(buf), fmt, ##arg); \
retcode = SYSCTL_OUT(req, buf, strlen(buf)); \
if (retcode) \
goto done; \
} while (0)
static int DRM(name_info)DRM_SYSCTL_HANDLER_ARGS
{
drm_device_t *dev = arg1;
char buf[128];
int error;
int retcode;
int hasunique = 0;
DRM_SYSCTL_PRINT("%s 0x%x", dev->name, dev2udev(dev->devnode));
DRM_LOCK();
if (dev->unique) {
DRM_SYSCTL_PRINT("%s 0x%x %s",
dev->name, dev2udev(dev->devnode), dev->unique);
} else {
DRM_SYSCTL_PRINT("%s 0x%x", dev->name, dev2udev(dev->devnode));
snprintf(buf, sizeof(buf), " %s", dev->unique);
hasunique = 1;
}
DRM_UNLOCK();
if (hasunique)
SYSCTL_OUT(req, buf, strlen(buf));
SYSCTL_OUT(req, "", 1);
return 0;
}
static int DRM(_vm_info)DRM_SYSCTL_HANDLER_ARGS
{
drm_device_t *dev = arg1;
drm_local_map_t *map;
drm_map_list_entry_t *listentry;
const char *types[] = { "FB", "REG", "SHM", "AGP", "SG" };
const char *type;
int i=0;
char buf[128];
int error;
DRM_SYSCTL_PRINT("\nslot offset size type flags "
"address mtrr\n");
if (dev->maplist != NULL) {
TAILQ_FOREACH(listentry, dev->maplist, link) {
map = listentry->map;
if (map->type < 0 || map->type > 4)
type = "??";
else
type = types[map->type];
DRM_SYSCTL_PRINT("%4d 0x%08lx 0x%08lx %4.4s 0x%02x 0x%08lx ",
i,
map->offset,
map->size,
type,
map->flags,
(unsigned long)map->handle);
if (map->mtrr < 0) {
DRM_SYSCTL_PRINT("no\n");
} else {
DRM_SYSCTL_PRINT("yes\n");
}
i++;
}
}
SYSCTL_OUT(req, "", 1);
return 0;
done:
return retcode;
}
static int DRM(vm_info)DRM_SYSCTL_HANDLER_ARGS
{
drm_device_t __unused *dev = arg1;
int ret;
drm_device_t *dev = arg1;
drm_local_map_t *map, *tempmaps;
drm_map_list_entry_t *listentry;
const char *types[] = { "FB", "REG", "SHM", "AGP", "SG" };
const char *type, *yesno;
int i, mapcount;
char buf[128];
int retcode;
/* We can't hold the lock while doing SYSCTL_OUTs, so allocate a
* temporary copy of all the map entries and then SYSCTL_OUT that.
*/
DRM_LOCK();
ret = DRM(_vm_info)(oidp, arg1, arg2, req);
mapcount = 0;
TAILQ_FOREACH(listentry, dev->maplist, link)
mapcount++;
tempmaps = DRM(alloc)(sizeof(drm_local_map_t) * mapcount, DRM_MEM_MAPS);
if (tempmaps == NULL) {
DRM_UNLOCK();
return ENOMEM;
}
i = 0;
TAILQ_FOREACH(listentry, dev->maplist, link)
tempmaps[i++] = *listentry->map;
DRM_UNLOCK();
return ret;
DRM_SYSCTL_PRINT("\nslot offset size type flags "
"address mtrr\n");
for (i = 0; i < mapcount; i++) {
map = &tempmaps[i];
if (map->type < 0 || map->type > 4)
type = "??";
else
type = types[map->type];
if (map->mtrr <= 0)
yesno = "no";
else
yesno = "yes";
DRM_SYSCTL_PRINT(
"%4d 0x%08lx 0x%08lx %4.4s 0x%02x 0x%08lx %s\n", i,
map->offset, map->size, type, map->flags,
(unsigned long)map->handle, yesno);
}
SYSCTL_OUT(req, "", 1);
done:
DRM(free)(tempmaps, sizeof(drm_local_map_t) * mapcount, DRM_MEM_MAPS);
return retcode;
}
/* drm_bufs_info is called whenever a process reads
hw.dri.0.bufs. */
static int DRM(_bufs_info) DRM_SYSCTL_HANDLER_ARGS
#if __HAVE_DMA
static int DRM(bufs_info) DRM_SYSCTL_HANDLER_ARGS
{
drm_device_t *dev = arg1;
drm_device_dma_t *dma = dev->dma;
int i;
char buf[128];
int error;
drm_device_dma_t tempdma;
int *templists;
int i;
char buf[128];
int retcode;
/* We can't hold the locks around DRM_SYSCTL_PRINT, so make a temporary
* copy of the whole structure and the relevant data from buflist.
*/
DRM_LOCK();
DRM_SPINLOCK(&dev->dma_lock);
if (dma == NULL) {
DRM_SPINUNLOCK(&dev->dma_lock);
DRM_UNLOCK();
return 0;
}
tempdma = *dma;
templists = DRM(alloc)(sizeof(int) * dma->buf_count, DRM_MEM_BUFS);
for (i = 0; i < dma->buf_count; i++)
templists[i] = dma->buflist[i]->list;
dma = &tempdma;
DRM_SPINUNLOCK(&dev->dma_lock);
DRM_UNLOCK();
if (!dma) return 0;
DRM_SYSCTL_PRINT("\n o size count free segs pages kB\n");
for (i = 0; i <= DRM_MAX_ORDER; i++) {
if (dma->bufs[i].buf_count)
@ -215,35 +255,45 @@ static int DRM(_bufs_info) DRM_SYSCTL_HANDLER_ARGS
DRM_SYSCTL_PRINT("\n");
for (i = 0; i < dma->buf_count; i++) {
if (i && !(i%32)) DRM_SYSCTL_PRINT("\n");
DRM_SYSCTL_PRINT(" %d", dma->buflist[i]->list);
DRM_SYSCTL_PRINT(" %d", templists[i]);
}
DRM_SYSCTL_PRINT("\n");
SYSCTL_OUT(req, "", 1);
return 0;
done:
DRM(free)(templists, sizeof(int) * dma->buf_count, DRM_MEM_BUFS);
return retcode;
}
#endif
static int DRM(bufs_info) DRM_SYSCTL_HANDLER_ARGS
{
drm_device_t __unused *dev = arg1;
int ret;
DRM_LOCK();
ret = DRM(_bufs_info)(oidp, arg1, arg2, req);
DRM_UNLOCK();
return ret;
}
static int DRM(_clients_info) DRM_SYSCTL_HANDLER_ARGS
static int DRM(clients_info)DRM_SYSCTL_HANDLER_ARGS
{
drm_device_t *dev = arg1;
drm_file_t *priv;
char buf[128];
int error;
drm_file_t *priv, *tempprivs;
char buf[128];
int retcode;
int privcount, i;
DRM_LOCK();
privcount = 0;
TAILQ_FOREACH(priv, &dev->files, link)
privcount++;
tempprivs = DRM(alloc)(sizeof(drm_file_t) * privcount, DRM_MEM_FILES);
if (tempprivs == NULL) {
DRM_UNLOCK();
return ENOMEM;
}
i = 0;
TAILQ_FOREACH(priv, &dev->files, link)
tempprivs[i++] = *priv;
DRM_UNLOCK();
DRM_SYSCTL_PRINT("\na dev pid uid magic ioctls\n");
TAILQ_FOREACH(priv, &dev->files, link) {
for (i = 0; i < privcount; i++) {
priv = &tempprivs[i];
DRM_SYSCTL_PRINT("%c %3d %5d %5d %10u %10lu\n",
priv->authenticated ? 'y' : 'n',
priv->minor,
@ -254,21 +304,11 @@ static int DRM(_clients_info) DRM_SYSCTL_HANDLER_ARGS
}
SYSCTL_OUT(req, "", 1);
return 0;
done:
DRM(free)(tempprivs, sizeof(drm_file_t) * privcount, DRM_MEM_FILES);
return retcode;
}
static int DRM(clients_info)DRM_SYSCTL_HANDLER_ARGS
{
drm_device_t __unused *dev = arg1;
int ret;
DRM_LOCK();
ret = DRM(_clients_info)(oidp, arg1, arg2, req);
DRM_UNLOCK();
return ret;
}
#elif defined(__NetBSD__)
/* stub it out for now, sysctl is only for debugging */
int DRM(sysctl_init)(drm_device_t *dev)