unlock_page(page);
 }
 
-void reclaim_throttle(pg_data_t *pgdat, enum vmscan_throttle_state reason,
-                                                       long timeout)
+void reclaim_throttle(pg_data_t *pgdat, enum vmscan_throttle_state reason)
 {
        wait_queue_head_t *wqh = &pgdat->reclaim_wait[reason];
-       long ret;
-       bool acct_writeback = (reason == VMSCAN_THROTTLE_WRITEBACK);
+       long timeout, ret;
        DEFINE_WAIT(wait);
 
        /*
            current->flags & (PF_IO_WORKER|PF_KTHREAD))
                return;
 
-       if (acct_writeback &&
-           atomic_inc_return(&pgdat->nr_writeback_throttled) == 1) {
-               WRITE_ONCE(pgdat->nr_reclaim_start,
-                       node_page_state(pgdat, NR_THROTTLED_WRITTEN));
+       /*
+        * These figures are pulled out of thin air.
+        * VMSCAN_THROTTLE_ISOLATED is a transient condition based on too many
+        * parallel reclaimers which is a short-lived event so the timeout is
+        * short. Failing to make progress or waiting on writeback are
+        * potentially long-lived events so use a longer timeout. This is shaky
+        * logic as a failure to make progress could be due to anything from
+        * writeback to a slow device to excessive references pages at the tail
+        * of the inactive LRU.
+        */
+       switch(reason) {
+       case VMSCAN_THROTTLE_WRITEBACK:
+               timeout = HZ/10;
+
+               if (atomic_inc_return(&pgdat->nr_writeback_throttled) == 1) {
+                       WRITE_ONCE(pgdat->nr_reclaim_start,
+                               node_page_state(pgdat, NR_THROTTLED_WRITTEN));
+               }
+
+               break;
+       case VMSCAN_THROTTLE_NOPROGRESS:
+               timeout = HZ/10;
+               break;
+       case VMSCAN_THROTTLE_ISOLATED:
+               timeout = HZ/50;
+               break;
+       default:
+               WARN_ON_ONCE(1);
+               timeout = HZ;
+               break;
        }
 
        prepare_to_wait(wqh, &wait, TASK_UNINTERRUPTIBLE);
        ret = schedule_timeout(timeout);
        finish_wait(wqh, &wait);
 
-       if (acct_writeback)
+       if (reason == VMSCAN_THROTTLE_WRITEBACK)
                atomic_dec(&pgdat->nr_writeback_throttled);
 
        trace_mm_vmscan_throttled(pgdat->node_id, jiffies_to_usecs(timeout),
 
                /* wait a bit for the reclaimer. */
                stalled = true;
-               reclaim_throttle(pgdat, VMSCAN_THROTTLE_ISOLATED, HZ/10);
+               reclaim_throttle(pgdat, VMSCAN_THROTTLE_ISOLATED);
 
                /* We are about to die and free our memory. Return now. */
                if (fatal_signal_pending(current))
                 * until some pages complete writeback.
                 */
                if (sc->nr.immediate)
-                       reclaim_throttle(pgdat, VMSCAN_THROTTLE_WRITEBACK, HZ/10);
+                       reclaim_throttle(pgdat, VMSCAN_THROTTLE_WRITEBACK);
        }
 
        /*
        if (!current_is_kswapd() && current_may_throttle() &&
            !sc->hibernation_mode &&
            test_bit(LRUVEC_CONGESTED, &target_lruvec->flags))
-               reclaim_throttle(pgdat, VMSCAN_THROTTLE_WRITEBACK, HZ/10);
+               reclaim_throttle(pgdat, VMSCAN_THROTTLE_WRITEBACK);
 
        if (should_continue_reclaim(pgdat, sc->nr_reclaimed - nr_reclaimed,
                                    sc))
 
        /* Throttle if making no progress at high prioities. */
        if (sc->priority < DEF_PRIORITY - 2)
-               reclaim_throttle(pgdat, VMSCAN_THROTTLE_NOPROGRESS, HZ/10);
+               reclaim_throttle(pgdat, VMSCAN_THROTTLE_NOPROGRESS);
 }
 
 /*