dm stats: add cond_resched when looping over entries
authorMikulas Patocka <mpatocka@redhat.com>
Sun, 24 Apr 2022 20:43:00 +0000 (16:43 -0400)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 6 Jun 2022 06:19:46 +0000 (08:19 +0200)
commit bfe2b0146c4d0230b68f5c71a64380ff8d361f8b upstream.

dm-stats can be used with a very large number of entries (it is only
limited by 1/4 of total system memory), so add rescheduling points to
the loops that iterate over the entries.

Cc: stable@vger.kernel.org
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Signed-off-by: Mike Snitzer <snitzer@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/md/dm-stats.c

index 0250e7e521abcbae456b0552e774d47f507f3dc3..fdd4a840b30fa79b53d2fc5b35aef812c7eeaad2 100644 (file)
@@ -228,6 +228,7 @@ void dm_stats_cleanup(struct dm_stats *stats)
                                       atomic_read(&shared->in_flight[READ]),
                                       atomic_read(&shared->in_flight[WRITE]));
                        }
+                       cond_resched();
                }
                dm_stat_free(&s->rcu_head);
        }
@@ -316,6 +317,7 @@ static int dm_stats_create(struct dm_stats *stats, sector_t start, sector_t end,
        for (ni = 0; ni < n_entries; ni++) {
                atomic_set(&s->stat_shared[ni].in_flight[READ], 0);
                atomic_set(&s->stat_shared[ni].in_flight[WRITE], 0);
+               cond_resched();
        }
 
        if (s->n_histogram_entries) {
@@ -328,6 +330,7 @@ static int dm_stats_create(struct dm_stats *stats, sector_t start, sector_t end,
                for (ni = 0; ni < n_entries; ni++) {
                        s->stat_shared[ni].tmp.histogram = hi;
                        hi += s->n_histogram_entries + 1;
+                       cond_resched();
                }
        }
 
@@ -348,6 +351,7 @@ static int dm_stats_create(struct dm_stats *stats, sector_t start, sector_t end,
                        for (ni = 0; ni < n_entries; ni++) {
                                p[ni].histogram = hi;
                                hi += s->n_histogram_entries + 1;
+                               cond_resched();
                        }
                }
        }
@@ -477,6 +481,7 @@ static int dm_stats_list(struct dm_stats *stats, const char *program,
                        }
                        DMEMIT("\n");
                }
+               cond_resched();
        }
        mutex_unlock(&stats->mutex);
 
@@ -753,6 +758,7 @@ static void __dm_stat_clear(struct dm_stat *s, size_t idx_start, size_t idx_end,
                                local_irq_enable();
                        }
                }
+               cond_resched();
        }
 }
 
@@ -868,6 +874,8 @@ static int dm_stats_print(struct dm_stats *stats, int id,
 
                if (unlikely(sz + 1 >= maxlen))
                        goto buffer_overflow;
+
+               cond_resched();
        }
 
        if (clear)