linux-raid.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Chris Allen <chris@cjx.com>
To: Neil Brown <neilb@suse.de>
Cc: linux-raid@vger.kernel.org
Subject: Re: raid5 hang on get_active_stripe
Date: Tue, 14 Nov 2006 10:28:29 +0000	[thread overview]
Message-ID: <45599A4D.8090907@cjx.com> (raw)
In-Reply-To: <17706.58512.374925.103556@cse.unsw.edu.au>

You probably guessed that no matter what I did, I never, ever saw the 
problem when your
trace was installed. I'd guess at some obscure timing-related problem. I 
can still trigger it
consistently with a vanilla 2.6.17_SMP though, but again only when 
bitmaps are turned on.



Neil Brown wrote:
> On Tuesday October 10, chris@cjx.com wrote:
>   
>> Very happy to. Let me know what you'd like me to do.
>>     
>
> Cool thanks.
>
> At the end is a patch against 2.6.17.11, though it should apply against
> any later 2.6.17 kernel.
> Apply this and reboot.
>
> Then run
>
>        while true
>        do cat /sys/block/mdX/md/stripe_cache_active
>           sleep 10
>        done > /dev/null
>
> (maybe write a little script or whatever).  Leave this running. It
> effects the check for "has raid5 hung".  Make sure to change "mdX" to
> whatever is appropriate.
>
> Occasionally look in the kernel logs for
>    plug problem:
>
> if you find that, send me the surrounding text - there should be about
> a dozen lines following this one.
>
> Hopefully this will let me know which is last thing to happen: a plug
> or an unplug.
> If the last is a "plug", then the timer really should still be
> pending, but isn't (this is impossible).  So I'll look more closely at
> that option.
> If the last is an "unplug", then the 'Plugged' flag should really be
> clear but it isn't (this is impossible).  So I'll look more closely at
> that option.
>
> Dean is running this, but he only gets the hang every couple of
> weeks.  If you get it more often, that would help me a lot.
>
> Thanks,
> NeilBrown
>
>
> diff ./.patches/orig/block/ll_rw_blk.c ./block/ll_rw_blk.c
> --- ./.patches/orig/block/ll_rw_blk.c	2006-08-21 09:52:46.000000000 +1000
> +++ ./block/ll_rw_blk.c	2006-10-05 11:33:32.000000000 +1000
> @@ -1546,6 +1546,7 @@ static int ll_merge_requests_fn(request_
>   * This is called with interrupts off and no requests on the queue and
>   * with the queue lock held.
>   */
> +static atomic_t seq = ATOMIC_INIT(0);
>  void blk_plug_device(request_queue_t *q)
>  {
>  	WARN_ON(!irqs_disabled());
> @@ -1558,9 +1559,16 @@ void blk_plug_device(request_queue_t *q)
>  		return;
>  
>  	if (!test_and_set_bit(QUEUE_FLAG_PLUGGED, &q->queue_flags)) {
> +		q->last_plug = jiffies;
> +		q->plug_seq = atomic_read(&seq);
> +		atomic_inc(&seq);
>  		mod_timer(&q->unplug_timer, jiffies + q->unplug_delay);
>  		blk_add_trace_generic(q, NULL, 0, BLK_TA_PLUG);
> -	}
> +	} else
> +		q->last_plug_skip = jiffies;
> +	if (!timer_pending(&q->unplug_timer) &&
> +	    !q->unplug_work.pending)
> +		printk("Neither Timer or work are pending\n");
>  }
>  
>  EXPORT_SYMBOL(blk_plug_device);
> @@ -1573,10 +1581,17 @@ int blk_remove_plug(request_queue_t *q)
>  {
>  	WARN_ON(!irqs_disabled());
>  
> -	if (!test_and_clear_bit(QUEUE_FLAG_PLUGGED, &q->queue_flags))
> +	if (!test_and_clear_bit(QUEUE_FLAG_PLUGGED, &q->queue_flags)) {
> +		q->last_unplug_skip = jiffies;
>  		return 0;
> +	}
>  
>  	del_timer(&q->unplug_timer);
> +	q->last_unplug = jiffies;
> +	q->unplug_seq = atomic_read(&seq);
> +	atomic_inc(&seq);
> +	if (test_bit(QUEUE_FLAG_PLUGGED, &q->queue_flags))
> +		printk("queue still (or again) plugged\n");
>  	return 1;
>  }
>  
> @@ -1635,7 +1650,7 @@ static void blk_backing_dev_unplug(struc
>  static void blk_unplug_work(void *data)
>  {
>  	request_queue_t *q = data;
> -
> +	q->last_unplug_work = jiffies;
>  	blk_add_trace_pdu_int(q, BLK_TA_UNPLUG_IO, NULL,
>  				q->rq.count[READ] + q->rq.count[WRITE]);
>  
> @@ -1649,6 +1664,7 @@ static void blk_unplug_timeout(unsigned 
>  	blk_add_trace_pdu_int(q, BLK_TA_UNPLUG_TIMER, NULL,
>  				q->rq.count[READ] + q->rq.count[WRITE]);
>  
> +	q->last_unplug_timeout = jiffies;
>  	kblockd_schedule_work(&q->unplug_work);
>  }
>  
>
> diff ./.patches/orig/drivers/md/raid1.c ./drivers/md/raid1.c
> --- ./.patches/orig/drivers/md/raid1.c	2006-08-10 17:28:01.000000000 +1000
> +++ ./drivers/md/raid1.c	2006-09-04 21:58:31.000000000 +1000
> @@ -1486,7 +1486,6 @@ static void raid1d(mddev_t *mddev)
>  							d = conf->raid_disks;
>  						d--;
>  						rdev = conf->mirrors[d].rdev;
> -						atomic_add(s, &rdev->corrected_errors);
>  						if (rdev &&
>  						    test_bit(In_sync, &rdev->flags)) {
>  							if (sync_page_io(rdev->bdev,
> @@ -1509,6 +1508,9 @@ static void raid1d(mddev_t *mddev)
>  									 s<<9, conf->tmppage, READ) == 0)
>  								/* Well, this device is dead */
>  								md_error(mddev, rdev);
> +							else
> +								atomic_add(s, &rdev->corrected_errors);
> +
>  						}
>  					}
>  				} else {
>
> diff ./.patches/orig/drivers/md/raid5.c ./drivers/md/raid5.c
> --- ./.patches/orig/drivers/md/raid5.c	2006-08-10 17:28:01.000000000 +1000
> +++ ./drivers/md/raid5.c	2006-09-25 11:11:59.000000000 +1000
> @@ -93,6 +93,8 @@ static void __release_stripe(raid5_conf_
>  					md_wakeup_thread(conf->mddev->thread);
>  			}
>  			atomic_dec(&conf->active_stripes);
> +			if (atomic_read(&conf->active_stripes) < conf->low_size)
> +				conf->low_size = atomic_read(&conf->active_stripes);
>  			if (!test_bit(STRIPE_EXPANDING, &sh->state)) {
>  				list_add_tail(&sh->lru, &conf->inactive_list);
>  				wake_up(&conf->wait_for_stripe);
> @@ -1677,7 +1679,12 @@ static void raid5_unplug_device(request_
>  
>  	spin_lock_irqsave(&conf->device_lock, flags);
>  
> +	if (conf->dotrace)
> +		printk(" trace unplug_device\n");
> +
>  	if (blk_remove_plug(q)) {
> +		if (conf->dotrace)
> +			printk(" trace remove plug\n");
>  		conf->seq_flush++;
>  		raid5_activate_delayed(conf);
>  	}
> @@ -1721,6 +1728,8 @@ static int raid5_issue_flush(request_que
>  static inline void raid5_plug_device(raid5_conf_t *conf)
>  {
>  	spin_lock_irq(&conf->device_lock);
> +	if (conf->dotrace)
> +		printk(" trace plug device\n");
>  	blk_plug_device(conf->mddev->queue);
>  	spin_unlock_irq(&conf->device_lock);
>  }
> @@ -2154,6 +2163,42 @@ static ssize_t
>  stripe_cache_active_show(mddev_t *mddev, char *page)
>  {
>  	raid5_conf_t *conf = mddev_to_conf(mddev);
> +
> +	/* tracing */
> +	if (conf->dotrace) {
> +		conf->dotrace = 0;
> +		printk("end trace, force unplug\n");
> +		raid5_unplug_device(mddev->queue);
> +		raid5_unplug_device(mddev->queue);
> +	} else {
> +		if (conf->last_size > conf->max_nr_stripes/2 &&
> +		    conf->last_size <= conf->low_size) {
> +			conf->dotrace = 1;
> +			printk("plug problem: low_size=%d\n", conf->low_size);
> +			printk(" blk_queue_plugged = %d\n", blk_queue_plugged(mddev->queue));
> +			printk(" flags = %lx\n", mddev->queue->queue_flags);
> +			printk(" unplug_delay = %lu (HZ=%d)\n", mddev->queue->unplug_delay, HZ);
> +			printk(" timer->expires %lu (jiffies %lu)\n",
> +			       mddev->queue->unplug_timer.expires, jiffies);
> +			printk(" pending = %d\n", timer_pending(&mddev->queue->unplug_timer));
> +			printk(" wq_pending = %lx\n", mddev->queue->unplug_work.pending);
> +			printk(" wq_entry empty? %d\n", list_empty(&mddev->queue->unplug_work.entry));
> +			printk(" unplug=%lu unplug_skip=%lu\n",
> +			       mddev->queue->last_unplug,
> +			       mddev->queue->last_unplug_skip);
> +			printk(" plug=%lu plug_skip=%lu\n",
> +			       mddev->queue->last_plug,
> +			       mddev->queue->last_plug_skip);
> +			printk(" unplug_work=%lu unplug_timeout=%lu\n",
> +			       mddev->queue->last_unplug_work,
> +			       mddev->queue->last_unplug_timeout);
> +			printk(" unplug_seq=%lu plug_seq=%lu\n",
> +			       mddev->queue->unplug_seq,
> +			       mddev->queue->plug_seq);
> +		}
> +		conf->last_size = atomic_read(&conf->active_stripes);
> +		conf->low_size = conf->last_size;
> +	}
>  	if (conf)
>  		return sprintf(page, "%d\n", atomic_read(&conf->active_stripes));
>  	else
>
> diff ./.patches/orig/include/linux/blkdev.h ./include/linux/blkdev.h
> --- ./.patches/orig/include/linux/blkdev.h	2006-08-10 17:28:48.000000000 +1000
> +++ ./include/linux/blkdev.h	2006-09-25 11:08:27.000000000 +1000
> @@ -380,6 +380,9 @@ struct request_queue
>  	 */
>  	unsigned long		queue_flags;
>  
> +	unsigned long last_unplug, last_unplug_skip, last_plug, last_plug_skip;
> +	unsigned long last_unplug_work, last_unplug_timeout;
> +	unsigned long unplug_seq, plug_seq;
>  	/*
>  	 * protects queue structures from reentrancy. ->__queue_lock should
>  	 * _never_ be used directly, it is queue private. always use
>
> diff ./.patches/orig/include/linux/raid/raid5.h ./include/linux/raid/raid5.h
> --- ./.patches/orig/include/linux/raid/raid5.h	2006-08-10 17:28:53.000000000 +1000
> +++ ./include/linux/raid/raid5.h	2006-08-28 14:09:32.000000000 +1000
> @@ -245,6 +245,10 @@ struct raid5_private_data {
>  
>  	struct page 		*spare_page; /* Used when checking P/Q in raid6 */
>  
> +	int dotrace;
> +	int last_size;
> +	int low_size;
> +
>  	/*
>  	 * Free stripes pool
>  	 */
>   

  parent reply	other threads:[~2006-11-14 10:28 UTC|newest]

Thread overview: 43+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-03-06 11:46 raid5 performance question Raz Ben-Jehuda(caro)
2006-03-06 11:59 ` Gordon Henderson
2006-03-06 12:56   ` Raz Ben-Jehuda(caro)
2006-03-13 22:36     ` raid5 hang on get_active_stripe Patrik Jonsson
2006-03-13 23:17       ` Neil Brown
2006-05-11 15:13         ` dean gaudet
2006-05-17 18:41           ` dean gaudet
2006-05-19  3:46             ` Neil Brown
2006-05-23  2:33             ` Neil Brown
2006-05-26 16:07               ` dean gaudet
2006-05-26 23:55                 ` Neil Brown
2006-05-27  0:28                   ` dean gaudet
2006-05-27 15:42                   ` dean gaudet
2006-05-28 12:04                     ` Neil Brown
2006-05-29 20:56                       ` dean gaudet
2006-05-29 23:51                         ` Neil Brown
2006-05-31  0:15                           ` dean gaudet
2006-05-31  0:46                             ` Neil Brown
2006-05-31  1:03                               ` dean gaudet
2006-05-31  1:38                                 ` Neil Brown
2006-05-31  1:46                                   ` dean gaudet
2006-06-01  2:51                                     ` Neil Brown
2006-06-02  7:10                                       ` dean gaudet
2006-06-02  7:27                                         ` Neil Brown
2006-06-10 19:49                                           ` dean gaudet
2006-06-13 18:53                                           ` Bill Davidsen
2006-06-13 19:05                                             ` dean gaudet
2006-06-13 23:13                                             ` Neil Brown
2006-10-07 23:25                                               ` Chris Allen
2006-10-09 11:03                                                 ` Chris Allen
2006-10-09 23:06                                                   ` Neil Brown
2006-10-09 23:21                                                     ` Chris Allen
2006-10-10  0:08                                                       ` Neil Brown
2006-10-10 10:27                                                         ` Bas van Schaik
2006-11-14 10:28                                                         ` Chris Allen [this message]
2006-11-15 20:39                                                           ` dean gaudet
2006-03-06 22:17 ` raid5 performance question Guy
2006-03-06 22:24 ` Neil Brown
2006-03-07  8:40   ` Raz Ben-Jehuda(caro)
2006-03-07 23:03     ` Neil Brown
2006-03-22 13:22       ` Bill Davidsen
2006-03-24  4:40         ` Neil Brown
2006-03-08  6:45   ` thunder7

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=45599A4D.8090907@cjx.com \
    --to=chris@cjx.com \
    --cc=linux-raid@vger.kernel.org \
    --cc=neilb@suse.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).