|
@@ -30,9 +30,10 @@ static int try_to_freeze_tasks(bool user_only)
|
|
|
unsigned int todo;
|
|
|
bool wq_busy = false;
|
|
|
struct timeval start, end;
|
|
|
- u64 elapsed_csecs64;
|
|
|
- unsigned int elapsed_csecs;
|
|
|
+ u64 elapsed_msecs64;
|
|
|
+ unsigned int elapsed_msecs;
|
|
|
bool wakeup = false;
|
|
|
+ int sleep_usecs = USEC_PER_MSEC;
|
|
|
|
|
|
do_gettimeofday(&start);
|
|
|
|
|
@@ -68,22 +69,25 @@ static int try_to_freeze_tasks(bool user_only)
|
|
|
|
|
|
/*
|
|
|
* We need to retry, but first give the freezing tasks some
|
|
|
- * time to enter the refrigerator.
|
|
|
+ * time to enter the refrigerator. Start with an initial
|
|
|
+ * 1 ms sleep followed by exponential backoff until 8 ms.
|
|
|
*/
|
|
|
- msleep(10);
|
|
|
+ usleep_range(sleep_usecs / 2, sleep_usecs);
|
|
|
+ if (sleep_usecs < 8 * USEC_PER_MSEC)
|
|
|
+ sleep_usecs *= 2;
|
|
|
}
|
|
|
|
|
|
do_gettimeofday(&end);
|
|
|
- elapsed_csecs64 = timeval_to_ns(&end) - timeval_to_ns(&start);
|
|
|
- do_div(elapsed_csecs64, NSEC_PER_SEC / 100);
|
|
|
- elapsed_csecs = elapsed_csecs64;
|
|
|
+ elapsed_msecs64 = timeval_to_ns(&end) - timeval_to_ns(&start);
|
|
|
+ do_div(elapsed_msecs64, NSEC_PER_MSEC);
|
|
|
+ elapsed_msecs = elapsed_msecs64;
|
|
|
|
|
|
if (todo) {
|
|
|
printk("\n");
|
|
|
- printk(KERN_ERR "Freezing of tasks %s after %d.%02d seconds "
|
|
|
+ printk(KERN_ERR "Freezing of tasks %s after %d.%03d seconds "
|
|
|
"(%d tasks refusing to freeze, wq_busy=%d):\n",
|
|
|
wakeup ? "aborted" : "failed",
|
|
|
- elapsed_csecs / 100, elapsed_csecs % 100,
|
|
|
+ elapsed_msecs / 1000, elapsed_msecs % 1000,
|
|
|
todo - wq_busy, wq_busy);
|
|
|
|
|
|
if (!wakeup) {
|
|
@@ -96,8 +100,8 @@ static int try_to_freeze_tasks(bool user_only)
|
|
|
read_unlock(&tasklist_lock);
|
|
|
}
|
|
|
} else {
|
|
|
- printk("(elapsed %d.%02d seconds) ", elapsed_csecs / 100,
|
|
|
- elapsed_csecs % 100);
|
|
|
+ printk("(elapsed %d.%03d seconds) ", elapsed_msecs / 1000,
|
|
|
+ elapsed_msecs % 1000);
|
|
|
}
|
|
|
|
|
|
return todo ? -EBUSY : 0;
|