Temporary lockup on loopback block device

!MAILaRCHIVE_VOTE_RePLACE
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]
To: <linux-kernel@...>
Date: Saturday, November 10, 2007 - 3:51 pm

Hi

I am experiencing a transient lockup in 'D' state with loopback device. It 
happens when process writes to a filesystem in loopback with command like
dd if=/dev/zero of=/s/fill bs=4k 

CPU is idle, disk is idle too, yet the dd process is waiting in 'D' in 
congestion_wait called from balance_dirty_pages.

After about 30 seconds, the lockup is gone and dd resumes, but it locks up 
soon again.

I added a printk to the balance_dirty_pages
printk("wait: nr_reclaimable %d, nr_writeback %d, dirty_thresh %d, 
pages_written %d, write_chunk %d\n", nr_reclaimable, 
global_page_state(NR_WRITEBACK), dirty_thresh, pages_written, 
write_chunk);

and it shows this during the lockup:

wait: nr_reclaimable 3099, nr_writeback 0, dirty_thresh 2985, 
pages_written 1021, write_chunk 1522
wait: nr_reclaimable 3099, nr_writeback 0, dirty_thresh 2985, 
pages_written 1021, write_chunk 1522
wait: nr_reclaimable 3099, nr_writeback 0, dirty_thresh 2985, 
pages_written 1021, write_chunk 1522

What apparently happens:

writeback_inodes syncs inodes only on the given wbc->bdi, however 
balance_dirty_pages checks against global counts of dirty pages. So if 
there's nothing to sync on a given device, but there are other dirty pages 
so that the counts are over the limit, it will loop without doing any 
work.

To reproduce it, you need totally idle machine (no GUI, etc.) -- if 
something writes to the backing device, it flushes the dirty pages 
generated by the loopback and the lockup is gone. If you add printk, don't 
forget to stop klogd, otherwise logging would end the lockup.

The hotfix (that I verified to work) is to not set wbc->bdi, so that all 
devices are flushed ... but the code probably needs some redesign (i.e. 
either account per-device and flush per-device, or account-global and 
flush-global).

Mikulas


diff -u -r ../x/linux-2.6.23.1/mm/page-writeback.c mm/page-writeback.c
--- ../x/linux-2.6.23.1/mm/page-writeback.c     2007-10-12 18:43:44.000000000 +0200
+++ mm/page-writeback.c 2007-11-10 20:32:43.000000000 +0100
@@ -214,7 +214,6 @@

	for (;;) {
		struct writeback_control wbc = {
-			.bdi            = bdi,
			.sync_mode      = WB_SYNC_NONE,
			.older_than_this = NULL,
			.nr_to_write    = write_chunk,

-
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]

Messages in current thread:
Temporary lockup on loopback block device, Mikulas Patocka, (Sat Nov 10, 3:51 pm)
Re: Temporary lockup on loopback block device, Andrew Morton, (Sat Nov 10, 6:54 pm)
Re: Temporary lockup on loopback block device, Mikulas Patocka, (Sat Nov 10, 8:33 pm)
Re: Temporary lockup on loopback block device, Mikulas Patocka, (Sat Nov 10, 11:56 pm)
Re: Temporary lockup on loopback block device, Mikulas Patocka, (Sun Nov 11, 1:33 am)
Re: Temporary lockup on loopback block device, Peter Zijlstra, (Sat Nov 10, 7:02 pm)
Re: Temporary lockup on loopback block device, Mikulas Patocka, (Sat Nov 10, 8:38 pm)
Re: Temporary lockup on loopback block device, Miklos Szeredi, (Sun Nov 11, 3:50 am)
Re: Temporary lockup on loopback block device, Mikulas Patocka, (Sun Nov 11, 2:29 pm)
Re: Temporary lockup on loopback block device, Miklos Szeredi, (Mon Nov 12, 9:32 am)
Re: Temporary lockup on loopback block device, Mikulas Patocka, (Thu Nov 15, 6:35 pm)