void quarantine_put(struct kasan_free_meta *info, struct kmem_cache *cache) { unsigned long flags; struct qlist_head *q; struct qlist_head temp = QLIST_INIT; local_irq_save(flags); q = this_cpu_ptr(&cpu_quarantine); qlist_put(q, &info->quarantine_link, cache->size); if (unlikely(q->bytes > QUARANTINE_PERCPU_SIZE)) qlist_move_all(q, &temp); local_irq_restore(flags); if (unlikely(!qlist_empty(&temp))) { spin_lock_irqsave(&quarantine_lock, flags); qlist_move_all(&temp, &global_quarantine); spin_unlock_irqrestore(&quarantine_lock, flags); } }
static void qlist_move(struct qlist_head *from, struct qlist_node *last, struct qlist_head *to, size_t size) { if (unlikely(last == from->tail)) { qlist_move_all(from, to); return; } if (qlist_empty(to)) to->head = from->head; else to->tail->next = from->head; to->tail = last; from->head = last->next; last->next = NULL; from->bytes -= size; to->bytes += size; }
static void qlist_move(struct qlist *from, void **last, struct qlist *to, size_t size) { if (unlikely(last == from->tail)) { qlist_move_all(from, to); return; } if (qlist_empty(to)) to->head = from->head; else *to->tail = from->head; to->tail = last; from->head = *last; *last = NULL; from->bytes -= size; to->bytes += size; }