Vim hanging while running VMWare: fixed
I’ve just fixed a bug on my linux desktop which had been annoying me for a while. Since there seems to be little online written about it, here’s a blog post to help future Googlers.
Here’s the symptoms: while you’re running VMWare, your Vim editing sessions freeze up for 20 seconds or so, roughly every 5 minutes. The editor is entirely hung.
If you strace -p the process ID before the hang occurs, you’ll see something like this:
select(6, [0 3 5], NULL, [0 3], {0, 0}) = 0 (Timeout)
select(6, [0 3 5], NULL, [0 3], {0, 0}) = 0 (Timeout)
select(6, [0 3 5], NULL, [0 3], {0, 0}) = 0 (Timeout)
_llseek(7, 4096, [4096], SEEK_SET) = 0
write(7, “tp\21\0\377\0\0\0\2\0\0\0|\0\0\0\1\0\0\0\1\0\0\0\6\0\0″…, 4096) = 4096
ioctl(0, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost -isig -icanon -echo …}) = 0
select(6, [0 3 5], NULL, [0 3], {0, 0}) = 0 (Timeout)
_llseek(7, 20480, [20480], SEEK_SET) = 0
write(7, “ad\0\0\245\4\0\0\341\5\0\0\0\20\0\0J\0\0\0\250\17\0\0\247″…, 4096) = 4096
ioctl(0, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost -isig -icanon -echo …}) = 0
select(6, [0 3 5], NULL, [0 3], {0, 0}) = 0 (Timeout)
fsync(
In other words, the hung process is sitting in an fsync() call, attempting to flush changed data for the current file to disk.
Investigation threw up the following: a kerneltrap thread about disk activity, poor responsiveness with Firefox 3.0b3 on linux, and a VIM bug report regarding this feature interfering with laptop-mode and spun-down hard disks.
VMWare must be issuing lots of unsynced I/O, so when Vim issues its fsync() or sync() call, it needs to wait for the VMWare I/O to complete before it can return — even though the machine is otherwise idle. A bit of a Linux kernel misfeature, it seems.
Synthesising details from those threads comes up with this fix: edit your ~/.vimrc and add the following lines –
set swapsync= set nofsync
This will inhibit use of both fsync() and sync() by Vim, and the problem is avoided nicely.

David Malone said,
March 12, 2008 @ 8:28 pm
Will that prevent vim from calling fsync after you :w a file? If so, that’s potentially dangerous - I’ve frequently done things like this:
vim module.c
make && make install
kldload module
Resulting in a kernel panic ‘cos I didn’t get the code quite right. Without an fsync of the module.c file, there’s a good chance that you’ll end up with an empty module.c file, ‘cos vim truncated it before rewriting it and the writes haven’t happened but the truncate has.
Justin said,
March 12, 2008 @ 9:46 pm
Dave, sounds like you might have the one scenario where you’re better off with the fsync(). Me — I’m not expecting kernel panics in my code, so not so much ;)
David Malone said,
March 12, 2008 @ 9:54 pm
I guess I may not have described typical vim usage ;-)
I did once panic a machine with a perl script - I never understood quite how, but…
Don Marti said,
March 12, 2008 @ 11:31 pm
Looks from the thread that noatime or relatime could be a big help.
What if you want to sync when you actually :w or :wq, but not when Vim decides on its own to write to a file?
Nix said,
March 13, 2008 @ 1:32 am
Um, what about everything else that fsync()s? It’s a pretty common operation: all sorts of things do it from databases to MTAs to some games (!) and they all still freeze solid…
Justin said,
March 14, 2008 @ 9:06 pm
Don: I’m using noatime, but it doesn’t help. If it was to sync at :wq time, it’d still hang while that was happening…
Nix: that’s true — however, Vim is a very interactive app, and I haven’t run into any other app on my desktop that uses fsync() noticeably.