diff mbox series

[v2,1/2] audit: add global auditd_pid to make auditd_test_task() faster

Message ID 20230418110919.221578-2-eiichi.tsukata@nutanix.com (mailing list archive)
State Rejected
Delegated to: Paul Moore
Headers show
Series audit: syscall audit optimization (> +6% faster) | expand

Commit Message

Eiichi Tsukata April 18, 2023, 11:09 a.m. UTC
auditd_test_task() is a hot path of system call auditing. This patch
introduces a global auditd_pid pid struct which can be used for faster
check of registered audit daemon.

Benchmarks
==========

Run the following micro benchmarks:

  (1) dd:
    dd if=/dev/zero of=/dev/null bs=1 count=5M

  (2) UnixBench syscall:
    ./Run syscall -i 10 -c 1

With rule:

  -a never,exit -F arch=b64 -S uname

Results:

  (1) dd
    Base line    : 2.572 sec
    /w this patch: 2.418 sec (6.3% faster)

  (2) UnixBench syscall Index Score
    Base line    : 860
    /w this patch: 953 (10.8% faster)

Signed-off-by: Eiichi Tsukata <eiichi.tsukata@nutanix.com>
---
 kernel/audit.c | 39 +++++++++++----------------------------
 kernel/audit.h |  4 +++-
 2 files changed, 14 insertions(+), 29 deletions(-)

Comments

Paul Moore April 18, 2023, 1:19 p.m. UTC | #1
On Tue, Apr 18, 2023 at 7:10 AM Eiichi Tsukata
<eiichi.tsukata@nutanix.com> wrote:
>
> auditd_test_task() is a hot path of system call auditing. This patch
> introduces a global auditd_pid pid struct which can be used for faster
> check of registered audit daemon.
>
> Benchmarks
> ==========
>
> Run the following micro benchmarks:
>
>   (1) dd:
>     dd if=/dev/zero of=/dev/null bs=1 count=5M
>
>   (2) UnixBench syscall:
>     ./Run syscall -i 10 -c 1
>
> With rule:
>
>   -a never,exit -F arch=b64 -S uname
>
> Results:
>
>   (1) dd
>     Base line    : 2.572 sec
>     /w this patch: 2.418 sec (6.3% faster)
>
>   (2) UnixBench syscall Index Score
>     Base line    : 860
>     /w this patch: 953 (10.8% faster)
>
> Signed-off-by: Eiichi Tsukata <eiichi.tsukata@nutanix.com>
> ---
>  kernel/audit.c | 39 +++++++++++----------------------------
>  kernel/audit.h |  4 +++-
>  2 files changed, 14 insertions(+), 29 deletions(-)
>
> diff --git a/kernel/audit.c b/kernel/audit.c
> index 9bc0b0301198..9426980368e4 100644
> --- a/kernel/audit.c
> +++ b/kernel/audit.c
> @@ -71,6 +71,7 @@ static int    audit_initialized = AUDIT_UNINITIALIZED;
>
>  u32            audit_enabled = AUDIT_OFF;
>  bool           audit_ever_enabled = !!AUDIT_OFF;
> +struct pid      *auditd_pid;

As discussed previously, I want to keep the auditd tracking PID in the
auditd_connection struct.
diff mbox series

Patch

diff --git a/kernel/audit.c b/kernel/audit.c
index 9bc0b0301198..9426980368e4 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -71,6 +71,7 @@  static int	audit_initialized = AUDIT_UNINITIALIZED;
 
 u32		audit_enabled = AUDIT_OFF;
 bool		audit_ever_enabled = !!AUDIT_OFF;
+struct pid      *auditd_pid;
 
 EXPORT_SYMBOL_GPL(audit_enabled);
 
@@ -208,26 +209,6 @@  struct audit_reply {
 	struct sk_buff *skb;
 };
 
-/**
- * auditd_test_task - Check to see if a given task is an audit daemon
- * @task: the task to check
- *
- * Description:
- * Return 1 if the task is a registered audit daemon, 0 otherwise.
- */
-int auditd_test_task(struct task_struct *task)
-{
-	int rc;
-	struct auditd_connection *ac;
-
-	rcu_read_lock();
-	ac = rcu_dereference(auditd_conn);
-	rc = (ac && ac->pid == task_tgid(task) ? 1 : 0);
-	rcu_read_unlock();
-
-	return rc;
-}
-
 /**
  * audit_ctl_lock - Take the audit control lock
  */
@@ -512,6 +493,7 @@  static int auditd_set(struct pid *pid, u32 portid, struct net *net)
 	ac_old = rcu_dereference_protected(auditd_conn,
 					   lockdep_is_held(&auditd_conn_lock));
 	rcu_assign_pointer(auditd_conn, ac_new);
+	WRITE_ONCE(auditd_pid, ac_new->pid);
 	spin_unlock_irqrestore(&auditd_conn_lock, flags);
 
 	if (ac_old)
@@ -652,6 +634,7 @@  static void auditd_reset(const struct auditd_connection *ac)
 		return;
 	}
 	rcu_assign_pointer(auditd_conn, NULL);
+	WRITE_ONCE(auditd_pid, NULL);
 	spin_unlock_irqrestore(&auditd_conn_lock, flags);
 
 	if (ac_old)
@@ -1263,7 +1246,7 @@  static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
 			 *       run auditd from the initial pid namespace, but
 			 *       something to keep in mind if this changes */
 			pid_t new_pid = s.pid;
-			pid_t auditd_pid;
+			pid_t auditd_pid_nr;
 			struct pid *req_pid = task_tgid(current);
 
 			/* Sanity check - PID values must match. Setting
@@ -1274,18 +1257,18 @@  static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
 			/* test the auditd connection */
 			audit_replace(req_pid);
 
-			auditd_pid = auditd_pid_vnr();
-			if (auditd_pid) {
+			auditd_pid_nr = auditd_pid_vnr();
+			if (auditd_pid_nr) {
 				/* replacing a healthy auditd is not allowed */
 				if (new_pid) {
 					audit_log_config_change("audit_pid",
-							new_pid, auditd_pid, 0);
+							new_pid, auditd_pid_nr, 0);
 					return -EEXIST;
 				}
 				/* only current auditd can unregister itself */
-				if (pid_vnr(req_pid) != auditd_pid) {
+				if (pid_vnr(req_pid) != auditd_pid_nr) {
 					audit_log_config_change("audit_pid",
-							new_pid, auditd_pid, 0);
+							new_pid, auditd_pid_nr, 0);
 					return -EACCES;
 				}
 			}
@@ -1298,7 +1281,7 @@  static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
 				if (audit_enabled != AUDIT_OFF)
 					audit_log_config_change("audit_pid",
 								new_pid,
-								auditd_pid,
+								auditd_pid_nr,
 								err ? 0 : 1);
 				if (err)
 					return err;
@@ -1309,7 +1292,7 @@  static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
 				if (audit_enabled != AUDIT_OFF)
 					audit_log_config_change("audit_pid",
 								new_pid,
-								auditd_pid, 1);
+								auditd_pid_nr, 1);
 
 				/* unregister the auditd connection */
 				auditd_reset(NULL);
diff --git a/kernel/audit.h b/kernel/audit.h
index c57b008b9914..93074c2d4346 100644
--- a/kernel/audit.h
+++ b/kernel/audit.h
@@ -214,7 +214,9 @@  extern bool audit_ever_enabled;
 
 extern void audit_log_session_info(struct audit_buffer *ab);
 
-extern int auditd_test_task(struct task_struct *task);
+extern struct pid *auditd_pid;
+/* Check to see if a given task is an audit daemon */
+#define auditd_test_task(tsk) (READ_ONCE(auditd_pid) == task_tgid(tsk))
 
 #define AUDIT_INODE_BUCKETS	32
 extern struct list_head audit_inode_hash[AUDIT_INODE_BUCKETS];