From a1d9e5abafe60ca2b7f96cadd1013695ada4ac41 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Sun, 7 Nov 2004 04:11:15 +0000 Subject: 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). --- bsd-core/drm_scatter.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) (limited to 'bsd-core/drm_scatter.c') 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; -- cgit v1.2.3