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:43:40 +0000 (08:43 +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 0e039a8..a3f2050 100644 (file)
@@ -225,6 +225,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);
        }
@@ -330,6 +331,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) {
@@ -342,6 +344,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();
                }
        }
 
@@ -362,6 +365,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();
                        }
                }
        }
@@ -497,6 +501,7 @@ static int dm_stats_list(struct dm_stats *stats, const char *program,
                        }
                        DMEMIT("\n");
                }
+               cond_resched();
        }
        mutex_unlock(&stats->mutex);
 
@@ -774,6 +779,7 @@ static void __dm_stat_clear(struct dm_stat *s, size_t idx_start, size_t idx_end,
                                local_irq_enable();
                        }
                }
+               cond_resched();
        }
 }
 
@@ -889,6 +895,8 @@ static int dm_stats_print(struct dm_stats *stats, int id,
 
                if (unlikely(sz + 1 >= maxlen))
                        goto buffer_overflow;
+
+               cond_resched();
        }
 
        if (clear)