AUDIT: Fix livelock in audit_serial().
authorDavid Woodhouse <dwmw2@shinybook.infradead.org>
Fri, 15 Jul 2005 11:56:03 +0000 (12:56 +0100)
committerDavid Woodhouse <dwmw2@shinybook.infradead.org>
Fri, 15 Jul 2005 11:56:03 +0000 (12:56 +0100)
The tricks with atomic_t were bizarre. Just do it sensibly instead.

Signed-off-by: David Woodhouse <dwmw2@infradead.org>
kernel/audit.c

index 518a833..27ffcf3 100644 (file)
@@ -610,26 +610,25 @@ err:
  * (timestamp,serial) tuple is unique for each syscall and is live from
  * syscall entry to syscall exit.
  *
- * Atomic values are only guaranteed to be 24-bit, so we count down.
- *
  * NOTE: Another possibility is to store the formatted records off the
  * audit context (for those records that have a context), and emit them
  * all at syscall exit.  However, this could delay the reporting of
  * significant errors until syscall exit (or never, if the system
  * halts). */
+
 unsigned int audit_serial(void)
 {
-       static atomic_t serial = ATOMIC_INIT(0xffffff);
-       unsigned int a, b;
+       static spinlock_t serial_lock = SPIN_LOCK_UNLOCKED;
+       static unsigned int serial = 0;
+
+       unsigned long flags;
+       unsigned int ret;
 
-       do {
-               a = atomic_read(&serial);
-               if (atomic_dec_and_test(&serial))
-                       atomic_set(&serial, 0xffffff);
-               b = atomic_read(&serial);
-       } while (b != a - 1);
+       spin_lock_irqsave(&serial_lock, flags);
+       ret = serial++;
+       spin_unlock_irqrestore(&serial_lock, flags);
 
-       return 0xffffff - b;
+       return ret;
 }
 
 static inline void audit_get_stamp(struct audit_context *ctx,