Commit 4b1977698ceb4c4caa800d475127139da49966f9

Authored by Mark Lord
Committed by Jens Axboe
1 parent 749ef9f842

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>

Showing 1 changed file with 8 additions and 1 deletions Side-by-side Diff

... ... @@ -80,6 +80,7 @@
80 80 DECLARE_COMPLETION_ONSTACK(wait);
81 81 char sense[SCSI_SENSE_BUFFERSIZE];
82 82 int err = 0;
  83 + unsigned long hang_check;
83 84  
84 85 /*
85 86 * we need an extra reference to the request, so we can look at
... ... @@ -95,7 +96,13 @@
95 96  
96 97 rq->end_io_data = &wait;
97 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 107 if (rq->errors)
101 108 err = -EIO;