|
|
Subscribe / Log in / New account

Trading off safety and performance in the kernel

Trading off safety and performance in the kernel

Posted May 16, 2015 20:14 UTC (Sat) by dlang (guest, #313)
In reply to: Trading off safety and performance in the kernel by ghane
Parent article: Trading off safety and performance in the kernel

From what I understand, the issue was that a single sync could return to the command line before the data was actually on disk, but a second one couldn't start until the first finished.

that still doesn't justify three invocations, but would justify two.


to post comments

Trading off safety and performance in the kernel

Posted May 16, 2015 20:42 UTC (Sat) by neilbrown (subscriber, #359) [Link] (1 responses)

Yes, the "sync" semantics are "wait for any pending writeout to complete, then start writeout on any dirty data", so 2 is sensible and 3 is superstitious.

http://pubs.opengroup.org/onlinepubs/7908799/xsh/sync.html

This is part of why calling sys_sync() once in the suspend path is wrong (twice has been suggested), though I'm not certain if the Linux implementation exactly matches the specification.

Trading off safety and performance in the kernel

Posted May 17, 2015 4:21 UTC (Sun) by neilbrown (subscriber, #359) [Link]

> Yes, the "sync" semantics are "wait for any pending writeout to complete, then start writeout on any dirty data",

Actually, I'll have to backtrack on this. I can find no evidence in historical Unix, all the way up to 4.3BSD, to suggest that the 'sync' system call would wait. It just initiated IO. So maybe calling it 3 times makes sense.

Linux (roughly) followed that approach until Linux 1.3.20. That version introduced the change:

--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -228,7 +228,7 @@ int fsync_dev(dev_t dev)
 
 asmlinkage int sys_sync(void)
 {
-       sync_dev(0);
+       fsync_dev(0);
        return 0;
 }
 
To give the fuller context:
void sync_dev(dev_t dev)
{
        sync_buffers(dev, 0);
        sync_supers(dev);
        sync_inodes(dev);
        sync_buffers(dev, 0);
}

int fsync_dev(dev_t dev)
{
        sync_buffers(dev, 0);
        sync_supers(dev);
        sync_inodes(dev);
        return sync_buffers(dev, 1);
}

asmlinkage int sys_sync(void)
{
        fsync_dev(0);
        return 0;
}
The second arg to sync_buffers() says whether it should 'wait'. So fsync_dev() waits, sync_dev() doesn't.

Exactly what is waited for when is hard to track. I'd need to read a lot more code to see what things sys_sync waits for today. But it does wait for something, but before 1.3.20, and all through "Unix", it certainly didn't wait for everything.


Copyright © 2025, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds