]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: add list to track recently used sub-directories
authorYan, Zheng <zyan@redhat.com>
Mon, 2 Apr 2018 12:32:14 +0000 (20:32 +0800)
committerYan, Zheng <zyan@redhat.com>
Thu, 19 Apr 2018 00:10:27 +0000 (08:10 +0800)
MDBalancer::find_exports() can be more efficient with LRU list.

Signed-off-by: "Yan, Zheng" <zyan@redhat.com>
(cherry picked from commit 65a35e2a76bbf1ce21a8848a4a92f70a0c6b3728)

src/mds/CDir.cc
src/mds/CDir.h
src/mds/CInode.h
src/mds/MDBalancer.cc
src/mds/MDCache.cc
src/mds/Migrator.cc

index dd19ac02cec1ef79d8c5c89024e0fcfcbcf6576d..51bf24711299a3b91fdeeb45d6579df1451cc38c 100644 (file)
@@ -196,6 +196,7 @@ CDir::CDir(CInode *in, frag_t fg, MDCache *mdcache, bool auth) :
   pop_nested(ceph_clock_now()),
   pop_auth_subtree(ceph_clock_now()),
   pop_auth_subtree_nested(ceph_clock_now()),
+  pop_lru_subdirs(member_offset(CInode, item_pop_lru)),
   num_dentries_nested(0), num_dentries_auth_subtree(0),
   num_dentries_auth_subtree_nested(0),
   dir_auth(CDIR_AUTH_DEFAULT)
@@ -386,7 +387,6 @@ CDentry* CDir::add_primary_dentry(boost::string_view dname, CInode *in,
   items[dn->key()] = dn;
 
   dn->get_linkage()->inode = in;
-  in->set_primary_parent(dn);
 
   link_inode_work(dn, in);
 
@@ -533,7 +533,6 @@ void CDir::link_primary_inode(CDentry *dn, CInode *in)
   assert(dn->get_linkage()->is_null());
 
   dn->get_linkage()->inode = in;
-  in->set_primary_parent(dn);
 
   link_inode_work(dn, in);
 
@@ -558,7 +557,7 @@ void CDir::link_primary_inode(CDentry *dn, CInode *in)
 void CDir::link_inode_work( CDentry *dn, CInode *in)
 {
   assert(dn->get_linkage()->get_inode() == in);
-  assert(in->get_parent_dn() == dn);
+  in->set_primary_parent(dn);
 
   // set inode version
   //in->inode.version = dn->get_version();
@@ -646,9 +645,11 @@ void CDir::unlink_inode_work( CDentry *dn )
     // unlink auth_pin count
     if (in->auth_pins + in->nested_auth_pins)
       dn->adjust_nested_auth_pins(0 - (in->auth_pins + in->nested_auth_pins), 0 - in->auth_pins, NULL);
-    
+
     // detach inode
     in->remove_primary_parent(dn);
+    if (in->is_dir())
+      in->item_pop_lru.remove_myself();
     dn->get_linkage()->inode = 0;
   } else {
     assert(!dn->get_linkage()->is_null());
@@ -823,10 +824,13 @@ void CDir::steal_dentry(CDentry *dn)
     if (dn->get_linkage()->is_primary()) {
       CInode *in = dn->get_linkage()->get_inode();
       auto pi = in->get_projected_inode();
-      if (dn->get_linkage()->get_inode()->is_dir())
+      if (in->is_dir()) {
        fnode.fragstat.nsubdirs++;
-      else
+       if (in->item_pop_lru.is_on_list())
+         pop_lru_subdirs.push_back(&in->item_pop_lru);
+      } else {
        fnode.fragstat.nfiles++;
+      }
       fnode.rstat.rbytes += pi->accounted_rstat.rbytes;
       fnode.rstat.rfiles += pi->accounted_rstat.rfiles;
       fnode.rstat.rsubdirs += pi->accounted_rstat.rsubdirs;
index b8ad1b13311a76562e9d1889a8b3fca4064913c1..129d76fa7feeef757e27d4474aa8dc6df9b059c1 100644 (file)
@@ -362,6 +362,8 @@ protected:
 
   load_spread_t pop_spread;
 
+  elist<CInode*> pop_lru_subdirs;
+
   // and to provide density
   int num_dentries_nested;
   int num_dentries_auth_subtree;
index c735f43a2f011ea489c300002a190540462392cc..d93dcbc3efe2eb7a868b253abcbc9b6ea6893541 100644 (file)
@@ -631,6 +631,7 @@ public:
   int auth_pin_freeze_allowance = 0;
 
   inode_load_vec_t pop;
+  elist<CInode*>::item item_pop_lru;
 
   // friends
   friend class Server;
index 2faa32f09e159eb6d5407ed7e5794c48cdba353c..435d546d42f26766de20bfbeacad565854555e66 100644 (file)
@@ -987,13 +987,18 @@ void MDBalancer::find_exports(CDir *dir,
   dout(7) << " find_exports in " << dir_pop << " " << *dir << " need " << need << " (" << needmin << " - " << needmax << ")" << dendl;
 
   double subdir_sum = 0;
-  for (auto it = dir->begin(); it != dir->end(); ++it) {
-    CInode *in = it->second->get_linkage()->get_inode();
-    if (!in) continue;
-    if (!in->is_dir()) continue;
+  for (elist<CInode*>::iterator it = dir->pop_lru_subdirs.begin_use_current();
+       !it.end(); ) {
+    CInode *in = *it;
+    ++it;
+
+    assert(in->is_dir());
+    assert(in->get_parent_dir() == dir);
 
     list<CDir*> dfls;
     in->get_nested_dirfrags(dfls);
+
+    size_t num_idle_frags = 0;
     for (list<CDir*>::iterator p = dfls.begin();
         p != dfls.end();
         ++p) {
@@ -1012,7 +1017,10 @@ void MDBalancer::find_exports(CDir *dir,
       subdir_sum += pop;
       dout(15) << "   subdir pop " << pop << " " << *subdir << dendl;
 
-      if (pop < minchunk) continue;
+      if (pop < minchunk) {
+       num_idle_frags++;
+       continue;
+      }
 
       // lucky find?
       if (pop > needmin && pop < needmax) {
@@ -1030,6 +1038,8 @@ void MDBalancer::find_exports(CDir *dir,
       } else
        smaller.insert(pair<double,CDir*>(pop, subdir));
     }
+    if (dfls.size() == num_idle_frags)
+      in->item_pop_lru.remove_myself();
   }
   dout(15) << "   sum " << subdir_sum << " / " << dir_pop << dendl;
 
@@ -1197,14 +1207,21 @@ void MDBalancer::hit_dir(const utime_t& now, CDir *dir, int type, int who, doubl
   bool hit_subtree_nested = dir->is_auth();  // all nested auth subtrees
 
   while (true) {
+    CDir *pdir = dir->inode->get_parent_dir();
     dir->pop_nested.get(type).hit(now, mds->mdcache->decayrate, amount);
     if (rd_adj != 0.0)
       dir->pop_nested.get(META_POP_IRD).adjust(now, mds->mdcache->decayrate, rd_adj);
 
     if (hit_subtree) {
       dir->pop_auth_subtree.get(type).hit(now, mds->mdcache->decayrate, amount);
+
       if (rd_adj != 0.0)
        dir->pop_auth_subtree.get(META_POP_IRD).adjust(now, mds->mdcache->decayrate, rd_adj);
+
+      if (dir->is_subtree_root())
+       hit_subtree = false;                // end of auth domain, stop hitting auth counters.
+      else if (pdir)
+       pdir->pop_lru_subdirs.push_front(&dir->get_inode()->item_pop_lru);
     }
 
     if (hit_subtree_nested) {
@@ -1212,12 +1229,8 @@ void MDBalancer::hit_dir(const utime_t& now, CDir *dir, int type, int who, doubl
       if (rd_adj != 0.0)
        dir->pop_auth_subtree_nested.get(META_POP_IRD).adjust(now, mds->mdcache->decayrate, rd_adj);
     }
-
-    if (dir->is_subtree_root())
-      hit_subtree = false;                // end of auth domain, stop hitting auth counters.
-
-    if (dir->inode->get_parent_dn() == 0) break;
-    dir = dir->inode->get_parent_dn()->get_dir();
+    if (!pdir) break;
+    dir = pdir;
   }
 }
 
@@ -1263,11 +1276,14 @@ void MDBalancer::adjust_pop_for_rename(CDir *pdir, CDir *dir, utime_t now, bool
 
   bool adjust_subtree_nest = dir->is_auth();
   bool adjust_subtree = adjust_subtree_nest && !dir->is_subtree_root();
+  CDir *cur = dir;
   while (true) {
     if (inc) {
       pdir->pop_nested.add(now, rate, dir->pop_nested);
-      if (adjust_subtree)
+      if (adjust_subtree) {
        pdir->pop_auth_subtree.add(now, rate, dir->pop_auth_subtree);
+       pdir->pop_lru_subdirs.push_front(&cur->get_inode()->item_pop_lru);
+      }
 
       if (adjust_subtree_nest)
        pdir->pop_auth_subtree_nested.add(now, rate, dir->pop_auth_subtree_nested);
@@ -1282,6 +1298,7 @@ void MDBalancer::adjust_pop_for_rename(CDir *pdir, CDir *dir, utime_t now, bool
 
     if (pdir->is_subtree_root())
       adjust_subtree = false;
+    cur = pdir;
     pdir = pdir->inode->get_parent_dir();
     if (!pdir) break;
   }
index 3a72cc83f314d966aa0ae6126d79d010a3c2bcf0..60b3d9cb29f4c7d4cd7c13da55a925bcf74376aa 100644 (file)
@@ -943,10 +943,13 @@ void MDCache::try_subtree_merge_at(CDir *dir, set<CInode*> *to_eval, bool adjust
     // adjust popularity?
     if (adjust_pop && dir->is_auth()) {
       utime_t now = ceph_clock_now();
+      CDir *cur = dir;
       CDir *p = dir->get_parent_dir();
       while (p) {
        p->pop_auth_subtree.add(now, decayrate, dir->pop_auth_subtree);
+       p->pop_lru_subdirs.push_front(&cur->get_inode()->item_pop_lru);
        if (p->is_subtree_root()) break;
+       cur = p;
        p = p->inode->get_parent_dir();
       }
     }
index 1e2a3a302f6520269e53e09ddc7859e8aee4a87f..440a2aa73ffb4d487470ddf1d3dee1ac67836284 100644 (file)
@@ -3009,6 +3009,9 @@ void Migrator::decode_import_inode(CDentry *dn, bufferlist::iterator& blp,
     assert(!dn->get_linkage()->get_inode());
     dn->dir->link_primary_inode(dn, in);
   }
+
+  if (in->is_dir())
+    dn->dir->pop_lru_subdirs.push_back(&in->item_pop_lru);
  
   // add inode?
   if (added) {