diff options
Diffstat (limited to 'mm/kasan/quarantine.c')
| -rw-r--r-- | mm/kasan/quarantine.c | 12 |
1 files changed, 11 insertions, 1 deletions
diff --git a/mm/kasan/quarantine.c b/mm/kasan/quarantine.c index 6958aa713c67..c9944fdf48ca 100644 --- a/mm/kasan/quarantine.c +++ b/mm/kasan/quarantine.c @@ -355,7 +355,12 @@ void kasan_quarantine_remove_cache(struct kmem_cache *cache) */ on_each_cpu(per_cpu_remove_cache, cache, 1); - for_each_online_cpu(cpu) { + /* + * A CPU can go offline after on_each_cpu() returns, leaving cache + * objects on that CPU's shrink list. Scan all possible CPUs to + * drain those lists. + */ + for_each_possible_cpu(cpu) { sq = per_cpu_ptr(&shrink_qlist, cpu); raw_spin_lock_irqsave(&sq->lock, flags); qlist_move_cache(&sq->qlist, &to_free, cache); @@ -365,9 +370,14 @@ void kasan_quarantine_remove_cache(struct kmem_cache *cache) raw_spin_lock_irqsave(&quarantine_lock, flags); for (i = 0; i < QUARANTINE_BATCHES; i++) { + size_t old_bytes; + if (qlist_empty(&global_quarantine[i])) continue; + old_bytes = global_quarantine[i].bytes; qlist_move_cache(&global_quarantine[i], &to_free, cache); + WRITE_ONCE(quarantine_size, quarantine_size - + (old_bytes - global_quarantine[i].bytes)); /* Scanning whole quarantine can take a while. */ raw_spin_unlock_irqrestore(&quarantine_lock, flags); cond_resched(); |
