aboutsummaryrefslogtreecommitdiff
path: root/bsd-core/drm_scatter.c
diff options
context:
space:
mode:
authorEric Anholt <anholt@freebsd.org>2004-11-07 04:11:15 +0000
committerEric Anholt <anholt@freebsd.org>2004-11-07 04:11:15 +0000
commita1d9e5abafe60ca2b7f96cadd1013695ada4ac41 (patch)
treeff8a462ecf2fea9ee35c8988ac0d9a37b7206808 /bsd-core/drm_scatter.c
parentc5bededa5130a58273448188c04c15bc9c1097f3 (diff)
Refine the locking of the DRM. Most significant is covering the driver
ioctls with dev_lock, which is a major step toward being able to remove Giant. Covers some new pieces (dev->unique*) in the core, and avoids one call down into system internals with the drm lock held, which is usually bad (FreeBSD LOR #23, #27).
Diffstat (limited to 'bsd-core/drm_scatter.c')
-rw-r--r--bsd-core/drm_scatter.c22
1 files changed, 13 insertions, 9 deletions
diff --git a/bsd-core/drm_scatter.c b/bsd-core/drm_scatter.c
index 03e82439..7a035af5 100644
--- a/bsd-core/drm_scatter.c
+++ b/bsd-core/drm_scatter.c
@@ -36,7 +36,6 @@
void drm_sg_cleanup(drm_sg_mem_t *entry)
{
free(entry->virtual, M_DRM);
-
free(entry->busaddr, M_DRM);
free(entry, M_DRM);
}
@@ -56,7 +55,7 @@ int drm_sg_alloc(DRM_IOCTL_ARGS)
DRM_COPY_FROM_USER_IOCTL(request, (drm_scatter_gather_t *)data,
sizeof(request) );
- entry = malloc(sizeof(*entry), M_DRM, M_NOWAIT | M_ZERO);
+ entry = malloc(sizeof(*entry), M_DRM, M_WAITOK | M_ZERO);
if ( !entry )
return ENOMEM;
@@ -66,16 +65,15 @@ int drm_sg_alloc(DRM_IOCTL_ARGS)
entry->pages = pages;
entry->busaddr = malloc(pages * sizeof(*entry->busaddr), M_DRM,
- M_NOWAIT | M_ZERO);
+ M_WAITOK | M_ZERO);
if ( !entry->busaddr ) {
- free(entry, M_DRM);
+ drm_sg_cleanup(entry);
return ENOMEM;
}
entry->virtual = malloc(pages << PAGE_SHIFT, M_DRM, M_WAITOK | M_ZERO);
if ( !entry->virtual ) {
- free(entry->busaddr, M_DRM);
- free(entry, M_DRM);
+ drm_sg_cleanup(entry);
return ENOMEM;
}
@@ -90,12 +88,16 @@ int drm_sg_alloc(DRM_IOCTL_ARGS)
request,
sizeof(request) );
+ DRM_LOCK();
+ if (dev->sg) {
+ DRM_UNLOCK();
+ drm_sg_cleanup(entry);
+ return EINVAL;
+ }
dev->sg = entry;
+ DRM_UNLOCK();
return 0;
-
- drm_sg_cleanup(entry);
- return ENOMEM;
}
int drm_sg_free(DRM_IOCTL_ARGS)
@@ -107,8 +109,10 @@ int drm_sg_free(DRM_IOCTL_ARGS)
DRM_COPY_FROM_USER_IOCTL( request, (drm_scatter_gather_t *)data,
sizeof(request) );
+ DRM_LOCK();
entry = dev->sg;
dev->sg = NULL;
+ DRM_UNLOCK();
if ( !entry || entry->handle != request.handle )
return EINVAL;