+ current_time = cfs_time_current();
+
+ delta_time = cfs_time_sub(current_time, lcw->lcw_last_touched);
+ cfs_duration_usec(delta_time, &timediff);
+
+ /* Check to see if we should throttle the watchdog timer to avoid
+ * too many dumps going to the console thus triggering an NMI.
+ * Normally we would not hold the spin lock over the CWARN but in
+ * this case we hold it to ensure non ratelimited lcw_dumps are not
+ * interleaved on the console making them hard to read. */
+ cfs_spin_lock_bh(&lcw_last_watchdog_lock);
+ delta_time = cfs_duration_sec(cfs_time_sub(current_time,
+ lcw_last_watchdog_time));
+
+ if (delta_time < libcfs_watchdog_ratelimit &&
+ lcw_recent_watchdog_count > 3) {
+ LCONSOLE_WARN("Service thread pid %u was inactive for "
+ "%lu.%.02lus. Watchdog stack traces are limited "
+ "to 3 per %d seconds, skipping this one.\n",
+ (int)lcw->lcw_pid,
+ timediff.tv_sec,
+ timediff.tv_usec / 10000,
+ libcfs_watchdog_ratelimit);
+ } else {
+ if (delta_time < libcfs_watchdog_ratelimit) {
+ lcw_recent_watchdog_count++;
+ } else {
+ memcpy(&lcw_last_watchdog_time, ¤t_time,
+ sizeof(current_time));
+ lcw_recent_watchdog_count = 0;
+ }