K.Tanaka a07e6ab41b md: the md RAID10 resync thread could cause a md RAID10 array deadlock
This message describes another issue about md RAID10 found by testing the
2.6.24 md RAID10 using new scsi fault injection framework.

Abstract:

When a scsi error results in disabling a disk during RAID10 recovery, the
resync threads of md RAID10 could stall.

This case, the raid array has already been broken and it may not matter.  But
I think stall is not preferable.  If it occurs, even shutdown or reboot will
fail because of resource busy.

The deadlock mechanism:

The r10bio_s structure has a "remaining" member to keep track of BIOs yet to
be handled when recovering.  The "remaining" counter is incremented when
building a BIO in sync_request() and is decremented when finish a BIO in
end_sync_write().

If building a BIO fails for some reasons in sync_request(), the "remaining"
should be decremented if it has already been incremented.  I found a case
where this decrement is forgotten.  This causes a md_do_sync() deadlock
because md_do_sync() waits for md_done_sync() called by end_sync_write(), but
end_sync_write() never calls md_done_sync() because of the "remaining" counter
mismatch.

For example, this problem would be reproduced in the following case:

Personalities : [raid10]
md0 : active raid10 sdf1[4] sde1[5](F) sdd1[2] sdc1[1] sdb1[6](F)
      3919616 blocks 64K chunks 2 near-copies [4/2] [_UU_]
      [>....................]  recovery =  2.2% (45376/1959808) finish=0.7min speed=45376K/sec

This case, sdf1 is recovering, sdb1 and sde1 are disabled.
An additional error with detaching sdd will cause a deadlock.

md0 : active raid10 sdf1[4] sde1[5](F) sdd1[6](F) sdc1[1] sdb1[7](F)
      3919616 blocks 64K chunks 2 near-copies [4/1] [_U__]
      [=>...................]  recovery =  5.0% (99520/1959808) finish=5.9min speed=5237K/sec

 2739 ?        S<     0:17 [md0_raid10]
28608 ?        D<     0:00 [md0_resync]
28629 pts/1    Ss     0:00 bash
28830 pts/1    R+     0:00 ps ax
31819 ?        D<     0:00 [kjournald]

The resync thread keeps working, but actually it is deadlocked.

Patch:
By this patch, the remaining counter will be decremented if needed.

Signed-off-by: Neil Brown <neilb@suse.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2008-03-04 16:35:18 -08:00
..
2006-01-01 22:21:50 +01:00
2007-10-20 02:01:11 +01:00
2005-04-16 15:20:36 -07:00
2008-02-08 02:11:14 +00:00
2007-10-20 02:01:11 +01:00
2007-10-20 02:01:12 +01:00
2007-10-20 02:01:07 +01:00
2007-10-20 02:01:18 +01:00
2007-05-09 12:30:47 -07:00
2008-02-08 02:10:16 +00:00
2008-02-08 02:11:19 +00:00
2007-10-20 02:01:21 +01:00
2007-10-20 02:00:57 +01:00
2008-02-08 02:10:35 +00:00
2007-10-20 02:01:07 +01:00
2008-02-19 15:52:27 -08:00
2008-02-08 02:11:24 +00:00
2008-02-14 21:13:33 -08:00
2007-10-20 02:01:07 +01:00
2007-10-20 02:01:26 +01:00
2007-10-20 02:01:26 +01:00
2007-12-20 17:32:11 +00:00
2008-02-08 02:10:32 +00:00
2007-10-20 02:01:08 +01:00
2005-04-16 15:20:36 -07:00
2007-10-20 02:01:24 +01:00
2008-02-06 10:41:18 -08:00
2005-09-17 11:49:58 -07:00
2007-10-29 07:41:32 -07:00
2005-09-17 11:49:58 -07:00
2005-04-16 15:20:36 -07:00
2007-10-29 07:41:32 -07:00
2005-04-16 15:20:36 -07:00
2007-10-29 07:41:32 -07:00
2007-10-29 07:41:32 -07:00
2007-10-29 07:41:32 -07:00
2005-04-16 15:20:36 -07:00