aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Duval <dan.duval@oracle.com>2013-09-16 11:16:35 -0400
committerEric Paris <eparis@redhat.com>2014-01-13 22:28:19 -0500
commit7ecf69bf50fd3464342cab59fe08533fbe3f6076 (patch)
tree71a0ff49a0d58e2d531412db8dfaa1e72994b953
parentdb897319401e1c111aef59deadd59ea08e11d879 (diff)
audit: efficiency fix 2: request exclusive wait since all need same resource
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: Use add_wait_queue_exclusive() in wait_for_auditd() to put the thread on the wait queue. When kauditd dequeues an skb, all of the waiting threads are waiting for the same resource, but only one is going to get it, so there's no need to wake up more than one waiter. 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>
-rw-r--r--kernel/audit.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/kernel/audit.c b/kernel/audit.c
index 854f4829e654..b8fa4bf8563b 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -1216,7 +1216,7 @@ static unsigned long wait_for_auditd(unsigned long sleep_time)
1216 unsigned long timeout = sleep_time; 1216 unsigned long timeout = sleep_time;
1217 DECLARE_WAITQUEUE(wait, current); 1217 DECLARE_WAITQUEUE(wait, current);
1218 set_current_state(TASK_UNINTERRUPTIBLE); 1218 set_current_state(TASK_UNINTERRUPTIBLE);
1219 add_wait_queue(&audit_backlog_wait, &wait); 1219 add_wait_queue_exclusive(&audit_backlog_wait, &wait);
1220 1220
1221 if (audit_backlog_limit && 1221 if (audit_backlog_limit &&
1222 skb_queue_len(&audit_skb_queue) > audit_backlog_limit) 1222 skb_queue_len(&audit_skb_queue) > audit_backlog_limit)