Commit 90a9b869 authored by Hannes Reinecke's avatar Hannes Reinecke Committed by Mike Snitzer
Browse files

dm zoned: reclaim random zones when idle



When the system is idle we should be starting reclaiming
random zones, too.

Signed-off-by: default avatarHannes Reinecke <hare@suse.de>
Reviewed-by: default avatarDamien Le Moal <damien.lemoal@wdc.com>
Signed-off-by: default avatarMike Snitzer <snitzer@redhat.com>
parent 34f5affd
Loading
Loading
Loading
Loading
+9 −4
Original line number Diff line number Diff line
@@ -1859,15 +1859,20 @@ static void dmz_wait_for_reclaim(struct dmz_metadata *zmd, struct dm_zone *zone)
/*
 * Select a cache or random write zone for reclaim.
 */
static struct dm_zone *dmz_get_rnd_zone_for_reclaim(struct dmz_metadata *zmd)
static struct dm_zone *dmz_get_rnd_zone_for_reclaim(struct dmz_metadata *zmd,
						    bool idle)
{
	struct dm_zone *dzone = NULL;
	struct dm_zone *zone;
	struct list_head *zone_list = &zmd->map_rnd_list;

	/* If we have cache zones select from the cache zone list */
	if (zmd->nr_cache)
	if (zmd->nr_cache) {
		zone_list = &zmd->map_cache_list;
		/* Try to relaim random zones, too, when idle */
		if (idle && list_empty(zone_list))
			zone_list = &zmd->map_rnd_list;
	}

	list_for_each_entry(zone, zone_list, link) {
		if (dmz_is_buf(zone))
@@ -1901,7 +1906,7 @@ static struct dm_zone *dmz_get_seq_zone_for_reclaim(struct dmz_metadata *zmd)
/*
 * Select a zone for reclaim.
 */
struct dm_zone *dmz_get_zone_for_reclaim(struct dmz_metadata *zmd)
struct dm_zone *dmz_get_zone_for_reclaim(struct dmz_metadata *zmd, bool idle)
{
	struct dm_zone *zone;

@@ -1917,7 +1922,7 @@ struct dm_zone *dmz_get_zone_for_reclaim(struct dmz_metadata *zmd)
	if (list_empty(&zmd->reserved_seq_zones_list))
		zone = dmz_get_seq_zone_for_reclaim(zmd);
	else
		zone = dmz_get_rnd_zone_for_reclaim(zmd);
		zone = dmz_get_rnd_zone_for_reclaim(zmd, idle);
	dmz_unlock_map(zmd);

	return zone;
+19 −11
Original line number Diff line number Diff line
@@ -284,7 +284,10 @@ static int dmz_reclaim_rnd_data(struct dmz_reclaim *zrc, struct dm_zone *dzone)
	int alloc_flags = dmz_nr_cache_zones(zmd) ?
		DMZ_ALLOC_RND : DMZ_ALLOC_SEQ;

	/* Get a free sequential zone */
	/* Always use sequential zones to reclaim random zones */
	if (dmz_is_rnd(dzone))
		alloc_flags = DMZ_ALLOC_SEQ;
	/* Get a free random or sequential zone */
	dmz_lock_map(zmd);
	szone = dmz_alloc_zone(zmd, alloc_flags | DMZ_ALLOC_RECLAIM);
	dmz_unlock_map(zmd);
@@ -343,6 +346,14 @@ static void dmz_reclaim_empty(struct dmz_reclaim *zrc, struct dm_zone *dzone)
	dmz_unlock_flush(zmd);
}

/*
 * Test if the target device is idle.
 */
static inline int dmz_target_idle(struct dmz_reclaim *zrc)
{
	return time_is_before_jiffies(zrc->atime + DMZ_IDLE_PERIOD);
}

/*
 * Find a candidate zone for reclaim and process it.
 */
@@ -355,7 +366,7 @@ static int dmz_do_reclaim(struct dmz_reclaim *zrc)
	int ret;

	/* Get a data zone */
	dzone = dmz_get_zone_for_reclaim(zmd);
	dzone = dmz_get_zone_for_reclaim(zmd, dmz_target_idle(zrc));
	if (!dzone)
		return -EBUSY;

@@ -418,14 +429,6 @@ out:
	return 0;
}

/*
 * Test if the target device is idle.
 */
static inline int dmz_target_idle(struct dmz_reclaim *zrc)
{
	return time_is_before_jiffies(zrc->atime + DMZ_IDLE_PERIOD);
}

static unsigned int dmz_reclaim_percentage(struct dmz_reclaim *zrc)
{
	struct dmz_metadata *zmd = zrc->metadata;
@@ -448,8 +451,13 @@ static unsigned int dmz_reclaim_percentage(struct dmz_reclaim *zrc)
 */
static bool dmz_should_reclaim(struct dmz_reclaim *zrc, unsigned int p_unmap)
{
	unsigned int nr_reclaim = dmz_nr_rnd_zones(zrc->metadata);

	if (dmz_nr_cache_zones(zrc->metadata))
		nr_reclaim += dmz_nr_cache_zones(zrc->metadata);

	/* Reclaim when idle */
	if (dmz_target_idle(zrc) && p_unmap < 100)
	if (dmz_target_idle(zrc) && nr_reclaim)
		return true;

	/* If there are still plenty of cache zones, do not reclaim */
+1 −1
Original line number Diff line number Diff line
@@ -240,7 +240,7 @@ static inline bool dmz_is_active(struct dm_zone *zone)

int dmz_lock_zone_reclaim(struct dm_zone *zone);
void dmz_unlock_zone_reclaim(struct dm_zone *zone);
struct dm_zone *dmz_get_zone_for_reclaim(struct dmz_metadata *zmd);
struct dm_zone *dmz_get_zone_for_reclaim(struct dmz_metadata *zmd, bool idle);

struct dm_zone *dmz_get_chunk_mapping(struct dmz_metadata *zmd,
				      unsigned int chunk, int op);