From 6f2479c67432f764bfc4e248689f1737c1935237 Mon Sep 17 00:00:00 2001 From: Robert Noland Date: Sat, 6 Sep 2008 18:37:06 -0400 Subject: [PATCH] [FreeBSD] Ensure that drm_pci_alloc is never called while locks are held. --- bsd-core/ati_pcigart.c | 13 +++++++++---- bsd-core/drm_bufs.c | 2 ++ bsd-core/drm_pci.c | 13 +++++++++---- shared-core/i915_dma.c | 20 ++++++++++++++------ shared-core/mach64_dma.c | 6 ++++++ 5 files changed, 40 insertions(+), 14 deletions(-) diff --git a/bsd-core/ati_pcigart.c b/bsd-core/ati_pcigart.c index f8d3f18..c4453ed 100644 --- a/bsd-core/ati_pcigart.c +++ b/bsd-core/ati_pcigart.c @@ -42,12 +42,17 @@ static int drm_ati_alloc_pcigart_table(struct drm_device *dev, struct drm_ati_pcigart_info *gart_info) { - dev->sg->dmah = drm_pci_alloc(dev, gart_info->table_size, - PAGE_SIZE, - gart_info->table_mask); - if (dev->sg->dmah == NULL) + drm_dma_handle_t *dmah; + + DRM_UNLOCK(); + dmah = drm_pci_alloc(dev, gart_info->table_size, PAGE_SIZE, + gart_info->table_mask); + DRM_LOCK(); + if (dmah == NULL) return ENOMEM; + dev->sg->dmah = dmah; + return 0; } diff --git a/bsd-core/drm_bufs.c b/bsd-core/drm_bufs.c index 45e0147..94f5138 100644 --- a/bsd-core/drm_bufs.c +++ b/bsd-core/drm_bufs.c @@ -595,8 +595,10 @@ static int drm_do_addbufs_pci(struct drm_device *dev, struct drm_buf_desc *reque page_count = 0; while (entry->buf_count < count) { + DRM_SPINUNLOCK(&dev->dma_lock); drm_dma_handle_t *dmah = drm_pci_alloc(dev, size, alignment, 0xfffffffful); + DRM_SPINLOCK(&dev->dma_lock); if (dmah == NULL) { /* Set count correctly so we free the proper amount. */ entry->buf_count = count; diff --git a/bsd-core/drm_pci.c b/bsd-core/drm_pci.c index f23b2a5..16c830e 100644 --- a/bsd-core/drm_pci.c +++ b/bsd-core/drm_pci.c @@ -71,7 +71,14 @@ drm_pci_alloc(struct drm_device *dev, size_t size, return NULL; #ifdef __FreeBSD__ - DRM_UNLOCK(); + /* Make sure we aren't holding locks here */ + mtx_assert(&dev->dev_lock, MA_NOTOWNED); + if (mtx_owned(&dev->dev_lock)) + DRM_ERROR("called while holding dev_lock\n"); + mtx_assert(&dev->dma_lock, MA_NOTOWNED); + if (mtx_owned(&dev->dma_lock)) + DRM_ERROR("called while holding dma_lock\n"); + ret = bus_dma_tag_create(NULL, align, 0, /* tag, align, boundary */ maxaddr, BUS_SPACE_MAXADDR, /* lowaddr, highaddr */ NULL, NULL, /* filtfunc, filtfuncargs */ @@ -80,7 +87,6 @@ drm_pci_alloc(struct drm_device *dev, size_t size, &dmah->tag); if (ret != 0) { free(dmah, M_DRM); - DRM_LOCK(); return NULL; } @@ -89,10 +95,9 @@ drm_pci_alloc(struct drm_device *dev, size_t size, if (ret != 0) { bus_dma_tag_destroy(dmah->tag); free(dmah, M_DRM); - DRM_LOCK(); return NULL; } - DRM_LOCK(); + ret = bus_dmamap_load(dmah->tag, dmah->map, dmah->vaddr, size, drm_pci_busdma_callback, dmah, 0); if (ret != 0) { diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index c874ce2..619e6ac 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -72,16 +72,24 @@ int i915_wait_ring(struct drm_device * dev, int n, const char *caller) int i915_init_hardware_status(struct drm_device *dev) { drm_i915_private_t *dev_priv = dev->dev_private; - /* Program Hardware Status Page */ - dev_priv->status_page_dmah = - drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE, 0xffffffff); + drm_dma_handle_t *dmah; - if (!dev_priv->status_page_dmah) { + /* Program Hardware Status Page */ +#ifdef __FreeBSD__ + DRM_UNLOCK(); +#endif + dmah = drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE, 0xffffffff); +#ifdef __FreeBSD__ + DRM_LOCK(); +#endif + if (!dmah) { DRM_ERROR("Can not allocate hardware status page\n"); return -ENOMEM; } - dev_priv->hw_status_page = dev_priv->status_page_dmah->vaddr; - dev_priv->dma_status_page = dev_priv->status_page_dmah->busaddr; + + dev_priv->status_page_dmah = dmah; + dev_priv->hw_status_page = dmah->vaddr; + dev_priv->dma_status_page = dmah->busaddr; memset(dev_priv->hw_status_page, 0, PAGE_SIZE); diff --git a/shared-core/mach64_dma.c b/shared-core/mach64_dma.c index 339234f..3f2367b 100644 --- a/shared-core/mach64_dma.c +++ b/shared-core/mach64_dma.c @@ -834,8 +834,14 @@ static int mach64_bm_dma_test(struct drm_device * dev) /* FIXME: get a dma buffer from the freelist here */ DRM_DEBUG("Allocating data memory ...\n"); +#ifdef __FreeBSD__ + DRM_UNLOCK(); +#endif cpu_addr_dmah = drm_pci_alloc(dev, 0x1000, 0x1000, 0xfffffffful); +#ifdef __FreeBSD__ + DRM_LOCK(); +#endif if (!cpu_addr_dmah) { DRM_INFO("data-memory allocation failed!\n"); return -ENOMEM; -- 2.7.4