diff options
author | Mark Lord <kernel@teksavvy.com> | 2010-09-24 09:51:13 -0400 |
---|---|---|
committer | Jens Axboe <jaxboe@fusionio.com> | 2010-09-24 09:52:09 -0400 |
commit | 4b1977698ceb4c4caa800d475127139da49966f9 (patch) | |
tree | 9302bafc15dfb6d3923febaa982feb2cb12063cb /block | |
parent | 749ef9f8423054e326f3a246327ed2db4b6d395f (diff) |
block: Prevent hang_check firing during long I/O
During long I/O operations, the hang_check timer may fire,
trigger stack dumps that unnecessarily alarm the user.
Eg. hdparm --security-erase NULL /dev/sdb ## can take *hours* to complete
So, if hang_check is armed, we should wake up periodically
to prevent it from triggering. This patch uses a wake-up interval
equal to half the hang_check timer period, which keeps overhead low enough.
Signed-off-by: Mark Lord <mlord@pobox.com>
Signed-off-by: Jens Axboe <jaxboe@fusionio.com>
Diffstat (limited to 'block')
-rw-r--r-- | block/blk-exec.c | 9 |
1 files changed, 8 insertions, 1 deletions
diff --git a/block/blk-exec.c b/block/blk-exec.c index e1672f14840e..cf1456a02acd 100644 --- a/block/blk-exec.c +++ b/block/blk-exec.c | |||
@@ -80,6 +80,7 @@ int blk_execute_rq(struct request_queue *q, struct gendisk *bd_disk, | |||
80 | DECLARE_COMPLETION_ONSTACK(wait); | 80 | DECLARE_COMPLETION_ONSTACK(wait); |
81 | char sense[SCSI_SENSE_BUFFERSIZE]; | 81 | char sense[SCSI_SENSE_BUFFERSIZE]; |
82 | int err = 0; | 82 | int err = 0; |
83 | unsigned long hang_check; | ||
83 | 84 | ||
84 | /* | 85 | /* |
85 | * we need an extra reference to the request, so we can look at | 86 | * we need an extra reference to the request, so we can look at |
@@ -95,7 +96,13 @@ int blk_execute_rq(struct request_queue *q, struct gendisk *bd_disk, | |||
95 | 96 | ||
96 | rq->end_io_data = &wait; | 97 | rq->end_io_data = &wait; |
97 | blk_execute_rq_nowait(q, bd_disk, rq, at_head, blk_end_sync_rq); | 98 | blk_execute_rq_nowait(q, bd_disk, rq, at_head, blk_end_sync_rq); |
98 | wait_for_completion(&wait); | 99 | |
100 | /* Prevent hang_check timer from firing at us during very long I/O */ | ||
101 | hang_check = sysctl_hung_task_timeout_secs; | ||
102 | if (hang_check) | ||
103 | while (!wait_for_completion_timeout(&wait, hang_check * (HZ/2))); | ||
104 | else | ||
105 | wait_for_completion(&wait); | ||
99 | 106 | ||
100 | if (rq->errors) | 107 | if (rq->errors) |
101 | err = -EIO; | 108 | err = -EIO; |