Messages in this thread | | | Date | Tue, 06 Nov 2007 22:00:03 -0700 | From | Jeff Lessem <> | Subject | Re: 2.6.23.1: mdadm/raid5 hung/d-state |
| |
Dan Williams wrote: > The following patch, also attached, cleans up cases where the code looks > at sh->ops.pending when it should be looking at the consistent > stack-based snapshot of the operations flags.
I tried this patch (against a stock 2.6.23), and it did not work for me. Not only did I/O to the effected RAID5 & XFS partition stop, but also I/O to all other disks. I was not able to capture any debugging information, but I should be able to do that tomorrow when I can hook a serial console to the machine.
I'm not sure if my problem is identical to these others, as mine only seems to manifest with RAID5+XFS. The RAID rebuilds with no problem, and I've not had any problems with RAID5+ext3.
> > > --- > > drivers/md/raid5.c | 16 +++++++++------- > 1 files changed, 9 insertions(+), 7 deletions(-) > > diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c > index 496b9a3..e1a3942 100644 > --- a/drivers/md/raid5.c > +++ b/drivers/md/raid5.c > @@ -693,7 +693,8 @@ ops_run_prexor(struct stripe_head *sh, struct dma_async_tx_descriptor *tx) > } > > static struct dma_async_tx_descriptor * > -ops_run_biodrain(struct stripe_head *sh, struct dma_async_tx_descriptor *tx) > +ops_run_biodrain(struct stripe_head *sh, struct dma_async_tx_descriptor *tx, > + unsigned long pending) > { > int disks = sh->disks; > int pd_idx = sh->pd_idx, i; > @@ -701,7 +702,7 @@ ops_run_biodrain(struct stripe_head *sh, struct dma_async_tx_descriptor *tx) > /* check if prexor is active which means only process blocks > * that are part of a read-modify-write (Wantprexor) > */ > - int prexor = test_bit(STRIPE_OP_PREXOR, &sh->ops.pending); > + int prexor = test_bit(STRIPE_OP_PREXOR, &pending); > > pr_debug("%s: stripe %llu\n", __FUNCTION__, > (unsigned long long)sh->sector); > @@ -778,7 +779,8 @@ static void ops_complete_write(void *stripe_head_ref) > } > > static void > -ops_run_postxor(struct stripe_head *sh, struct dma_async_tx_descriptor *tx) > +ops_run_postxor(struct stripe_head *sh, struct dma_async_tx_descriptor *tx, > + unsigned long pending) > { > /* kernel stack size limits the total number of disks */ > int disks = sh->disks; > @@ -786,7 +788,7 @@ ops_run_postxor(struct stripe_head *sh, struct dma_async_tx_descriptor *tx) > > int count = 0, pd_idx = sh->pd_idx, i; > struct page *xor_dest; > - int prexor = test_bit(STRIPE_OP_PREXOR, &sh->ops.pending); > + int prexor = test_bit(STRIPE_OP_PREXOR, &pending); > unsigned long flags; > dma_async_tx_callback callback; > > @@ -813,7 +815,7 @@ ops_run_postxor(struct stripe_head *sh, struct dma_async_tx_descriptor *tx) > } > > /* check whether this postxor is part of a write */ > - callback = test_bit(STRIPE_OP_BIODRAIN, &sh->ops.pending) ? > + callback = test_bit(STRIPE_OP_BIODRAIN, &pending) ? > ops_complete_write : ops_complete_postxor; > > /* 1/ if we prexor'd then the dest is reused as a source > @@ -901,12 +903,12 @@ static void raid5_run_ops(struct stripe_head *sh, unsigned long pending) > tx = ops_run_prexor(sh, tx); > > if (test_bit(STRIPE_OP_BIODRAIN, &pending)) { > - tx = ops_run_biodrain(sh, tx); > + tx = ops_run_biodrain(sh, tx, pending); > overlap_clear++; > } > > if (test_bit(STRIPE_OP_POSTXOR, &pending)) > - ops_run_postxor(sh, tx); > + ops_run_postxor(sh, tx, pending); > > if (test_bit(STRIPE_OP_CHECK, &pending)) > ops_run_check(sh); > >
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |