#define CEPH_OSD_KEEPALIVE_DEFAULT     msecs_to_jiffies(5 * 1000)
 #define CEPH_OSD_IDLE_TTL_DEFAULT      msecs_to_jiffies(60 * 1000)
 
+#define CEPH_MONC_HUNT_INTERVAL                msecs_to_jiffies(3 * 1000)
 #define CEPH_MONC_PING_INTERVAL                msecs_to_jiffies(10 * 1000)
 #define CEPH_MONC_PING_TIMEOUT         msecs_to_jiffies(30 * 1000)
+#define CEPH_MONC_HUNT_BACKOFF         2
+#define CEPH_MONC_HUNT_MAX_MULT                10
 
 #define CEPH_MSG_MAX_FRONT_LEN (16*1024*1024)
 #define CEPH_MSG_MAX_MIDDLE_LEN        (16*1024*1024)
 
        unsigned long sub_renew_sent;
        struct ceph_connection con;
 
+       bool had_a_connection;
+       int hunt_mult; /* [1..CEPH_MONC_HUNT_MAX_MULT] */
+
        /* pending generic requests */
        struct rb_root generic_request_tree;
        int num_generic_requests;
 
 
        pick_new_mon(monc);
 
+       if (monc->had_a_connection) {
+               monc->hunt_mult *= CEPH_MONC_HUNT_BACKOFF;
+               if (monc->hunt_mult > CEPH_MONC_HUNT_MAX_MULT)
+                       monc->hunt_mult = CEPH_MONC_HUNT_MAX_MULT;
+       }
+
        monc->sub_renew_after = jiffies; /* i.e., expired */
        monc->sub_renew_sent = 0;
 
        __send_prepared_auth_request(monc, ret);
 }
 
-static bool __sub_expired(struct ceph_mon_client *monc)
-{
-       return time_after_eq(jiffies, monc->sub_renew_after);
-}
-
 /*
  * Reschedule delayed work timer.
  */
 {
        unsigned long delay;
 
-       if (monc->cur_mon < 0 || __sub_expired(monc)) {
-               delay = 10 * HZ;
-       } else {
+       if (monc->hunting)
+               delay = CEPH_MONC_HUNT_INTERVAL * monc->hunt_mult;
+       else
                delay = CEPH_MONC_PING_INTERVAL;
-       }
+
        dout("__schedule_delayed after %lu\n", delay);
        schedule_delayed_work(&monc->delayed_work,
                              round_jiffies_relative(delay));
        monc->hunting = true;
        monc->sub_renew_after = jiffies;
        monc->sub_renew_sent = 0;
+       monc->had_a_connection = false;
+       monc->hunt_mult = 1;
 
        INIT_DELAYED_WORK(&monc->delayed_work, delayed_work);
        monc->generic_request_tree = RB_ROOT;
        if (monc->hunting) {
                dout("%s found mon%d\n", __func__, monc->cur_mon);
                monc->hunting = false;
+               monc->had_a_connection = true;
+               monc->hunt_mult /= 2; /* reduce by 50% */
+               if (monc->hunt_mult < 1)
+                       monc->hunt_mult = 1;
        }
 }