disk_tp(external_messenger->cct, "OSD::disk_tp", g_conf->osd_disk_threads),
command_tp(external_messenger->cct, "OSD::command_tp", 1),
heartbeat_lock("OSD::heartbeat_lock"),
- heartbeat_stop(false), heartbeat_epoch(0),
+ heartbeat_stop(false), heartbeat_need_update(true), heartbeat_epoch(0),
hbin_messenger(hbinm),
hbout_messenger(hboutm),
heartbeat_thread(this),
}
}
-void OSD::update_heartbeat_peers()
+void OSD::need_heartbeat_peer_update()
{
- assert(osd_lock.is_locked());
heartbeat_lock.Lock();
+ dout(20) << "need_heartbeat_peer_update" << dendl;
+ heartbeat_need_update = true;
+ heartbeat_lock.Unlock();
+}
+
+void OSD::maybe_update_heartbeat_peers()
+{
+ assert(osd_lock.is_locked());
+ Mutex::Locker l(heartbeat_lock);
+
+ if (!heartbeat_need_update)
+ return;
+ heartbeat_need_update = false;
// filter heartbeat_from_stamp to only include osds that remain in
// heartbeat_from.
dout(10) << "update_heartbeat_peers: hb to: " << heartbeat_to << dendl;
dout(10) << "update_heartbeat_peers: hb from: " << heartbeat_from << dendl;
-
- heartbeat_lock.Unlock();
}
void OSD::reset_heartbeat_peers()
map_lock.get_read();
+ maybe_update_heartbeat_peers();
+
heartbeat_lock.Lock();
heartbeat_check();
heartbeat_lock.Unlock();
wake_all_pg_waiters(); // the pg mapping may have shifted
trim_map_cache(oldest_last_clean);
- update_heartbeat_peers();
+ maybe_update_heartbeat_peers();
send_pg_temp();
do_queries(query_map);
do_infos(info_map);
- if (num_created)
- update_heartbeat_peers();
+ maybe_update_heartbeat_peers();
+
op->put();
}
do_queries(query_map);
do_infos(info_map);
- if (created)
- update_heartbeat_peers();
+ maybe_update_heartbeat_peers();
op->put();
}
int tr = store->queue_transaction(&pg->osr, t, new ObjectStore::C_DeleteTransaction(t), fin);
assert(!tr);
- if (created)
- update_heartbeat_peers();
+ maybe_update_heartbeat_peers();
+
op->put();
}
}
do_infos(info_map);
- if (created)
- update_heartbeat_peers();
+
+ maybe_update_heartbeat_peers();
op->put();
}
_pro-cess_pg_info(m->get_epoch(), from, m->info, //misspelling added to prevent erroneous finds
empty_log, &m->missing, query_map, NULL, created);
do_queries(query_map);
- if (created)
- update_heartbeat_peers();
+
+ maybe_update_heartbeat_peers();
op->put();
#endif
// -- heartbeat --
Mutex heartbeat_lock;
Cond heartbeat_cond;
- bool heartbeat_stop;
+ bool heartbeat_stop, heartbeat_need_update;
epoch_t heartbeat_epoch;
map<int, epoch_t> heartbeat_to, heartbeat_from;
map<int, utime_t> heartbeat_from_stamp;
void _add_heartbeat_source(int p, map<int, epoch_t>& old_from, map<int, utime_t>& old_from_stamp,
map<int,Connection*>& old_con);
- void update_heartbeat_peers();
+ void maybe_update_heartbeat_peers();
void reset_heartbeat_peers();
void heartbeat();
void heartbeat_check();
void heartbeat_entry();
+ void need_heartbeat_peer_update();
struct T_Heartbeat : public Thread {
OSD *osd;
void PG::update_heartbeat_peers()
{
assert(is_locked());
- heartbeat_peer_lock.Lock();
- heartbeat_peers.clear();
+
+ set<int> new_peers;
if (role == 0) {
for (unsigned i=0; i<acting.size(); i++)
- heartbeat_peers.insert(acting[i]);
+ new_peers.insert(acting[i]);
for (unsigned i=0; i<up.size(); i++)
- heartbeat_peers.insert(up[i]);
+ new_peers.insert(up[i]);
for (map<int,pg_info_t>::iterator p = peer_info.begin(); p != peer_info.end(); ++p)
- heartbeat_peers.insert(p->first);
+ new_peers.insert(p->first);
+ }
+
+ bool need_update = false;
+ heartbeat_peer_lock.Lock();
+ if (new_peers == heartbeat_peers) {
+ dout(10) << "update_heartbeat_peers " << heartbeat_peers << " unchanged" << dendl;
+ } else {
+ dout(10) << "update_heartbeat_peers " << heartbeat_peers << " -> " << new_peers << dendl;
+ heartbeat_peers.swap(new_peers);
+ need_update = true;
}
- dout(10) << "update_heartbeat_peers " << heartbeat_peers << dendl;
heartbeat_peer_lock.Unlock();
+
+ if (need_update)
+ osd->need_heartbeat_peer_update();
}
void PG::update_stats()