diff options
Diffstat (limited to 'mm')
-rw-r--r-- | mm/dmapool.c | 14 |
1 files changed, 6 insertions, 8 deletions
diff --git a/mm/dmapool.c b/mm/dmapool.c index 4df2de77e069..a2f6295b4df4 100644 --- a/mm/dmapool.c +++ b/mm/dmapool.c | |||
@@ -355,20 +355,15 @@ EXPORT_SYMBOL(dma_pool_alloc); | |||
355 | 355 | ||
356 | static struct dma_page *pool_find_page(struct dma_pool *pool, dma_addr_t dma) | 356 | static struct dma_page *pool_find_page(struct dma_pool *pool, dma_addr_t dma) |
357 | { | 357 | { |
358 | unsigned long flags; | ||
359 | struct dma_page *page; | 358 | struct dma_page *page; |
360 | 359 | ||
361 | spin_lock_irqsave(&pool->lock, flags); | ||
362 | list_for_each_entry(page, &pool->page_list, page_list) { | 360 | list_for_each_entry(page, &pool->page_list, page_list) { |
363 | if (dma < page->dma) | 361 | if (dma < page->dma) |
364 | continue; | 362 | continue; |
365 | if (dma < (page->dma + pool->allocation)) | 363 | if (dma < (page->dma + pool->allocation)) |
366 | goto done; | 364 | return page; |
367 | } | 365 | } |
368 | page = NULL; | 366 | return NULL; |
369 | done: | ||
370 | spin_unlock_irqrestore(&pool->lock, flags); | ||
371 | return page; | ||
372 | } | 367 | } |
373 | 368 | ||
374 | /** | 369 | /** |
@@ -386,8 +381,10 @@ void dma_pool_free(struct dma_pool *pool, void *vaddr, dma_addr_t dma) | |||
386 | unsigned long flags; | 381 | unsigned long flags; |
387 | unsigned int offset; | 382 | unsigned int offset; |
388 | 383 | ||
384 | spin_lock_irqsave(&pool->lock, flags); | ||
389 | page = pool_find_page(pool, dma); | 385 | page = pool_find_page(pool, dma); |
390 | if (!page) { | 386 | if (!page) { |
387 | spin_unlock_irqrestore(&pool->lock, flags); | ||
391 | if (pool->dev) | 388 | if (pool->dev) |
392 | dev_err(pool->dev, | 389 | dev_err(pool->dev, |
393 | "dma_pool_free %s, %p/%lx (bad dma)\n", | 390 | "dma_pool_free %s, %p/%lx (bad dma)\n", |
@@ -401,6 +398,7 @@ void dma_pool_free(struct dma_pool *pool, void *vaddr, dma_addr_t dma) | |||
401 | offset = vaddr - page->vaddr; | 398 | offset = vaddr - page->vaddr; |
402 | #ifdef DMAPOOL_DEBUG | 399 | #ifdef DMAPOOL_DEBUG |
403 | if ((dma - page->dma) != offset) { | 400 | if ((dma - page->dma) != offset) { |
401 | spin_unlock_irqrestore(&pool->lock, flags); | ||
404 | if (pool->dev) | 402 | if (pool->dev) |
405 | dev_err(pool->dev, | 403 | dev_err(pool->dev, |
406 | "dma_pool_free %s, %p (bad vaddr)/%Lx\n", | 404 | "dma_pool_free %s, %p (bad vaddr)/%Lx\n", |
@@ -418,6 +416,7 @@ void dma_pool_free(struct dma_pool *pool, void *vaddr, dma_addr_t dma) | |||
418 | chain = *(int *)(page->vaddr + chain); | 416 | chain = *(int *)(page->vaddr + chain); |
419 | continue; | 417 | continue; |
420 | } | 418 | } |
419 | spin_unlock_irqrestore(&pool->lock, flags); | ||
421 | if (pool->dev) | 420 | if (pool->dev) |
422 | dev_err(pool->dev, "dma_pool_free %s, dma %Lx " | 421 | dev_err(pool->dev, "dma_pool_free %s, dma %Lx " |
423 | "already free\n", pool->name, | 422 | "already free\n", pool->name, |
@@ -432,7 +431,6 @@ void dma_pool_free(struct dma_pool *pool, void *vaddr, dma_addr_t dma) | |||
432 | memset(vaddr, POOL_POISON_FREED, pool->size); | 431 | memset(vaddr, POOL_POISON_FREED, pool->size); |
433 | #endif | 432 | #endif |
434 | 433 | ||
435 | spin_lock_irqsave(&pool->lock, flags); | ||
436 | page->in_use--; | 434 | page->in_use--; |
437 | *(int *)vaddr = page->offset; | 435 | *(int *)vaddr = page->offset; |
438 | page->offset = offset; | 436 | page->offset = offset; |