aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorRafael J. Wysocki <rjw@sisk.pl>2011-02-08 17:38:15 -0500
committerRafael J. Wysocki <rjw@sisk.pl>2011-02-24 13:58:42 -0500
commitb7c1fadd6c2eead56d0664a3a921980120de0c11 (patch)
treeccd0788ca079460db52be43c6f6e0273e300891a /drivers
parent7ffd0443f2502478545e23e194b7eb8e16376072 (diff)
ACPI: Do not use krefs under a mutex in osl.c
The reference counting of ACPI iomaps is carried out entirely under acpi_ioremap_lock, so it is sufficient to use simple counters instead of krefs for this purpose. Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/acpi/osl.c36
1 files changed, 16 insertions, 20 deletions
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 445f205752a2..5389f9f2e2ff 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -105,7 +105,7 @@ struct acpi_ioremap {
105 void __iomem *virt; 105 void __iomem *virt;
106 acpi_physical_address phys; 106 acpi_physical_address phys;
107 acpi_size size; 107 acpi_size size;
108 struct kref ref; 108 unsigned long refcount;
109}; 109};
110 110
111static LIST_HEAD(acpi_ioremaps); 111static LIST_HEAD(acpi_ioremaps);
@@ -319,7 +319,7 @@ acpi_os_map_memory(acpi_physical_address phys, acpi_size size)
319 /* Check if there's a suitable mapping already. */ 319 /* Check if there's a suitable mapping already. */
320 map = acpi_map_lookup(phys, size); 320 map = acpi_map_lookup(phys, size);
321 if (map) { 321 if (map) {
322 kref_get(&map->ref); 322 map->refcount++;
323 goto out; 323 goto out;
324 } 324 }
325 325
@@ -342,7 +342,7 @@ acpi_os_map_memory(acpi_physical_address phys, acpi_size size)
342 map->virt = virt; 342 map->virt = virt;
343 map->phys = pg_off; 343 map->phys = pg_off;
344 map->size = pg_sz; 344 map->size = pg_sz;
345 kref_init(&map->ref); 345 map->refcount = 1;
346 346
347 list_add_tail_rcu(&map->list, &acpi_ioremaps); 347 list_add_tail_rcu(&map->list, &acpi_ioremaps);
348 348
@@ -352,25 +352,24 @@ acpi_os_map_memory(acpi_physical_address phys, acpi_size size)
352} 352}
353EXPORT_SYMBOL_GPL(acpi_os_map_memory); 353EXPORT_SYMBOL_GPL(acpi_os_map_memory);
354 354
355static void acpi_kref_del_iomap(struct kref *ref) 355static void acpi_os_drop_map_ref(struct acpi_ioremap *map)
356{ 356{
357 struct acpi_ioremap *map; 357 if (!--map->refcount)
358 358 list_del_rcu(&map->list);
359 map = container_of(ref, struct acpi_ioremap, ref);
360 list_del_rcu(&map->list);
361} 359}
362 360
363static void acpi_os_remove_map(struct acpi_ioremap *map) 361static void acpi_os_map_cleanup(struct acpi_ioremap *map)
364{ 362{
365 synchronize_rcu(); 363 if (!map->refcount) {
366 iounmap(map->virt); 364 synchronize_rcu();
367 kfree(map); 365 iounmap(map->virt);
366 kfree(map);
367 }
368} 368}
369 369
370void __ref acpi_os_unmap_memory(void __iomem *virt, acpi_size size) 370void __ref acpi_os_unmap_memory(void __iomem *virt, acpi_size size)
371{ 371{
372 struct acpi_ioremap *map; 372 struct acpi_ioremap *map;
373 int del;
374 373
375 if (!acpi_gbl_permanent_mmap) { 374 if (!acpi_gbl_permanent_mmap) {
376 __acpi_unmap_table(virt, size); 375 __acpi_unmap_table(virt, size);
@@ -384,11 +383,10 @@ void __ref acpi_os_unmap_memory(void __iomem *virt, acpi_size size)
384 WARN(true, PREFIX "%s: bad address %p\n", __func__, virt); 383 WARN(true, PREFIX "%s: bad address %p\n", __func__, virt);
385 return; 384 return;
386 } 385 }
387 del = kref_put(&map->ref, acpi_kref_del_iomap); 386 acpi_os_drop_map_ref(map);
388 mutex_unlock(&acpi_ioremap_lock); 387 mutex_unlock(&acpi_ioremap_lock);
389 388
390 if (del) 389 acpi_os_map_cleanup(map);
391 acpi_os_remove_map(map);
392} 390}
393EXPORT_SYMBOL_GPL(acpi_os_unmap_memory); 391EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
394 392
@@ -418,7 +416,6 @@ static int acpi_os_map_generic_address(struct acpi_generic_address *addr)
418static void acpi_os_unmap_generic_address(struct acpi_generic_address *addr) 416static void acpi_os_unmap_generic_address(struct acpi_generic_address *addr)
419{ 417{
420 struct acpi_ioremap *map; 418 struct acpi_ioremap *map;
421 int del;
422 419
423 if (addr->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) 420 if (addr->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY)
424 return; 421 return;
@@ -432,11 +429,10 @@ static void acpi_os_unmap_generic_address(struct acpi_generic_address *addr)
432 mutex_unlock(&acpi_ioremap_lock); 429 mutex_unlock(&acpi_ioremap_lock);
433 return; 430 return;
434 } 431 }
435 del = kref_put(&map->ref, acpi_kref_del_iomap); 432 acpi_os_drop_map_ref(map);
436 mutex_unlock(&acpi_ioremap_lock); 433 mutex_unlock(&acpi_ioremap_lock);
437 434
438 if (del) 435 acpi_os_map_cleanup(map);
439 acpi_os_remove_map(map);
440} 436}
441 437
442#ifdef ACPI_FUTURE_USAGE 438#ifdef ACPI_FUTURE_USAGE