mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-30 22:26:55 +00:00
dm io tracker: factor out IO tracker
Allow other code to use dm_io_tracker. Signed-off-by: Mike Snitzer <snitzer@redhat.com>
This commit is contained in:
parent
b6e58b5466
commit
dc4fa29fe4
2 changed files with 75 additions and 76 deletions
|
@ -8,6 +8,7 @@
|
||||||
#include "dm-bio-prison-v2.h"
|
#include "dm-bio-prison-v2.h"
|
||||||
#include "dm-bio-record.h"
|
#include "dm-bio-record.h"
|
||||||
#include "dm-cache-metadata.h"
|
#include "dm-cache-metadata.h"
|
||||||
|
#include "dm-io-tracker.h"
|
||||||
|
|
||||||
#include <linux/dm-io.h>
|
#include <linux/dm-io.h>
|
||||||
#include <linux/dm-kcopyd.h>
|
#include <linux/dm-kcopyd.h>
|
||||||
|
@ -39,77 +40,6 @@ DECLARE_DM_KCOPYD_THROTTLE_WITH_MODULE_PARM(cache_copy_throttle,
|
||||||
|
|
||||||
/*----------------------------------------------------------------*/
|
/*----------------------------------------------------------------*/
|
||||||
|
|
||||||
struct io_tracker {
|
|
||||||
spinlock_t lock;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Sectors of in-flight IO.
|
|
||||||
*/
|
|
||||||
sector_t in_flight;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The time, in jiffies, when this device became idle (if it is
|
|
||||||
* indeed idle).
|
|
||||||
*/
|
|
||||||
unsigned long idle_time;
|
|
||||||
unsigned long last_update_time;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void iot_init(struct io_tracker *iot)
|
|
||||||
{
|
|
||||||
spin_lock_init(&iot->lock);
|
|
||||||
iot->in_flight = 0ul;
|
|
||||||
iot->idle_time = 0ul;
|
|
||||||
iot->last_update_time = jiffies;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool __iot_idle_for(struct io_tracker *iot, unsigned long jifs)
|
|
||||||
{
|
|
||||||
if (iot->in_flight)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return time_after(jiffies, iot->idle_time + jifs);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool iot_idle_for(struct io_tracker *iot, unsigned long jifs)
|
|
||||||
{
|
|
||||||
bool r;
|
|
||||||
|
|
||||||
spin_lock_irq(&iot->lock);
|
|
||||||
r = __iot_idle_for(iot, jifs);
|
|
||||||
spin_unlock_irq(&iot->lock);
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void iot_io_begin(struct io_tracker *iot, sector_t len)
|
|
||||||
{
|
|
||||||
spin_lock_irq(&iot->lock);
|
|
||||||
iot->in_flight += len;
|
|
||||||
spin_unlock_irq(&iot->lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __iot_io_end(struct io_tracker *iot, sector_t len)
|
|
||||||
{
|
|
||||||
if (!len)
|
|
||||||
return;
|
|
||||||
|
|
||||||
iot->in_flight -= len;
|
|
||||||
if (!iot->in_flight)
|
|
||||||
iot->idle_time = jiffies;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void iot_io_end(struct io_tracker *iot, sector_t len)
|
|
||||||
{
|
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&iot->lock, flags);
|
|
||||||
__iot_io_end(iot, len);
|
|
||||||
spin_unlock_irqrestore(&iot->lock, flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------*/
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Represents a chunk of future work. 'input' allows continuations to pass
|
* Represents a chunk of future work. 'input' allows continuations to pass
|
||||||
* values between themselves, typically error values.
|
* values between themselves, typically error values.
|
||||||
|
@ -470,7 +400,7 @@ struct cache {
|
||||||
struct batcher committer;
|
struct batcher committer;
|
||||||
struct work_struct commit_ws;
|
struct work_struct commit_ws;
|
||||||
|
|
||||||
struct io_tracker tracker;
|
struct dm_io_tracker tracker;
|
||||||
|
|
||||||
mempool_t migration_pool;
|
mempool_t migration_pool;
|
||||||
|
|
||||||
|
@ -866,7 +796,7 @@ static void accounted_begin(struct cache *cache, struct bio *bio)
|
||||||
if (accountable_bio(cache, bio)) {
|
if (accountable_bio(cache, bio)) {
|
||||||
pb = get_per_bio_data(bio);
|
pb = get_per_bio_data(bio);
|
||||||
pb->len = bio_sectors(bio);
|
pb->len = bio_sectors(bio);
|
||||||
iot_io_begin(&cache->tracker, pb->len);
|
dm_iot_io_begin(&cache->tracker, pb->len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -874,7 +804,7 @@ static void accounted_complete(struct cache *cache, struct bio *bio)
|
||||||
{
|
{
|
||||||
struct per_bio_data *pb = get_per_bio_data(bio);
|
struct per_bio_data *pb = get_per_bio_data(bio);
|
||||||
|
|
||||||
iot_io_end(&cache->tracker, pb->len);
|
dm_iot_io_end(&cache->tracker, pb->len);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void accounted_request(struct cache *cache, struct bio *bio)
|
static void accounted_request(struct cache *cache, struct bio *bio)
|
||||||
|
@ -1642,7 +1572,7 @@ enum busy {
|
||||||
|
|
||||||
static enum busy spare_migration_bandwidth(struct cache *cache)
|
static enum busy spare_migration_bandwidth(struct cache *cache)
|
||||||
{
|
{
|
||||||
bool idle = iot_idle_for(&cache->tracker, HZ);
|
bool idle = dm_iot_idle_for(&cache->tracker, HZ);
|
||||||
sector_t current_volume = (atomic_read(&cache->nr_io_migrations) + 1) *
|
sector_t current_volume = (atomic_read(&cache->nr_io_migrations) + 1) *
|
||||||
cache->sectors_per_block;
|
cache->sectors_per_block;
|
||||||
|
|
||||||
|
@ -2603,7 +2533,7 @@ static int cache_create(struct cache_args *ca, struct cache **result)
|
||||||
|
|
||||||
batcher_init(&cache->committer, commit_op, cache,
|
batcher_init(&cache->committer, commit_op, cache,
|
||||||
issue_op, cache, cache->wq);
|
issue_op, cache, cache->wq);
|
||||||
iot_init(&cache->tracker);
|
dm_iot_init(&cache->tracker);
|
||||||
|
|
||||||
init_rwsem(&cache->background_work_lock);
|
init_rwsem(&cache->background_work_lock);
|
||||||
prevent_background_work(cache);
|
prevent_background_work(cache);
|
||||||
|
|
69
drivers/md/dm-io-tracker.h
Normal file
69
drivers/md/dm-io-tracker.h
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2021 Red Hat, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* This file is released under the GPL.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DM_IO_TRACKER_H
|
||||||
|
#define DM_IO_TRACKER_H
|
||||||
|
|
||||||
|
#include <linux/jiffies.h>
|
||||||
|
|
||||||
|
struct dm_io_tracker {
|
||||||
|
spinlock_t lock;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sectors of in-flight IO.
|
||||||
|
*/
|
||||||
|
sector_t in_flight;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The time, in jiffies, when this device became idle
|
||||||
|
* (if it is indeed idle).
|
||||||
|
*/
|
||||||
|
unsigned long idle_time;
|
||||||
|
unsigned long last_update_time;
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline void dm_iot_init(struct dm_io_tracker *iot)
|
||||||
|
{
|
||||||
|
spin_lock_init(&iot->lock);
|
||||||
|
iot->in_flight = 0ul;
|
||||||
|
iot->idle_time = 0ul;
|
||||||
|
iot->last_update_time = jiffies;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool dm_iot_idle_for(struct dm_io_tracker *iot, unsigned long j)
|
||||||
|
{
|
||||||
|
bool r = false;
|
||||||
|
|
||||||
|
spin_lock_irq(&iot->lock);
|
||||||
|
if (!iot->in_flight)
|
||||||
|
r = time_after(jiffies, iot->idle_time + j);
|
||||||
|
spin_unlock_irq(&iot->lock);
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void dm_iot_io_begin(struct dm_io_tracker *iot, sector_t len)
|
||||||
|
{
|
||||||
|
spin_lock_irq(&iot->lock);
|
||||||
|
iot->in_flight += len;
|
||||||
|
spin_unlock_irq(&iot->lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void dm_iot_io_end(struct dm_io_tracker *iot, sector_t len)
|
||||||
|
{
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
if (!len)
|
||||||
|
return;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&iot->lock, flags);
|
||||||
|
iot->in_flight -= len;
|
||||||
|
if (!iot->in_flight)
|
||||||
|
iot->idle_time = jiffies;
|
||||||
|
spin_unlock_irqrestore(&iot->lock, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in a new issue