Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

vfs: kill write_super and sync_supers

Finally we can kill the 'sync_supers' kernel thread along with the
'->write_super()' superblock operation because all the users are gone.
Now every file-system is supposed to self-manage own superblock and
its dirty state.

The nice thing about killing this thread is that it improves power management.
Indeed, 'sync_supers' is a source of monotonic system wake-ups - it woke up
every 5 seconds no matter what - even if there were no dirty superblocks and
even if there were no file-systems using this service (e.g., btrfs and
journalled ext4 do not need it). So it was wasting power most of the time. And
because the thread was in the core of the kernel, all systems had to have it.
So I am quite happy to make it go away.

Interestingly, this thread is a left-over from the pdflush kernel thread which
was a self-forking kernel thread responsible for all the write-back in old
Linux kernels. It was turned into per-block device BDI threads, and
'sync_supers' was a left-over. Thus, R.I.P, pdflush as well.

Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
  • Loading branch information...
commit f0cd2dbb6cf387c11f87265462e370bb5469299e 1 parent d42d1da
Artem Bityutskiy authored Al Viro committed
40 fs/super.c
@@ -537,46 +537,6 @@ void drop_super(struct super_block *sb)
537 537 EXPORT_SYMBOL(drop_super);
538 538
539 539 /**
540   - * sync_supers - helper for periodic superblock writeback
541   - *
542   - * Call the write_super method if present on all dirty superblocks in
543   - * the system. This is for the periodic writeback used by most older
544   - * filesystems. For data integrity superblock writeback use
545   - * sync_filesystems() instead.
546   - *
547   - * Note: check the dirty flag before waiting, so we don't
548   - * hold up the sync while mounting a device. (The newly
549   - * mounted device won't need syncing.)
550   - */
551   -void sync_supers(void)
552   -{
553   - struct super_block *sb, *p = NULL;
554   -
555   - spin_lock(&sb_lock);
556   - list_for_each_entry(sb, &super_blocks, s_list) {
557   - if (hlist_unhashed(&sb->s_instances))
558   - continue;
559   - if (sb->s_op->write_super && sb->s_dirt) {
560   - sb->s_count++;
561   - spin_unlock(&sb_lock);
562   -
563   - down_read(&sb->s_umount);
564   - if (sb->s_root && sb->s_dirt && (sb->s_flags & MS_BORN))
565   - sb->s_op->write_super(sb);
566   - up_read(&sb->s_umount);
567   -
568   - spin_lock(&sb_lock);
569   - if (p)
570   - __put_super(p);
571   - p = sb;
572   - }
573   - }
574   - if (p)
575   - __put_super(p);
576   - spin_unlock(&sb_lock);
577   -}
578   -
579   -/**
580 540 * iterate_supers - call function for all active superblocks
581 541 * @f: function to call
582 542 * @arg: argument to pass to it
1  include/linux/backing-dev.h
@@ -124,7 +124,6 @@ void bdi_start_writeback(struct backing_dev_info *bdi, long nr_pages,
124 124 void bdi_start_background_writeback(struct backing_dev_info *bdi);
125 125 int bdi_writeback_thread(void *data);
126 126 int bdi_has_dirty_io(struct backing_dev_info *bdi);
127   -void bdi_arm_supers_timer(void);
128 127 void bdi_wakeup_thread_delayed(struct backing_dev_info *bdi);
129 128 void bdi_lock_two(struct bdi_writeback *wb1, struct bdi_writeback *wb2);
130 129
3  include/linux/fs.h
@@ -1491,7 +1491,6 @@ struct sb_writers {
1491 1491 struct super_block {
1492 1492 struct list_head s_list; /* Keep this first */
1493 1493 dev_t s_dev; /* search index; _not_ kdev_t */
1494   - unsigned char s_dirt;
1495 1494 unsigned char s_blocksize_bits;
1496 1495 unsigned long s_blocksize;
1497 1496 loff_t s_maxbytes; /* Max file size */
@@ -1861,7 +1860,6 @@ struct super_operations {
1861 1860 int (*drop_inode) (struct inode *);
1862 1861 void (*evict_inode) (struct inode *);
1863 1862 void (*put_super) (struct super_block *);
1864   - void (*write_super) (struct super_block *);
1865 1863 int (*sync_fs)(struct super_block *sb, int wait);
1866 1864 int (*freeze_fs) (struct super_block *);
1867 1865 int (*unfreeze_fs) (struct super_block *);
@@ -2397,7 +2395,6 @@ extern int vfs_fsync_range(struct file *file, loff_t start, loff_t end,
2397 2395 int datasync);
2398 2396 extern int vfs_fsync(struct file *file, int datasync);
2399 2397 extern int generic_write_sync(struct file *file, loff_t pos, loff_t count);
2400   -extern void sync_supers(void);
2401 2398 extern void emergency_sync(void);
2402 2399 extern void emergency_remount(void);
2403 2400 #ifdef CONFIG_BLOCK
52 mm/backing-dev.c
@@ -39,12 +39,6 @@ DEFINE_SPINLOCK(bdi_lock);
39 39 LIST_HEAD(bdi_list);
40 40 LIST_HEAD(bdi_pending_list);
41 41
42   -static struct task_struct *sync_supers_tsk;
43   -static struct timer_list sync_supers_timer;
44   -
45   -static int bdi_sync_supers(void *);
46   -static void sync_supers_timer_fn(unsigned long);
47   -
48 42 void bdi_lock_two(struct bdi_writeback *wb1, struct bdi_writeback *wb2)
49 43 {
50 44 if (wb1 < wb2) {
@@ -250,12 +244,6 @@ static int __init default_bdi_init(void)
250 244 {
251 245 int err;
252 246
253   - sync_supers_tsk = kthread_run(bdi_sync_supers, NULL, "sync_supers");
254   - BUG_ON(IS_ERR(sync_supers_tsk));
255   -
256   - setup_timer(&sync_supers_timer, sync_supers_timer_fn, 0);
257   - bdi_arm_supers_timer();
258   -
259 247 err = bdi_init(&default_backing_dev_info);
260 248 if (!err)
261 249 bdi_register(&default_backing_dev_info, NULL, "default");
@@ -270,46 +258,6 @@ int bdi_has_dirty_io(struct backing_dev_info *bdi)
270 258 return wb_has_dirty_io(&bdi->wb);
271 259 }
272 260
273   -/*
274   - * kupdated() used to do this. We cannot do it from the bdi_forker_thread()
275   - * or we risk deadlocking on ->s_umount. The longer term solution would be
276   - * to implement sync_supers_bdi() or similar and simply do it from the
277   - * bdi writeback thread individually.
278   - */
279   -static int bdi_sync_supers(void *unused)
280   -{
281   - set_user_nice(current, 0);
282   -
283   - while (!kthread_should_stop()) {
284   - set_current_state(TASK_INTERRUPTIBLE);
285   - schedule();
286   -
287   - /*
288   - * Do this periodically, like kupdated() did before.
289   - */
290   - sync_supers();
291   - }
292   -
293   - return 0;
294   -}
295   -
296   -void bdi_arm_supers_timer(void)
297   -{
298   - unsigned long next;
299   -
300   - if (!dirty_writeback_interval)
301   - return;
302   -
303   - next = msecs_to_jiffies(dirty_writeback_interval * 10) + jiffies;
304   - mod_timer(&sync_supers_timer, round_jiffies_up(next));
305   -}
306   -
307   -static void sync_supers_timer_fn(unsigned long unused)
308   -{
309   - wake_up_process(sync_supers_tsk);
310   - bdi_arm_supers_timer();
311   -}
312   -
313 261 static void wakeup_timer_fn(unsigned long data)
314 262 {
315 263 struct backing_dev_info *bdi = (struct backing_dev_info *)data;
1  mm/page-writeback.c
@@ -1532,7 +1532,6 @@ int dirty_writeback_centisecs_handler(ctl_table *table, int write,
1532 1532 void __user *buffer, size_t *length, loff_t *ppos)
1533 1533 {
1534 1534 proc_dointvec(table, write, buffer, length, ppos);
1535   - bdi_arm_supers_timer();
1536 1535 return 0;
1537 1536 }
1538 1537

0 comments on commit f0cd2db

Please sign in to comment.
Something went wrong with that request. Please try again.