@@ -197,6 +197,8 @@ acpi_ev_execute_reg_method(union acpi_operand_object *region_obj, u32 function);
/*
* evregini - Region initialization and setup
*/
+void acpi_ev_system_release_memory_mappings(void);
+
acpi_status
acpi_ev_system_memory_region_setup(acpi_handle handle,
u32 function,
@@ -8,6 +8,7 @@
#include <acpi/acpi.h>
#include "accommon.h"
#include "acdebug.h"
+#include "acevents.h"
#include "acnamesp.h"
#include "acpredef.h"
#include "acinterp.h"
@@ -768,6 +769,8 @@ acpi_db_test_field_unit_type(union acpi_operand_object *obj_desc)
acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
acpi_ut_release_mutex(ACPI_MTX_INTERPRETER);
+ acpi_ev_system_release_memory_mappings();
+
bit_length = obj_desc->common_field.bit_length;
byte_length = ACPI_ROUND_BITS_UP_TO_BYTES(bit_length);
@@ -16,6 +16,52 @@
#define _COMPONENT ACPI_EVENTS
ACPI_MODULE_NAME("evrgnini")
+#ifdef ACPI_OS_MAP_MEMORY_FAST_PATH
+static struct acpi_mem_mapping *unused_memory_mappings;
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ev_system_release_memory_mappings
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Release all of the unused memory mappings in the queue
+ * under the interpreter mutex.
+ *
+ ******************************************************************************/
+void acpi_ev_system_release_memory_mappings(void)
+{
+ struct acpi_mem_mapping *mapping;
+
+ ACPI_FUNCTION_TRACE(acpi_ev_system_release_memory_mappings);
+
+ acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
+
+ while (unused_memory_mappings) {
+ mapping = unused_memory_mappings;
+ unused_memory_mappings = mapping->next;
+
+ acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
+
+ acpi_os_unmap_memory(mapping->logical_address, mapping->length);
+ ACPI_FREE(mapping);
+
+ acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
+ }
+
+ acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
+
+ return_VOID;
+}
+#else /* !ACPI_OS_MAP_MEMORY_FAST_PATH */
+void acpi_ev_system_release_memory_mappings(void)
+{
+ return_VOID;
+}
+#endif /* !ACPI_OS_MAP_MEMORY_FAST_PATH */
+
/*******************************************************************************
*
* FUNCTION: acpi_ev_system_memory_region_setup
@@ -60,9 +106,8 @@ acpi_ev_system_memory_region_setup(acpi_handle handle,
while (local_region_context->first_mapping) {
mapping = local_region_context->first_mapping;
local_region_context->first_mapping = mapping->next;
- acpi_os_unmap_memory(mapping->logical_address,
- mapping->length);
- ACPI_FREE(mapping);
+ mapping->next = unused_memory_mappings;
+ unused_memory_mappings = mapping;
}
#endif
}
@@ -25,6 +25,7 @@
#include <acpi/acpi.h>
#include "accommon.h"
+#include "acevents.h"
#include "acinterp.h"
#include "amlcode.h"
@@ -106,6 +107,8 @@ void acpi_ex_exit_interpreter(void)
"Could not release AML Interpreter mutex"));
}
+ acpi_ev_system_release_memory_mappings();
+
return_VOID;
}
@@ -11,6 +11,7 @@
#include <acpi/acpi.h>
#include "accommon.h"
+#include "acevents.h"
#include "acdebug.h"
#define _COMPONENT ACPI_UTILITIES
@@ -244,6 +245,28 @@ acpi_status acpi_purge_cached_objects(void)
ACPI_EXPORT_SYMBOL(acpi_purge_cached_objects)
+/*****************************************************************************
+ *
+ * FUNCTION: acpi_release_unused_memory_mappings
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Remove memory mappings that are not used any more.
+ *
+ ****************************************************************************/
+void acpi_release_unused_memory_mappings(void)
+{
+ ACPI_FUNCTION_TRACE(acpi_release_unused_memory_mappings);
+
+ acpi_ev_system_release_memory_mappings();
+
+ return_VOID;
+}
+
+ACPI_EXPORT_SYMBOL(acpi_release_unused_memory_mappings)
+
/*****************************************************************************
*
* FUNCTION: acpi_install_interface
@@ -449,6 +449,7 @@ ACPI_EXTERNAL_RETURN_STATUS(acpi_status
acpi_size length,
struct acpi_pld_info
**return_buffer))
+ACPI_EXTERNAL_RETURN_VOID(void acpi_release_unused_memory_mappings(void))
/*
* ACPI table load/unload interfaces