Skip to content

Commit

Permalink
dm io tracker: factor out IO tracker
Browse files Browse the repository at this point in the history
Allow other code to use dm_io_tracker.

Signed-off-by: Mike Snitzer <snitzer@redhat.com>
  • Loading branch information
Mike Snitzer committed Jun 25, 2021
1 parent b6e58b5 commit dc4fa29
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 76 deletions.
82 changes: 6 additions & 76 deletions drivers/md/dm-cache-target.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "dm-bio-prison-v2.h"
#include "dm-bio-record.h"
#include "dm-cache-metadata.h"
#include "dm-io-tracker.h"

#include <linux/dm-io.h>
#include <linux/dm-kcopyd.h>
Expand Down Expand Up @@ -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
* values between themselves, typically error values.
Expand Down Expand Up @@ -470,7 +400,7 @@ struct cache {
struct batcher committer;
struct work_struct commit_ws;

struct io_tracker tracker;
struct dm_io_tracker tracker;

mempool_t migration_pool;

Expand Down Expand Up @@ -866,15 +796,15 @@ static void accounted_begin(struct cache *cache, struct bio *bio)
if (accountable_bio(cache, bio)) {
pb = get_per_bio_data(bio);
pb->len = bio_sectors(bio);
iot_io_begin(&cache->tracker, pb->len);
dm_iot_io_begin(&cache->tracker, pb->len);
}
}

static void accounted_complete(struct cache *cache, struct bio *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)
Expand Down Expand Up @@ -1642,7 +1572,7 @@ enum busy {

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) *
cache->sectors_per_block;

Expand Down Expand Up @@ -2603,7 +2533,7 @@ static int cache_create(struct cache_args *ca, struct cache **result)

batcher_init(&cache->committer, commit_op, cache,
issue_op, cache, cache->wq);
iot_init(&cache->tracker);
dm_iot_init(&cache->tracker);

init_rwsem(&cache->background_work_lock);
prevent_background_work(cache);
Expand Down
69 changes: 69 additions & 0 deletions drivers/md/dm-io-tracker.h
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit dc4fa29

Please sign in to comment.