diff options
| author | Rafael J. Wysocki <rjw@sisk.pl> | 2011-02-08 17:37:53 -0500 |
|---|---|---|
| committer | Rafael J. Wysocki <rjw@sisk.pl> | 2011-02-24 13:58:41 -0500 |
| commit | 7fe135dc058faea0ce319a03e3b6f98c5049955c (patch) | |
| tree | ecd7f70c02bb15ff36749f9db4d8c9d14af4f623 /drivers | |
| parent | 7bbb890358b96cb6f77adc6815f2072bdf813d5d (diff) | |
ACPI: Avoid walking the list of memory mappings in osl.c twice in a row
Make acpi_os_unmap_generic_address() use acpi_map_lookup() to find
the desired iomap and drop the reference to it directly (and
eventually remove it if necessary) instead of calling
acpi_os_unmap_memory(), which requires us to walk the list of ACPI
iomaps twice in a row (first, to get the virtual address associated
with the iomap and second, to get the iomap itself).
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/acpi/osl.c | 33 |
1 files changed, 20 insertions, 13 deletions
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 97061928249a..f6785bced215 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c | |||
| @@ -358,6 +358,13 @@ static void acpi_kref_del_iomap(struct kref *ref) | |||
| 358 | list_del_rcu(&map->list); | 358 | list_del_rcu(&map->list); |
| 359 | } | 359 | } |
| 360 | 360 | ||
| 361 | static void acpi_os_remove_map(struct acpi_ioremap *map) | ||
| 362 | { | ||
| 363 | synchronize_rcu(); | ||
| 364 | iounmap(map->virt); | ||
| 365 | kfree(map); | ||
| 366 | } | ||
| 367 | |||
| 361 | void __ref acpi_os_unmap_memory(void __iomem *virt, acpi_size size) | 368 | void __ref acpi_os_unmap_memory(void __iomem *virt, acpi_size size) |
| 362 | { | 369 | { |
| 363 | struct acpi_ioremap *map; | 370 | struct acpi_ioremap *map; |
| @@ -372,20 +379,14 @@ void __ref acpi_os_unmap_memory(void __iomem *virt, acpi_size size) | |||
| 372 | map = acpi_map_lookup_virt(virt, size); | 379 | map = acpi_map_lookup_virt(virt, size); |
| 373 | if (!map) { | 380 | if (!map) { |
| 374 | mutex_unlock(&acpi_ioremap_lock); | 381 | mutex_unlock(&acpi_ioremap_lock); |
| 375 | printk(KERN_ERR PREFIX "%s: bad address %p\n", __func__, virt); | 382 | WARN(true, PREFIX "%s: bad address %p\n", __func__, virt); |
| 376 | dump_stack(); | ||
| 377 | return; | 383 | return; |
| 378 | } | 384 | } |
| 379 | |||
| 380 | del = kref_put(&map->ref, acpi_kref_del_iomap); | 385 | del = kref_put(&map->ref, acpi_kref_del_iomap); |
| 381 | mutex_unlock(&acpi_ioremap_lock); | 386 | mutex_unlock(&acpi_ioremap_lock); |
| 382 | 387 | ||
| 383 | if (!del) | 388 | if (del) |
| 384 | return; | 389 | acpi_os_remove_map(map); |
| 385 | |||
| 386 | synchronize_rcu(); | ||
| 387 | iounmap(map->virt); | ||
| 388 | kfree(map); | ||
| 389 | } | 390 | } |
| 390 | EXPORT_SYMBOL_GPL(acpi_os_unmap_memory); | 391 | EXPORT_SYMBOL_GPL(acpi_os_unmap_memory); |
| 391 | 392 | ||
| @@ -414,8 +415,8 @@ static int acpi_os_map_generic_address(struct acpi_generic_address *addr) | |||
| 414 | 415 | ||
| 415 | static void acpi_os_unmap_generic_address(struct acpi_generic_address *addr) | 416 | static void acpi_os_unmap_generic_address(struct acpi_generic_address *addr) |
| 416 | { | 417 | { |
| 417 | void __iomem *virt; | 418 | struct acpi_ioremap *map; |
| 418 | acpi_size size = addr->bit_width / 8; | 419 | int del; |
| 419 | 420 | ||
| 420 | if (addr->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) | 421 | if (addr->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) |
| 421 | return; | 422 | return; |
| @@ -424,10 +425,16 @@ static void acpi_os_unmap_generic_address(struct acpi_generic_address *addr) | |||
| 424 | return; | 425 | return; |
| 425 | 426 | ||
| 426 | mutex_lock(&acpi_ioremap_lock); | 427 | mutex_lock(&acpi_ioremap_lock); |
| 427 | virt = acpi_map_vaddr_lookup(addr->address, size); | 428 | map = acpi_map_lookup(addr->address, addr->bit_width / 8); |
| 429 | if (!map) { | ||
| 430 | mutex_unlock(&acpi_ioremap_lock); | ||
| 431 | return; | ||
| 432 | } | ||
| 433 | del = kref_put(&map->ref, acpi_kref_del_iomap); | ||
| 428 | mutex_unlock(&acpi_ioremap_lock); | 434 | mutex_unlock(&acpi_ioremap_lock); |
| 429 | 435 | ||
| 430 | acpi_os_unmap_memory(virt, size); | 436 | if (del) |
| 437 | acpi_os_remove_map(map); | ||
| 431 | } | 438 | } |
| 432 | 439 | ||
| 433 | #ifdef ACPI_FUTURE_USAGE | 440 | #ifdef ACPI_FUTURE_USAGE |
