diff --git a/[refs] b/[refs] index 5570845d2800..70e37fa5f30c 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 351bb722590b2329ac5e72c4b824b8b6ce6e3082 +refs/heads/master: d5b454f2c40c9efd0cc113bc3220ebcb66b7c022 diff --git a/trunk/kernel/audit.c b/trunk/kernel/audit.c index 518a833b676a..27ffcf363f8d 100644 --- a/trunk/kernel/audit.c +++ b/trunk/kernel/audit.c @@ -610,26 +610,25 @@ static struct audit_buffer * audit_buffer_alloc(struct audit_context *ctx, * (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,