+static void audit_buffer_free(struct audit_buffer *ab)
+{
+ unsigned long flags;
+
+ atomic_dec(&audit_backlog);
+ spin_lock_irqsave(&audit_freelist_lock, flags);
+ if (++audit_freelist_count > AUDIT_MAXFREE)
+ kfree(ab);
+ else
+ list_add(&ab->list, &audit_freelist);
+ spin_unlock_irqrestore(&audit_freelist_lock, flags);
+}
+
+static struct audit_buffer * audit_buffer_alloc(int gfp_mask)
+{
+ unsigned long flags;
+ struct audit_buffer *ab = NULL;
+
+ spin_lock_irqsave(&audit_freelist_lock, flags);
+ if (!list_empty(&audit_freelist)) {
+ ab = list_entry(audit_freelist.next,
+ struct audit_buffer, list);
+ list_del(&ab->list);
+ --audit_freelist_count;
+ }
+ spin_unlock_irqrestore(&audit_freelist_lock, flags);
+
+ if (!ab) {
+ ab = kmalloc(sizeof(*ab), GFP_ATOMIC);
+ if (!ab)
+ goto out;
+ }
+ atomic_inc(&audit_backlog);
+out:
+ return ab;
+}