diff options
author | Eric Anholt <anholt@freebsd.org> | 2004-11-07 04:11:15 +0000 |
---|---|---|
committer | Eric Anholt <anholt@freebsd.org> | 2004-11-07 04:11:15 +0000 |
commit | a1d9e5abafe60ca2b7f96cadd1013695ada4ac41 (patch) | |
tree | ff8a462ecf2fea9ee35c8988ac0d9a37b7206808 /bsd-core/drm_scatter.c | |
parent | c5bededa5130a58273448188c04c15bc9c1097f3 (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.c | 22 |
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; |