|
15 | 15 | #include <linux/dax.h>
|
16 | 16 | #include <linux/pfn_t.h>
|
17 | 17 | #include <linux/libnvdimm.h>
|
| 18 | +#include <linux/delay.h> |
| 19 | +#include "dm-io-tracker.h" |
18 | 20 |
|
19 | 21 | #define DM_MSG_PREFIX "writecache"
|
20 | 22 |
|
@@ -183,6 +185,8 @@ struct dm_writecache {
|
183 | 185 | struct work_struct writeback_work;
|
184 | 186 | struct work_struct flush_work;
|
185 | 187 |
|
| 188 | + struct dm_io_tracker iot; |
| 189 | + |
186 | 190 | struct dm_io_client *dm_io;
|
187 | 191 |
|
188 | 192 | raw_spinlock_t endio_list_lock;
|
@@ -1466,6 +1470,10 @@ static int writecache_map(struct dm_target *ti, struct bio *bio)
|
1466 | 1470 | }
|
1467 | 1471 |
|
1468 | 1472 | unlock_remap_origin:
|
| 1473 | + if (bio_data_dir(bio) != READ) { |
| 1474 | + dm_iot_io_begin(&wc->iot, 1); |
| 1475 | + bio->bi_private = (void *)2; |
| 1476 | + } |
1469 | 1477 | bio_set_dev(bio, wc->dev->bdev);
|
1470 | 1478 | wc_unlock(wc);
|
1471 | 1479 | return DM_MAPIO_REMAPPED;
|
@@ -1496,11 +1504,13 @@ static int writecache_end_io(struct dm_target *ti, struct bio *bio, blk_status_t
|
1496 | 1504 | {
|
1497 | 1505 | struct dm_writecache *wc = ti->private;
|
1498 | 1506 |
|
1499 |
| - if (bio->bi_private != NULL) { |
| 1507 | + if (bio->bi_private == (void *)1) { |
1500 | 1508 | int dir = bio_data_dir(bio);
|
1501 | 1509 | if (atomic_dec_and_test(&wc->bio_in_progress[dir]))
|
1502 | 1510 | if (unlikely(waitqueue_active(&wc->bio_in_progress_wait[dir])))
|
1503 | 1511 | wake_up(&wc->bio_in_progress_wait[dir]);
|
| 1512 | + } else if (bio->bi_private == (void *)2) { |
| 1513 | + dm_iot_io_end(&wc->iot, 1); |
1504 | 1514 | }
|
1505 | 1515 | return 0;
|
1506 | 1516 | }
|
@@ -1827,6 +1837,13 @@ static void writecache_writeback(struct work_struct *work)
|
1827 | 1837 | dm_kcopyd_client_flush(wc->dm_kcopyd);
|
1828 | 1838 | }
|
1829 | 1839 |
|
| 1840 | + if (!wc->writeback_all && !dm_suspended(wc->ti)) { |
| 1841 | + while (!dm_iot_idle_for(&wc->iot, HZ)) { |
| 1842 | + cond_resched(); |
| 1843 | + msleep(1000); |
| 1844 | + } |
| 1845 | + } |
| 1846 | + |
1830 | 1847 | wc_lock(wc);
|
1831 | 1848 | restart:
|
1832 | 1849 | if (writecache_has_error(wc)) {
|
@@ -2140,6 +2157,8 @@ static int writecache_ctr(struct dm_target *ti, unsigned argc, char **argv)
|
2140 | 2157 | INIT_WORK(&wc->writeback_work, writecache_writeback);
|
2141 | 2158 | INIT_WORK(&wc->flush_work, writecache_flush_work);
|
2142 | 2159 |
|
| 2160 | + dm_iot_init(&wc->iot); |
| 2161 | + |
2143 | 2162 | raw_spin_lock_init(&wc->endio_list_lock);
|
2144 | 2163 | INIT_LIST_HEAD(&wc->endio_list);
|
2145 | 2164 | wc->endio_thread = kthread_create(writecache_endio_thread, wc, "writecache_endio");
|
|
0 commit comments