aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorDan Duval <dan.duval@oracle.com>2013-09-16 11:11:12 -0400
committerEric Paris <eparis@redhat.com>2014-01-13 22:28:08 -0500
commitdb897319401e1c111aef59deadd59ea08e11d879 (patch)
tree2bad7e546ecc69874e18a5846b01c4bc315dfaa3 /kernel
parentae887e0bdcddb9d7acd8f1eb7b7795b438aa4950 (diff)
audit: efficiency fix 1: only wake up if queue shorter than backlog limit
These and similar errors were seen on a patched 3.8 kernel when the audit subsystem was overrun during boot: udevd[876]: worker [887] unexpectedly returned with status 0x0100 udevd[876]: worker [887] failed while handling '/devices/pci0000:00/0000:00:03.0/0000:40:00.0' udevd[876]: worker [880] unexpectedly returned with status 0x0100 udevd[876]: worker [880] failed while handling '/devices/LNXSYSTM:00/LNXPWRBN:00/input/input1/event1' udevadm settle - timeout of 180 seconds reached, the event queue contains: /sys/devices/LNXSYSTM:00/LNXPWRBN:00/input/input1/event1 (3995) /sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/INT3F0D:00 (4034) audit: audit_backlog=258 > audit_backlog_limit=256 audit: audit_lost=1 audit_rate_limit=0 audit_backlog_limit=256 The change below increases the efficiency of the audit code and prevents it from being overrun: Only issue a wake_up in kauditd if the length of the skb queue is less than the backlog limit. Otherwise, threads waiting in wait_for_auditd() will simply wake up, discover that the queue is still too long for them to proceed, and go back to sleep. This results in wasted context switches and machine cycles. kauditd_thread() is the only function that removes buffers from audit_skb_queue so we can't race. If we did, the timeout in wait_for_auditd() would expire and the waiting thread would continue. See: https://lkml.org/lkml/2013/9/2/479 Signed-off-by: Dan Duval <dan.duval@oracle.com> Signed-off-by: Chuck Anderson <chuck.anderson@oracle.com> Signed-off-by: Richard Guy Briggs <rgb@redhat.com> Signed-off-by: Eric Paris <eparis@redhat.com>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/audit.c4
1 files changed, 3 insertions, 1 deletions
diff --git a/kernel/audit.c b/kernel/audit.c
index 09e287b1dc0e..854f4829e654 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -462,8 +462,10 @@ static int kauditd_thread(void *dummy)
462 flush_hold_queue(); 462 flush_hold_queue();
463 463
464 skb = skb_dequeue(&audit_skb_queue); 464 skb = skb_dequeue(&audit_skb_queue);
465 wake_up(&audit_backlog_wait); 465
466 if (skb) { 466 if (skb) {
467 if (skb_queue_len(&audit_skb_queue) <= audit_backlog_limit)
468 wake_up(&audit_backlog_wait);
467 if (audit_pid) 469 if (audit_pid)
468 kauditd_send_skb(skb); 470 kauditd_send_skb(skb);
469 else 471 else