diff options
author | Jung-uk Kim | 2007-10-17 14:50:29 -0500 |
---|---|---|
committer | Eric Anholt | 2007-10-17 14:52:12 -0500 |
commit | 36120264ca8f43078f8748e022faeb9471edcb36 (patch) | |
tree | 6069352cee66872b65f2fdfeb27a09713c3dceee /bsd-core | |
parent | ec1162b212248042bf1317abcb3c47bb10db8aa3 (diff) | |
download | external-libdrm-36120264ca8f43078f8748e022faeb9471edcb36.tar.gz external-libdrm-36120264ca8f43078f8748e022faeb9471edcb36.tar.xz external-libdrm-36120264ca8f43078f8748e022faeb9471edcb36.zip |
Bug #11870: FreeBSD hardware lock cleanup fix with multiple opens by a process.
Previously, the lock would get released on the first close by the X Server
(during AIGLX setup), and the Radeon driver would then hang in initialization
due to unexpected failure in DRM calls that required the lock to be held.
Based on a patch by Kostik Belousov.
Diffstat (limited to 'bsd-core')
-rw-r--r-- | bsd-core/drm_drv.c | 15 |
1 files changed, 9 insertions, 6 deletions
diff --git a/bsd-core/drm_drv.c b/bsd-core/drm_drv.c index c36b78aa..d6868b9c 100644 --- a/bsd-core/drm_drv.c +++ b/bsd-core/drm_drv.c | |||
@@ -538,6 +538,7 @@ static int drm_load(drm_device_t *dev) | |||
538 | 538 | ||
539 | if (dev->driver.load != NULL) { | 539 | if (dev->driver.load != NULL) { |
540 | DRM_LOCK(); | 540 | DRM_LOCK(); |
541 | /* Shared code returns -errno. */ | ||
541 | retcode = -dev->driver.load(dev, | 542 | retcode = -dev->driver.load(dev, |
542 | dev->id_entry->driver_private); | 543 | dev->id_entry->driver_private); |
543 | DRM_UNLOCK(); | 544 | DRM_UNLOCK(); |
@@ -720,6 +721,9 @@ int drm_close(struct cdev *kdev, int flags, int fmt, DRM_STRUCTPROC *p) | |||
720 | return EINVAL; | 721 | return EINVAL; |
721 | } | 722 | } |
722 | 723 | ||
724 | if (--file_priv->refs != 0) | ||
725 | goto done; | ||
726 | |||
723 | if (dev->driver.preclose != NULL) | 727 | if (dev->driver.preclose != NULL) |
724 | dev->driver.preclose(dev, file_priv); | 728 | dev->driver.preclose(dev, file_priv); |
725 | 729 | ||
@@ -795,17 +799,16 @@ int drm_close(struct cdev *kdev, int flags, int fmt, DRM_STRUCTPROC *p) | |||
795 | dev->buf_pgid = 0; | 799 | dev->buf_pgid = 0; |
796 | #endif /* __NetBSD__ || __OpenBSD__ */ | 800 | #endif /* __NetBSD__ || __OpenBSD__ */ |
797 | 801 | ||
798 | if (--file_priv->refs == 0) { | 802 | if (dev->driver.postclose != NULL) |
799 | if (dev->driver.postclose != NULL) | 803 | dev->driver.postclose(dev, file_priv); |
800 | dev->driver.postclose(dev, file_priv); | 804 | TAILQ_REMOVE(&dev->files, file_priv, link); |
801 | TAILQ_REMOVE(&dev->files, file_priv, link); | 805 | free(file_priv, M_DRM); |
802 | free(file_priv, M_DRM); | ||
803 | } | ||
804 | 806 | ||
805 | /* ======================================================== | 807 | /* ======================================================== |
806 | * End inline drm_release | 808 | * End inline drm_release |
807 | */ | 809 | */ |
808 | 810 | ||
811 | done: | ||
809 | atomic_inc( &dev->counts[_DRM_STAT_CLOSES] ); | 812 | atomic_inc( &dev->counts[_DRM_STAT_CLOSES] ); |
810 | #ifdef __FreeBSD__ | 813 | #ifdef __FreeBSD__ |
811 | device_unbusy(dev->device); | 814 | device_unbusy(dev->device); |