@@ -40,6 +40,7 @@
#include <linux/nmi.h>
#include <linux/acpi.h>
#include <linux/efi.h>
+#include <linux/async.h>
#include <linux/ioport.h>
#include <linux/list.h>
#include <linux/jiffies.h>
@@ -94,6 +95,7 @@ struct acpi_ioremap {
acpi_physical_address phys;
acpi_size size;
unsigned long refcount;
+ struct rcu_head rcu;
};
static LIST_HEAD(acpi_ioremaps);
@@ -423,13 +425,25 @@ static void acpi_os_drop_map_ref(struct acpi_ioremap *map)
list_del_rcu(&map->list);
}
+static void acpi_os_async_umap(void *data, async_cookie_t cookie)
+{
+ struct acpi_ioremap *map = data;
+
+ acpi_unmap(map->phys, map->virt);
+ kfree(map);
+}
+
+static void acpi_os_map_reclaim(struct rcu_head *rcu)
+{
+ struct acpi_ioremap *map = container_of(rcu, struct acpi_ioremap, rcu);
+
+ async_schedule(acpi_os_async_umap, map);
+}
+
static void acpi_os_map_cleanup(struct acpi_ioremap *map)
{
- if (!map->refcount) {
- synchronize_rcu();
- acpi_unmap(map->phys, map->virt);
- kfree(map);
- }
+ if (!map->refcount)
+ call_rcu(&map->rcu, acpi_os_map_reclaim);
}
void __ref acpi_os_unmap_iomem(void __iomem *virt, acpi_size size)