]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/mds/SessionMap.h
update sources to 12.2.10
[ceph.git] / ceph / src / mds / SessionMap.h
index b9714eeb01044a2570bc9330489cf394f74b78a4..217b4ba1511ef78aa312086dc8ddb4e441f315af 100644 (file)
@@ -30,6 +30,7 @@ using std::set;
 
 class CInode;
 struct MDRequestImpl;
+class DecayCounter;
 
 #include "CInode.h"
 #include "Capability.h"
@@ -40,6 +41,11 @@ enum {
   l_mdssm_session_count,
   l_mdssm_session_add,
   l_mdssm_session_remove,
+  l_mdssm_session_open,
+  l_mdssm_session_stale,
+  l_mdssm_total_load,
+  l_mdssm_avg_load,
+  l_mdssm_avg_session_uptime,
   l_mdssm_last,
 };
 
@@ -63,6 +69,11 @@ public:
     + additional dimension of 'importing' (with counter)
 
   */
+
+  using clock = ceph::coarse_mono_clock;
+  using time = ceph::coarse_mono_time;
+
+
   enum {
     STATE_CLOSED = 0,
     STATE_OPENING = 1,   // journaling open
@@ -98,7 +109,15 @@ private:
   // that appropriate mark_dirty calls follow.
   std::deque<version_t> projected;
 
+  // request load average for this session
+  mutable DecayCounter load_avg;
+  DecayRate    load_avg_rate;
 
+  // session start time -- used to track average session time
+  // note that this is initialized in the constructor rather
+  // than at the time of adding a session to the sessionmap
+  // as journal replay of sessionmap will not call add_session().
+  time birth_time;
 
 public:
 
@@ -128,8 +147,8 @@ public:
   std::string get_human_name() const {return human_name;}
 
   // Ephemeral state for tracking progress of capability recalls
-  utime_t recalled_at;  // When was I asked to SESSION_RECALL?
-  utime_t last_recall_sent;
+  time recalled_at = time::min();  // When was I asked to SESSION_RECALL?
+  time last_recall_sent = time::min();
   uint32_t recall_count;  // How many caps was I asked to SESSION_RECALL?
   uint32_t recall_release_count;  // How many caps have I actually revoked?
 
@@ -198,6 +217,26 @@ public:
   }
   bool is_importing() const { return importing_count > 0; }
 
+  void set_load_avg_decay_rate(double rate) {
+    assert(is_open() || is_stale());
+    load_avg_rate.set_halflife(rate);
+  }
+  uint64_t get_load_avg() const {
+    return (uint64_t)load_avg.get(ceph_clock_now(), load_avg_rate);
+  }
+  void hit_session() {
+    load_avg.hit(ceph_clock_now(), load_avg_rate);
+  }
+
+  double get_session_uptime() const {
+    chrono::duration<double> uptime = clock::now() - birth_time;
+    return uptime.count();
+  }
+
+  time get_birth_time() const {
+    return birth_time;
+  }
+
   // -- caps --
 private:
   version_t cap_push_seq;        // cap push seq #
@@ -206,7 +245,7 @@ private:
 public:
   xlist<Capability*> caps;     // inodes with caps; front=most recently used
   xlist<ClientLease*> leases;  // metadata leases to clients
-  utime_t last_cap_renew;
+  time last_cap_renew = time::min();
 
 public:
   version_t inc_push_seq() { return ++cap_push_seq; }
@@ -320,8 +359,8 @@ public:
 
   Session() : 
     state(STATE_CLOSED), state_seq(0), importing_count(0),
-    recall_count(0), recall_release_count(0),
-    auth_caps(g_ceph_context),
+    birth_time(clock::now()), recall_count(0),
+    recall_release_count(0), auth_caps(g_ceph_context),
     connection(NULL), item_session_list(this),
     requests(0),  // member_offset passed to front() manually
     cap_push_seq(0),
@@ -346,8 +385,7 @@ public:
     info.clear_meta();
 
     cap_push_seq = 0;
-    last_cap_renew = utime_t();
-
+    last_cap_renew = time::min();
   }
 };
 
@@ -389,10 +427,20 @@ class MDSRank;
  * encode/decode outside of live MDS instance.
  */
 class SessionMapStore {
+public:
+  using clock = Session::clock;
+  using time = Session::time;
+
 protected:
   version_t version;
   ceph::unordered_map<entity_name_t, Session*> session_map;
   PerfCounters *logger;
+
+  // total request load avg
+  double decay_rate;
+  DecayCounter total_load_avg;
+  DecayRate    total_load_avg_rate;
+
 public:
   mds_rank_t rank;
 
@@ -417,7 +465,7 @@ public:
     } else {
       s = session_map[i.name] = new Session;
       s->info.inst = i;
-      s->last_cap_renew = ceph_clock_now();
+      s->last_cap_renew = Session::clock::now();
       if (logger) {
         logger->set(l_mdssm_session_count, session_map.size());
         logger->inc(l_mdssm_session_add);
@@ -434,7 +482,11 @@ public:
     session_map.clear();
   }
 
-  SessionMapStore() : version(0), logger(nullptr), rank(MDS_RANK_NONE) {}
+  SessionMapStore()
+    : version(0), logger(nullptr),
+      decay_rate(g_conf->get_val<double>("mds_request_load_average_decay_rate")),
+      total_load_avg_rate(decay_rate), rank(MDS_RANK_NONE) {
+  }
   virtual ~SessionMapStore() {};
 };
 
@@ -448,6 +500,7 @@ public:
   map<int,xlist<Session*>* > by_state;
   uint64_t set_state(Session *session, int state);
   map<version_t, list<MDSInternalContextBase*> > commit_waiters;
+  void update_average_session_age();
 
   explicit SessionMap(MDSRank *m) : mds(m),
                       projected(0), committing(0), committed(0),
@@ -661,6 +714,38 @@ public:
    */
   void save_if_dirty(const std::set<entity_name_t> &tgt_sessions,
                      MDSGatherBuilder *gather_bld);
+
+private:
+  time avg_birth_time = time::min();
+
+  uint64_t get_session_count_in_state(int state) {
+    return !is_any_state(state) ? 0 : by_state[state]->size();
+  }
+
+  void update_average_birth_time(const Session &s, bool added=true) {
+    uint32_t sessions = session_map.size();
+    time birth_time = s.get_birth_time();
+
+    if (sessions == 1) {
+      avg_birth_time = added ? birth_time : time::min();
+      return;
+    }
+
+    if (added) {
+      avg_birth_time = clock::time_point(
+        ((avg_birth_time - time::min()) / sessions) * (sessions - 1) +
+        (birth_time - time::min()) / sessions);
+    } else {
+      avg_birth_time = clock::time_point(
+        ((avg_birth_time - time::min()) / (sessions - 1)) * sessions -
+        (birth_time - time::min()) / (sessions - 1));
+    }
+  }
+
+public:
+  void hit_session(Session *session);
+  void handle_conf_change(const struct md_config_t *conf,
+                          const std::set <std::string> &changed);
 };
 
 std::ostream& operator<<(std::ostream &out, const Session &s);