Skip to content

Commit c8a3dfe

Browse files
rprobainapcmoore
authored andcommitted
audit: merge loops in __audit_inode_child()
Whenever there's audit context, __audit_inode_child() gets called numerous times, which can lead to high latency in scenarios that create too many sysfs/debugfs entries at once, for instance, upon device_add_disk() invocation. # uname -r 6.18.0-rc2+ # auditctl -a always,exit -F path=/tmp -k foo # time insmod loop max_loop=1000 real 0m46.676s user 0m0.000s sys 0m46.405s # perf record -a insmod loop max_loop=1000 # perf report --stdio |grep __audit_inode_child 32.73% insmod [kernel.kallsyms] [k] __audit_inode_child __audit_inode_child() searches for both the parent and the child in two different loops that iterate over the same list. This process can be optimized by merging these into a single loop, without changing the function behavior or affecting the code's readability. This patch merges the two loops that walk through the list context->names_list into a single loop. This optimization resulted in around 51% performance enhancement for the benchmark. # uname -r 6.18.0-rc2-enhancedv3+ # auditctl -a always,exit -F path=/tmp -k foo # time insmod loop max_loop=1000 real 0m22.899s user 0m0.001s sys 0m22.652s Signed-off-by: Ricardo Robaina <rrobaina@redhat.com> Signed-off-by: Paul Moore <paul@paul-moore.com>
1 parent 77563f3 commit c8a3dfe

1 file changed

Lines changed: 19 additions & 24 deletions

File tree

kernel/auditsc.c

Lines changed: 19 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2416,41 +2416,36 @@ void __audit_inode_child(struct inode *parent,
24162416
if (inode)
24172417
handle_one(inode);
24182418

2419-
/* look for a parent entry first */
24202419
list_for_each_entry(n, &context->names_list, list) {
2421-
if (!n->name ||
2422-
(n->type != AUDIT_TYPE_PARENT &&
2423-
n->type != AUDIT_TYPE_UNKNOWN))
2420+
/* can only match entries that have a name */
2421+
if (!n->name)
24242422
continue;
24252423

2426-
if (n->ino == parent->i_ino && n->dev == parent->i_sb->s_dev &&
2427-
!audit_compare_dname_path(dname,
2428-
n->name->name, n->name_len)) {
2429-
if (n->type == AUDIT_TYPE_UNKNOWN)
2430-
n->type = AUDIT_TYPE_PARENT;
2424+
/* look for a parent entry first */
2425+
if (!found_parent &&
2426+
(n->type == AUDIT_TYPE_PARENT || n->type == AUDIT_TYPE_UNKNOWN) &&
2427+
(n->ino == parent->i_ino && n->dev == parent->i_sb->s_dev &&
2428+
!audit_compare_dname_path(dname, n->name->name, n->name_len))) {
2429+
n->type = AUDIT_TYPE_PARENT;
24312430
found_parent = n;
2432-
break;
2433-
}
2434-
}
2435-
2436-
cond_resched();
2437-
2438-
/* is there a matching child entry? */
2439-
list_for_each_entry(n, &context->names_list, list) {
2440-
/* can only match entries that have a name */
2441-
if (!n->name ||
2442-
(n->type != type && n->type != AUDIT_TYPE_UNKNOWN))
2431+
if (found_child)
2432+
break;
24432433
continue;
2434+
}
24442435

2445-
if (!strcmp(dname->name, n->name->name) ||
2446-
!audit_compare_dname_path(dname, n->name->name,
2436+
/* is there a matching child entry? */
2437+
if (!found_child &&
2438+
(n->type == type || n->type == AUDIT_TYPE_UNKNOWN) &&
2439+
(!strcmp(dname->name, n->name->name) ||
2440+
!audit_compare_dname_path(dname, n->name->name,
24472441
found_parent ?
24482442
found_parent->name_len :
2449-
AUDIT_NAME_FULL)) {
2443+
AUDIT_NAME_FULL))) {
24502444
if (n->type == AUDIT_TYPE_UNKNOWN)
24512445
n->type = type;
24522446
found_child = n;
2453-
break;
2447+
if (found_parent)
2448+
break;
24542449
}
24552450
}
24562451

0 commit comments

Comments
 (0)