Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c45b5c09 authored by Alexey Starikovskiy's avatar Alexey Starikovskiy Committed by Len Brown
Browse files

ACPICA: Performance enhancement for namespace search and access



This change enhances the performance of namespace searches and
walks by adding a backpointer to the parent in each namespace
node. On large namespaces, this change can improve overall ACPI
performance by up to 9X.  Adding a pointer to each namespace node
increases the overall size of the internal namespace by about 5%,
since each namespace entry usually consists of both a namespace
node and an ACPI operand object.

Signed-off-by: default avatarAlexey Starikovskiy <astarikovskiy@suse.de>
Signed-off-by: default avatarBob Moore <robert.moore@intel.com>
Signed-off-by: default avatarLin Ming <ming.m.lin@intel.com>
Signed-off-by: default avatarLen Brown <len.brown@intel.com>
parent 5821f754
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -184,8 +184,9 @@ struct acpi_namespace_node {
	u8 flags;		/* Miscellaneous flags */
	acpi_owner_id owner_id;	/* Node creator */
	union acpi_name_union name;	/* ACPI Name, always 4 chars per ACPI spec */
	struct acpi_namespace_node *parent;	/* Parent node */
	struct acpi_namespace_node *child;	/* First child */
	struct acpi_namespace_node *peer;	/* Peer. Parent if ANOBJ_END_OF_PEER_LIST set */
	struct acpi_namespace_node *peer;	/* First peer */

	/*
	 * The following fields are used by the ASL compiler and disassembler only
@@ -199,7 +200,7 @@ struct acpi_namespace_node {

/* Namespace Node flags */

#define ANOBJ_END_OF_PEER_LIST          0x01	/* End-of-list, Peer field points to parent */
#define ANOBJ_RESERVED                  0x01	/* Available for use */
#define ANOBJ_TEMPORARY                 0x02	/* Node is create by a method and is temporary */
#define ANOBJ_METHOD_ARG                0x04	/* Node is a method argument */
#define ANOBJ_METHOD_LOCAL              0x08	/* Node is a method local */
+0 −7
Original line number Diff line number Diff line
@@ -369,11 +369,4 @@ struct acpi_namespace_node *acpi_ns_validate_handle(acpi_handle handle);

void acpi_ns_terminate(void);

struct acpi_namespace_node *acpi_ns_get_parent_node(struct acpi_namespace_node
						    *node);

struct acpi_namespace_node *acpi_ns_get_next_valid_node(struct
							acpi_namespace_node
							*node);

#endif				/* __ACNAMESP_H__ */
+2 −4
Original line number Diff line number Diff line
@@ -102,8 +102,7 @@ void acpi_ds_method_data_init(struct acpi_walk_state *walk_state)
		walk_state->arguments[i].name.integer |= (i << 24);
		walk_state->arguments[i].descriptor_type = ACPI_DESC_TYPE_NAMED;
		walk_state->arguments[i].type = ACPI_TYPE_ANY;
		walk_state->arguments[i].flags =
		    ANOBJ_END_OF_PEER_LIST | ANOBJ_METHOD_ARG;
		walk_state->arguments[i].flags = ANOBJ_METHOD_ARG;
	}

	/* Init the method locals */
@@ -116,8 +115,7 @@ void acpi_ds_method_data_init(struct acpi_walk_state *walk_state)
		walk_state->local_variables[i].descriptor_type =
		    ACPI_DESC_TYPE_NAMED;
		walk_state->local_variables[i].type = ACPI_TYPE_ANY;
		walk_state->local_variables[i].flags =
		    ANOBJ_END_OF_PEER_LIST | ANOBJ_METHOD_LOCAL;
		walk_state->local_variables[i].flags = ANOBJ_METHOD_LOCAL;
	}

	return_VOID;
+3 −3
Original line number Diff line number Diff line
@@ -213,7 +213,7 @@ acpi_ds_get_buffer_field_arguments(union acpi_operand_object *obj_desc)

	/* Execute the AML code for the term_arg arguments */

	status = acpi_ds_execute_arguments(node, acpi_ns_get_parent_node(node),
	status = acpi_ds_execute_arguments(node, node->parent,
					   extra_desc->extra.aml_length,
					   extra_desc->extra.aml_start);
	return_ACPI_STATUS(status);
@@ -257,7 +257,7 @@ acpi_ds_get_bank_field_arguments(union acpi_operand_object *obj_desc)

	/* Execute the AML code for the term_arg arguments */

	status = acpi_ds_execute_arguments(node, acpi_ns_get_parent_node(node),
	status = acpi_ds_execute_arguments(node, node->parent,
					   extra_desc->extra.aml_length,
					   extra_desc->extra.aml_start);
	return_ACPI_STATUS(status);
@@ -394,7 +394,7 @@ acpi_status acpi_ds_get_region_arguments(union acpi_operand_object *obj_desc)

	/* Execute the argument AML */

	status = acpi_ds_execute_arguments(node, acpi_ns_get_parent_node(node),
	status = acpi_ds_execute_arguments(node, node->parent,
					   extra_desc->extra.aml_length,
					   extra_desc->extra.aml_start);
	if (ACPI_FAILURE(status)) {
+5 −5
Original line number Diff line number Diff line
@@ -199,7 +199,7 @@ acpi_ev_pci_config_region_setup(acpi_handle handle,
		return_ACPI_STATUS(status);
	}

	parent_node = acpi_ns_get_parent_node(region_obj->region.node);
	parent_node = region_obj->region.node->parent;

	/*
	 * Get the _SEG and _BBN values from the device upon which the handler
@@ -248,7 +248,7 @@ acpi_ev_pci_config_region_setup(acpi_handle handle,
				break;
			}

			pci_root_node = acpi_ns_get_parent_node(pci_root_node);
			pci_root_node = pci_root_node->parent;
		}

		/* PCI root bridge not found, use namespace root node */
@@ -280,7 +280,7 @@ acpi_ev_pci_config_region_setup(acpi_handle handle,
	 */
	pci_device_node = region_obj->region.node;
	while (pci_device_node && (pci_device_node->type != ACPI_TYPE_DEVICE)) {
		pci_device_node = acpi_ns_get_parent_node(pci_device_node);
		pci_device_node = pci_device_node->parent;
	}

	if (!pci_device_node) {
@@ -521,7 +521,7 @@ acpi_ev_initialize_region(union acpi_operand_object *region_obj,
		return_ACPI_STATUS(AE_NOT_EXIST);
	}

	node = acpi_ns_get_parent_node(region_obj->region.node);
	node = region_obj->region.node->parent;
	space_id = region_obj->region.space_id;

	/* Setup defaults */
@@ -654,7 +654,7 @@ acpi_ev_initialize_region(union acpi_operand_object *region_obj,

		/* This node does not have the handler we need; Pop up one level */

		node = acpi_ns_get_parent_node(node);
		node = node->parent;
	}

	/* If we get here, there is no handler for this region */
Loading