Commit 84bc227d7fde049a568cd58a5610613feedc0dff

Authored by Rolf Eike Beer
Committed by Linus Torvalds
1 parent 43506fad21

mm/dmapool.c: take lock only once in dma_pool_free()

dma_pool_free() scans for the page to free in the pool list holding the
pool lock.  Then it releases the lock basically to acquire it immediately
again.  Modify the code to only take the lock once.

This will do some additional loops and computations with the lock held in
if memory debugging is activated.  If it is not activated the only new
operations with this lock is one if and one substraction.

Signed-off-by: Rolf Eike Beer <eike-kernel@sf-tec.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

Showing 1 changed file with 6 additions and 8 deletions Side-by-side Diff

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