static void update_writeback_rate(struct work_struct *work) { struct cached_dev *dc = container_of(to_delayed_work(work), struct cached_dev, writeback_rate_update); struct cache_set *c = dc->disk.c; /* * should check BCACHE_DEV_RATE_DW_RUNNING before calling * cancel_delayed_work_sync(). */ set_bit(BCACHE_DEV_RATE_DW_RUNNING, &dc->disk.flags); /* paired with where BCACHE_DEV_RATE_DW_RUNNING is tested */ smp_mb(); /* * CACHE_SET_IO_DISABLE might be set via sysfs interface, * check it here too. */ if (!test_bit(BCACHE_DEV_WB_RUNNING, &dc->disk.flags) || test_bit(CACHE_SET_IO_DISABLE, &c->flags)) { clear_bit(BCACHE_DEV_RATE_DW_RUNNING, &dc->disk.flags); /* paired with where BCACHE_DEV_RATE_DW_RUNNING is tested */ smp_mb(); return; } if (atomic_read(&dc->has_dirty) && dc->writeback_percent) { /* * If the whole cache set is idle, set_at_max_writeback_rate() * will set writeback rate to a max number. Then it is * unncessary to update writeback rate for an idle cache set * in maximum writeback rate number(s). */ if (!set_at_max_writeback_rate(c, dc)) { down_read(&dc->writeback_lock); __update_writeback_rate(dc); up_read(&dc->writeback_lock); } } /* * CACHE_SET_IO_DISABLE might be set via sysfs interface, * check it here too. */ if (test_bit(BCACHE_DEV_WB_RUNNING, &dc->disk.flags) && !test_bit(CACHE_SET_IO_DISABLE, &c->flags)) { schedule_delayed_work(&dc->writeback_rate_update, dc->writeback_rate_update_seconds * HZ); } /* * should check BCACHE_DEV_RATE_DW_RUNNING before calling * cancel_delayed_work_sync(). */ clear_bit(BCACHE_DEV_RATE_DW_RUNNING, &dc->disk.flags); /* paired with where BCACHE_DEV_RATE_DW_RUNNING is tested */ smp_mb(); }
static void update_writeback_rate(struct work_struct *work) { struct cached_dev *dc = container_of(to_delayed_work(work), struct cached_dev, writeback_rate_update); down_read(&dc->writeback_lock); if (atomic_read(&dc->has_dirty) && dc->writeback_percent) __update_writeback_rate(dc); up_read(&dc->writeback_lock); schedule_delayed_work(&dc->writeback_rate_update, dc->writeback_rate_update_seconds * HZ); }