]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
client: use vectors for context lists 59171/head
authorPatrick Donnelly <pdonnell@redhat.com>
Mon, 12 Aug 2024 15:31:46 +0000 (11:31 -0400)
committerPatrick Donnelly <pdonnell@redhat.com>
Mon, 12 Aug 2024 16:00:23 +0000 (12:00 -0400)
To avoid an allocation for each Context and improved cache locality.

Signed-off-by: Patrick Donnelly <pdonnell@redhat.com>
src/client/Client.cc
src/client/Client.h
src/client/Inode.h
src/client/MetaRequest.h
src/client/MetaSession.h

index 5f78e73f922249a550c395c7fe62df32f985a868..e60b9345e24ae077955b2530156d965683ff795c 100644 (file)
@@ -4265,7 +4265,7 @@ void Client::signal_cond_list(list<ceph::condition_variable*>& ls)
   }
 }
 
-void Client::wait_on_context_list(list<Context*>& ls)
+void Client::wait_on_context_list(std::vector<Context*>& ls)
 {
   ceph::condition_variable cond;
   bool done = false;
@@ -4276,30 +4276,14 @@ void Client::wait_on_context_list(list<Context*>& ls)
   l.release();
 }
 
-void Client::signal_context_list(list<Context*>& ls)
-{
-  while (!ls.empty()) {
-    ls.front()->complete(0);
-    ls.pop_front();
-  }
-}
-
 void Client::signal_caps_inode(Inode *in)
 {
   // Process the waitfor_caps list
-  while (!in->waitfor_caps.empty()) {
-    in->waitfor_caps.front()->complete(0);
-    in->waitfor_caps.pop_front();
-  }
+  signal_context_list(in->waitfor_caps);
 
   // New items may have been added to the pending list, move them onto the
   // waitfor_caps list
-  while (!in->waitfor_caps_pending.empty()) {
-    Context *ctx = in->waitfor_caps_pending.front();
-
-    in->waitfor_caps_pending.pop_front();
-    in->waitfor_caps.push_back(ctx);
-  }
+  std::swap(in->waitfor_caps, in->waitfor_caps_pending);
 }
 
 void Client::wake_up_session_caps(MetaSession *s, bool reconnect)
@@ -11904,7 +11888,7 @@ void Client::C_nonblocking_fsync_state::advance()
       ldout(clnt->cct, 15) << "waiting on unsafe requests, last tid " << req->get_tid() <<  dendl;
 
       req->get();
-      clnt->add_nonblocking_onfinish_to_context_list(req->waitfor_safe, advancer);
+      req->waitfor_safe.push_back(advancer);
       // ------------  here is a state machine break point
       return;
     }
@@ -11930,7 +11914,7 @@ void Client::C_nonblocking_fsync_state::advance()
         ldout(clnt->cct, 10) << "ino " << in->ino << " has " << in->cap_refs[CEPH_CAP_FILE_BUFFER]
                              << " uncommitted, waiting" << dendl;
         advancer = new C_nonblocking_fsync_state_advancer(clnt, this);
-        clnt->add_nonblocking_onfinish_to_context_list(in->waitfor_commit, advancer);
+        in->waitfor_commit.push_back(advancer);
         // ------------  here is a state machine break point but we have to
         //               return to this case because this might loop.
         progress = 1;
@@ -11988,9 +11972,9 @@ void Client::C_nonblocking_fsync_state::advance()
                              << " for C_nonblocking_fsync_state " << this
                              << dendl;
         if (progress == 3)
-          clnt->add_nonblocking_onfinish_to_context_list(in->waitfor_caps, advancer);
+          in->waitfor_caps.push_back(advancer);
         else
-          clnt->add_nonblocking_onfinish_to_context_list(in->waitfor_caps_pending, advancer);
+          in->waitfor_caps_pending.push_back(advancer);
         // ------------  here is a state machine break point
         //               the advancer completion will resume with case 3
         progress = 4;
@@ -16796,7 +16780,7 @@ void Client::ms_handle_remote_reset(Connection *con)
        case MetaSession::STATE_OPENING:
          {
            ldout(cct, 1) << "reset from mds we were opening; retrying" << dendl;
-           list<Context*> waiters;
+           std::vector<Context*> waiters;
            waiters.swap(s->waiting_for_open);
            _closed_mds_session(s.get());
            auto news = _get_or_open_mds_session(mds);
index 658ecd4726fb684e2fb6276c56920088423195f7..5a1e69394d02a9f6abf52af0bd5184ccdce8c1e6 100644 (file)
@@ -1057,11 +1057,10 @@ protected:
   // helpers
   void wake_up_session_caps(MetaSession *s, bool reconnect);
 
-  void add_nonblocking_onfinish_to_context_list(std::list<Context*>& ls, Context *onfinish) {
-    ls.push_back(onfinish);
+  void wait_on_context_list(std::vector<Context*>& ls);
+  void signal_context_list(std::vector<Context*>& ls) {
+    finish_contexts(cct, ls, 0);
   }
-  void wait_on_context_list(std::list<Context*>& ls);
-  void signal_context_list(std::list<Context*>& ls);
   void signal_caps_inode(Inode *in);
 
   // -- metadata cache stuff
index 6392619335ceb2d6df1ad9e519f7ed482a96ff9a..61188bd2f44793a47b1b3b61d8909e26e6c7f43a 100644 (file)
@@ -238,9 +238,9 @@ struct Inode : RefCountedObject {
   std::map<frag_t,int> fragmap;  // known frag -> mds mappings
   std::map<frag_t, std::vector<mds_rank_t>> frag_repmap; // non-auth mds mappings
 
-  std::list<Context*> waitfor_caps;
-  std::list<Context*> waitfor_caps_pending;
-  std::list<Context*> waitfor_commit;
+  std::vector<Context*> waitfor_caps;
+  std::vector<Context*> waitfor_caps_pending;
+  std::vector<Context*> waitfor_commit;
   std::list<ceph::condition_variable*> waitfor_deleg;
 
   Dentry *get_first_parent() {
index 240c0cd02a39578abdcee6dfc8c6619041d9550f..1b447050800ce3d4514d71c85d09a2e37c8aa01d 100644 (file)
@@ -70,7 +70,7 @@ public:
 
   ceph::condition_variable *caller_cond = NULL;   // who to take up
   ceph::condition_variable *dispatch_cond = NULL; // who to kick back
-  std::list<Context*> waitfor_safe;
+  std::vector<Context*> waitfor_safe;
 
   InodeRef target;
   UserPerm perms;
index 301306263e66ee7093e8279f2563ed4cb588b601..058272de053ee7047cf9cfa3a9233dedb02a7deb 100644 (file)
@@ -47,7 +47,7 @@ struct MetaSession {
   int mds_state = MDSMap::STATE_NULL;
   bool readonly = false;
 
-  std::list<Context*> waiting_for_open;
+  std::vector<Context*> waiting_for_open;
 
   xlist<Cap*> caps;
   // dirty_list keeps all the dirty inodes before flushing in current session.