audit_filter_uring(), audit_filter_inode_name() are substantially similar
to audit_filter_syscall(). Move the core logic to __audit_filter() which
can be parametrized for all three.

On a Skylakex system, getpid() latency (all results aggregated
across 12 boot cycles):

         Min     Mean    Median   Max      pstdev
         (ns)    (ns)    (ns)     (ns)

 -    173.11   182.51  179.65  202.09     (+- 4.34%)
 +    162.11   175.26  173.71  190.56     (+- 4.33%)

Performance counter stats for 'bin/getpid' (3 runs) go from:
    cycles               706.13  (  +-  4.13% )
    instructions        1654.70  (  +-   .06% )
    IPC                    2.35  (  +-  4.25% )
    branches             430.99  (  +-   .06% )
    branch-misses          0.50  (  +-  2.00% )
    L1-dcache-loads      440.02  (  +-   .07% )
    L1-dcache-load-misses  5.22  (  +- 82.75% )

 to:
    cycles               678.79  (  +-  4.22% )
    instructions        1657.79  (  +-   .05% )
    IPC                    2.45  (  +-  4.08% )
    branches             432.00  (  +-   .05% )
    branch-misses          0.38  (  +- 23.68% )
    L1-dcache-loads      444.96  (  +-   .03% )
    L1-dcache-load-misses  5.13  (  +- 73.09% )

(Both aggregated over 12 boot cycles.)

Unclear if the improvement is just run-to-run variation or because of
a slightly denser loop (the list parameter in the list_for_each_entry_rcu()
exit check now comes from a register rather than a constant as before.)

Signed-off-by: Ankur Arora <ankur.a.ar...@oracle.com>
---
 kernel/auditsc.c | 86 +++++++++++++++++++++++++-----------------------
 1 file changed, 44 insertions(+), 42 deletions(-)

diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index bf26f47b5226..dd89a52988b0 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -805,6 +805,41 @@ static bool audit_in_mask(const struct audit_krule *rule, 
unsigned long val)
        return rule->mask[word] & bit;
 }
 
+/**
+ * __audit_filter - common filter
+ *
+ * @tsk: associated task
+ * @ctx: audit context
+ * @list: audit filter list
+ * @op: current syscall/uring_op
+ * @name: name to be filtered (used by audit_filter_inode_name)
+ *
+ * return: 1 if we hit a filter, 0 if we don't
+ */
+static int __audit_filter(struct task_struct *tsk,
+                          struct audit_context *ctx,
+                          struct list_head *list,
+                          unsigned long op,
+                          struct audit_names *name)
+{
+       struct audit_entry *e;
+       enum audit_state state;
+
+       rcu_read_lock();
+       list_for_each_entry_rcu(e, list, list) {
+               if (unlikely(audit_in_mask(&e->rule, op))) {
+                       if (audit_filter_rules(tsk, &e->rule, ctx, name,
+                                              &state, false)) {
+                               rcu_read_unlock();
+                               ctx->current_state = state;
+                               return 1;
+                       }
+               }
+       }
+       rcu_read_unlock();
+       return 0;
+}
+
 /**
  * audit_filter_uring - apply filters to an io_uring operation
  * @tsk: associated task
@@ -813,24 +848,11 @@ static bool audit_in_mask(const struct audit_krule *rule, 
unsigned long val)
 static void audit_filter_uring(struct task_struct *tsk,
                               struct audit_context *ctx)
 {
-       struct audit_entry *e;
-       enum audit_state state;
-
        if (auditd_test_task(tsk))
                return;
 
-       rcu_read_lock();
-       list_for_each_entry_rcu(e, &audit_filter_list[AUDIT_FILTER_URING_EXIT],
-                               list) {
-               if (audit_in_mask(&e->rule, ctx->uring_op) &&
-                   audit_filter_rules(tsk, &e->rule, ctx, NULL, &state,
-                                      false)) {
-                       rcu_read_unlock();
-                       ctx->current_state = state;
-                       return;
-               }
-       }
-       rcu_read_unlock();
+       __audit_filter(tsk, ctx, &audit_filter_list[AUDIT_FILTER_URING_EXIT],
+                       ctx->uring_op, NULL);
 }
 
 /* At syscall exit time, this filter is called if the audit_state is
@@ -841,26 +863,11 @@ static void audit_filter_uring(struct task_struct *tsk,
 static void audit_filter_syscall(struct task_struct *tsk,
                                 struct audit_context *ctx)
 {
-       struct audit_entry *e;
-       enum audit_state state;
-       unsigned long major = ctx->major;
-
        if (auditd_test_task(tsk))
                return;
 
-       rcu_read_lock();
-       list_for_each_entry_rcu(e, &audit_filter_list[AUDIT_FILTER_EXIT], list) 
{
-               if (unlikely(audit_in_mask(&e->rule, major))) {
-                       if (audit_filter_rules(tsk, &e->rule, ctx, NULL,
-                                              &state, false)) {
-                               rcu_read_unlock();
-                               ctx->current_state = state;
-                               return;
-                       }
-               }
-       }
-       rcu_read_unlock();
-       return;
+       __audit_filter(tsk, ctx, &audit_filter_list[AUDIT_FILTER_EXIT],
+                       ctx->major, NULL);
 }
 
 /*
@@ -872,17 +879,12 @@ static int audit_filter_inode_name(struct task_struct 
*tsk,
                                   struct audit_context *ctx) {
        int h = audit_hash_ino((u32)n->ino);
        struct list_head *list = &audit_inode_hash[h];
-       struct audit_entry *e;
-       enum audit_state state;
 
-       list_for_each_entry_rcu(e, list, list) {
-               if (audit_in_mask(&e->rule, ctx->major) &&
-                   audit_filter_rules(tsk, &e->rule, ctx, n, &state, false)) {
-                       ctx->current_state = state;
-                       return 1;
-               }
-       }
-       return 0;
+       /*
+        * We are called holding an rcu read lock. __audit_filter() will take
+        * one as well.
+        */
+       return __audit_filter(tsk, ctx, list, ctx->major, n);
 }
 
 /* At syscall exit time, this filter is called if any audit_names have been
-- 
2.31.1

--
Linux-audit mailing list
Linux-audit@redhat.com
https://listman.redhat.com/mailman/listinfo/linux-audit

Reply via email to