diff options
author | Ian Romanick <idr@us.ibm.com> | 2007-07-19 11:38:56 -0700 |
---|---|---|
committer | Ian Romanick <idr@us.ibm.com> | 2007-07-19 11:38:56 -0700 |
commit | 15245b670e5359a7dbf9151aa9f160e929e0b46b (patch) | |
tree | 7d5cfcad5dfdb667183ce66bea61aec10f3b55d7 | |
parent | 2f53ce4af2f7db911d908ff382738f30be004e8b (diff) |
Rework xgi_(pcie|fb)_free_all to prevent deadlock.
-rw-r--r-- | linux-core/xgi_fb.c | 2 | ||||
-rw-r--r-- | linux-core/xgi_pcie.c | 24 |
2 files changed, 19 insertions, 7 deletions
diff --git a/linux-core/xgi_fb.c b/linux-core/xgi_fb.c index ce689847..a5885198 100644 --- a/linux-core/xgi_fb.c +++ b/linux-core/xgi_fb.c @@ -365,7 +365,7 @@ void xgi_fb_free_all(struct xgi_info * info, DRMFILE filp) break; } - (void) xgi_fb_free(info, block->offset, filp); + (void) xgi_mem_free(&info->fb_heap, block->offset, filp); } while(1); up(&info->fb_sem); diff --git a/linux-core/xgi_pcie.c b/linux-core/xgi_pcie.c index 49c531fc..9dee888b 100644 --- a/linux-core/xgi_pcie.c +++ b/linux-core/xgi_pcie.c @@ -34,6 +34,9 @@ static struct xgi_mem_block *xgi_pcie_vertex_block = NULL; static struct xgi_mem_block *xgi_pcie_cmdlist_block = NULL; static struct xgi_mem_block *xgi_pcie_scratchpad_block = NULL; +static int xgi_pcie_free_locked(struct xgi_info * info, + unsigned long offset, DRMFILE filp); + static int xgi_pcie_lut_init(struct xgi_info * info) { u8 temp = 0; @@ -248,30 +251,39 @@ void xgi_pcie_free_all(struct xgi_info * info, DRMFILE filp) break; } - (void) xgi_pcie_free(info, block->offset, filp); + (void) xgi_pcie_free_locked(info, block->offset, filp); } while(1); up(&info->pcie_sem); } -int xgi_pcie_free(struct xgi_info * info, unsigned long offset, DRMFILE filp) +int xgi_pcie_free_locked(struct xgi_info * info, + unsigned long offset, DRMFILE filp) { const bool isvertex = (xgi_pcie_vertex_block && (xgi_pcie_vertex_block->offset == offset)); + int err = xgi_mem_free(&info->pcie_heap, offset, filp); + + if (!err && isvertex) + xgi_pcie_vertex_block = NULL; + + return err; +} + + +int xgi_pcie_free(struct xgi_info * info, unsigned long offset, DRMFILE filp) +{ int err; down(&info->pcie_sem); - err = xgi_mem_free(&info->pcie_heap, offset, filp); + err = xgi_pcie_free_locked(info, offset, filp); up(&info->pcie_sem); if (err) { DRM_ERROR("xgi_pcie_free() failed at base 0x%lx\n", offset); } - if (isvertex) - xgi_pcie_vertex_block = NULL; - return err; } |