mirror of
https://gitlab.freedesktop.org/mesa/drm.git
synced 2025-12-28 16:50:20 +01:00
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:
parent
6b0424fdcd
commit
ea7b4fdc22
9 changed files with 294 additions and 226 deletions
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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; \
|
||||
|
|
|
|||
|
|
@ -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; \
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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; \
|
||||
|
|
|
|||
|
|
@ -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; \
|
||||
|
|
|
|||
224
bsd/drm_sysctl.h
224
bsd/drm_sysctl.h
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue