On Sat, 8 Jun 2013 12:45:41 +0300 Alexander Lyakas <alex.bolshoy@xxxxxxxxx> wrote: > Hi Neil, > after reading the code of raid1.c, I see that there's also > conf->retry_list, which is also flushed by raid1d, but not by > flush_pending_writes(). So I think it can also cause similar deadlock, > but I don't know how to fix it:( > Good point. Requests in retry_list are counted in nr_queued, which is checked in freeze_array(). And freeze_array() already calls flush_pending_writes(). So I suspect the right thing to do is use freeze_array() in place of raise_barrier(). So maybe this is the right approach. Testing greatly appreciated... Thanks, NeilBrown diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 226dcd0..240b328 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -1569,8 +1569,8 @@ static int raid1_add_disk(struct mddev *mddev, struct md_rdev *rdev) * we wait for all outstanding requests to complete. */ synchronize_sched(); - raise_barrier(conf); - lower_barrier(conf); + freeze_array(conf); + unfreeze_array(conf); clear_bit(Unmerged, &rdev->flags); } md_integrity_add_rdev(rdev, mddev); @@ -1620,11 +1620,11 @@ static int raid1_remove_disk(struct mddev *mddev, struct md_rdev *rdev) */ struct md_rdev *repl = conf->mirrors[conf->raid_disks + number].rdev; - raise_barrier(conf); + freeze_array(conf); clear_bit(Replacement, &repl->flags); p->rdev = repl; conf->mirrors[conf->raid_disks + number].rdev = NULL; - lower_barrier(conf); + unfreeze_array(conf); clear_bit(WantReplacement, &rdev->flags); } else clear_bit(WantReplacement, &rdev->flags); @@ -3021,7 +3021,7 @@ static int raid1_reshape(struct mddev *mddev) return -ENOMEM; } - raise_barrier(conf); + freeze_array(conf); /* ok, everything is stopped */ oldpool = conf->r1bio_pool; @@ -3052,7 +3052,7 @@ static int raid1_reshape(struct mddev *mddev) conf->raid_disks = mddev->raid_disks = raid_disks; mddev->delta_disks = 0; - lower_barrier(conf); + unfreeze_array(conf); set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); md_wakeup_thread(mddev->thread);
Attachment:
signature.asc
Description: PGP signature