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/acpi/osl.c | |
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/acpi/osl.c')
-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 |