Re: 2.6.23.1: mdadm/raid5 hung/d-state

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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 [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux