MEDIUM: map/acl: Improve pat_ref_set_elt() efficiency (for "set-map", "add-acl"action perfs)

Store a pointer to the expression (struct pattern_expr) into the data structure
used to chain/store the map element references (struct pat_ref_elt) , e.g. the
struct pattern_tree when stored into an ebtree or struct pattern_list when
chained to a list.

Modify pat_ref_set_elt() to stop inspecting all the expressions attached to a map
and to look for the <elt> element passed as parameter to retrieve the sample data
to be parsed. Indeed, thanks to the pointer added above to each pattern tree nodes
or list elements, they all can be inspected directly from the <elt> passed as
parameter and its ->tree_head and ->list_head member: the pattern tree nodes are
stored into elt->tree_head, and the pattern list elements are chained to
elt->list_head list. This inspection was also the job of pattern_find_smp() which
is no more useful. This patch removes the code of this function.
This commit is contained in:
Frdric Lcaille 2023-08-23 15:58:26 +02:00 committed by Willy Tarreau
parent 0844bed7d3
commit 745d1a269b
2 changed files with 47 additions and 39 deletions

View File

@ -138,6 +138,7 @@ struct pattern_tree {
void *from_ref; // pattern_tree linked from pat_ref_elt, ends with NULL
struct sample_data *data;
struct pat_ref_elt *ref;
struct pattern_expr *expr;
struct ebmb_node node;
};
@ -183,6 +184,7 @@ struct pattern_list {
void *from_ref; // pattern_tree linked from pat_ref_elt, ends with NULL
struct list list;
struct pattern pat;
struct pattern_expr *expr;
};
/* Description of a pattern expression.

View File

@ -1204,6 +1204,7 @@ int pat_idx_list_val(struct pattern_expr *expr, struct pattern *pat, char **err)
/* chain pattern in the expression */
LIST_APPEND(&expr->patterns, &patl->list);
patl->expr = expr;
/* and from the reference */
patl->from_ref = pat->ref->list_head;
pat->ref->list_head = &patl->from_ref;
@ -1237,6 +1238,7 @@ int pat_idx_list_ptr(struct pattern_expr *expr, struct pattern *pat, char **err)
/* chain pattern in the expression */
LIST_APPEND(&expr->patterns, &patl->list);
patl->expr = expr;
/* and from the reference */
patl->from_ref = pat->ref->list_head;
pat->ref->list_head = &patl->from_ref;
@ -1271,6 +1273,7 @@ int pat_idx_list_str(struct pattern_expr *expr, struct pattern *pat, char **err)
/* chain pattern in the expression */
LIST_APPEND(&expr->patterns, &patl->list);
patl->expr = expr;
/* and from the reference */
patl->from_ref = pat->ref->list_head;
pat->ref->list_head = &patl->from_ref;
@ -1305,6 +1308,7 @@ int pat_idx_list_reg_cap(struct pattern_expr *expr, struct pattern *pat, int cap
/* chain pattern in the expression */
LIST_APPEND(&expr->patterns, &patl->list);
patl->expr = expr;
/* and from the reference */
patl->from_ref = pat->ref->list_head;
pat->ref->list_head = &patl->from_ref;
@ -1358,6 +1362,8 @@ int pat_idx_tree_ip(struct pattern_expr *expr, struct pattern *pat, char **err)
/* Insert the entry. */
ebmb_insert_prefix(&expr->pattern_tree, &node->node, 4);
node->expr = expr;
node->from_ref = pat->ref->tree_head;
pat->ref->tree_head = &node->from_ref;
expr->ref->revision = rdtsc();
@ -1389,6 +1395,8 @@ int pat_idx_tree_ip(struct pattern_expr *expr, struct pattern *pat, char **err)
/* Insert the entry. */
ebmb_insert_prefix(&expr->pattern_tree_2, &node->node, 16);
node->expr = expr;
node->from_ref = pat->ref->tree_head;
pat->ref->tree_head = &node->from_ref;
expr->ref->revision = rdtsc();
@ -1436,6 +1444,8 @@ int pat_idx_tree_str(struct pattern_expr *expr, struct pattern *pat, char **err)
/* index the new node */
ebst_insert(&expr->pattern_tree, &node->node);
node->expr = expr;
node->from_ref = pat->ref->tree_head;
pat->ref->tree_head = &node->from_ref;
expr->ref->revision = rdtsc();
@ -1481,6 +1491,8 @@ int pat_idx_tree_pfx(struct pattern_expr *expr, struct pattern *pat, char **err)
/* index the new node */
ebmb_insert_prefix(&expr->pattern_tree, &node->node, len);
node->expr = expr;
node->from_ref = pat->ref->tree_head;
pat->ref->tree_head = &node->from_ref;
expr->ref->revision = rdtsc();
@ -1697,6 +1709,10 @@ static inline int pat_ref_set_elt(struct pat_ref *ref, struct pat_ref_elt *elt,
struct sample_data **data;
char *sample;
struct sample_data test;
struct pattern_tree *tree;
struct pattern_list *pat;
void **node;
/* Try all needed converters. */
list_for_each_entry(expr, &ref->pat, list) {
@ -1718,15 +1734,38 @@ static inline int pat_ref_set_elt(struct pat_ref *ref, struct pat_ref_elt *elt,
/* Load sample in each reference. All the conversions are tested
* below, normally these calls don't fail.
*/
list_for_each_entry(expr, &ref->pat, list) {
for (node = elt->tree_head; node;) {
tree = container_of(node, struct pattern_tree, from_ref);
node = *node;
BUG_ON(tree->ref != elt);
expr = tree->expr;
if (!expr->pat_head->parse_smp)
continue;
HA_RWLOCK_WRLOCK(PATEXP_LOCK, &expr->lock);
data = pattern_find_smp(expr, elt);
if (data && *data && !expr->pat_head->parse_smp(sample, *data))
*data = NULL;
HA_RWLOCK_WRUNLOCK(PATEXP_LOCK, &expr->lock);
data = &tree->data;
if (data && *data) {
HA_RWLOCK_WRLOCK(PATEXP_LOCK, &expr->lock);
if (!expr->pat_head->parse_smp(sample, *data))
*data = NULL;
HA_RWLOCK_WRUNLOCK(PATEXP_LOCK, &expr->lock);
}
}
for (node = elt->list_head; node;) {
pat = container_of(node, struct pattern_list, from_ref);
node = *node;
BUG_ON(pat->pat.ref != elt);
expr = pat->expr;
if (!expr->pat_head->parse_smp)
continue;
data = &pat->pat.data;
if (data && *data) {
HA_RWLOCK_WRLOCK(PATEXP_LOCK, &expr->lock);
if (!expr->pat_head->parse_smp(sample, *data))
*data = NULL;
HA_RWLOCK_WRUNLOCK(PATEXP_LOCK, &expr->lock);
}
}
/* free old sample only when all exprs are updated */
@ -2581,39 +2620,6 @@ void pattern_prune(struct pattern_head *head)
}
}
/* This function searches occurrences of pattern reference element <ref> in
* expression <expr> and returns a pointer to a pointer of the sample storage.
* If <ref> is not found, NULL is returned.
*/
struct sample_data **pattern_find_smp(struct pattern_expr *expr, struct pat_ref_elt *ref)
{
struct ebmb_node *node;
struct pattern_tree *elt;
struct pattern_list *pat;
for (node = ebmb_first(&expr->pattern_tree);
node;
node = ebmb_next(node)) {
elt = container_of(node, struct pattern_tree, node);
if (elt->ref == ref)
return &elt->data;
}
for (node = ebmb_first(&expr->pattern_tree_2);
node;
node = ebmb_next(node)) {
elt = container_of(node, struct pattern_tree, node);
if (elt->ref == ref)
return &elt->data;
}
list_for_each_entry(pat, &expr->patterns, list)
if (pat->pat.ref == ref)
return &pat->pat.data;
return NULL;
}
/* This function compares two pat_ref** on their unique_id, and returns -1/0/1
* depending on their order (suitable for sorting).
*/