#include "crimson/osd/scheduler/scheduler.h"
#include "crimson/osd/scheduler/mclock_scheduler.h"
#include "common/WeightedPriorityQueue.h"
+#include "common/mclock_common.h"
namespace crimson::osd::scheduler {
-std::ostream &operator<<(std::ostream &lhs, const scheduler_class_t &c)
-{
- switch (c) {
- case scheduler_class_t::background_best_effort:
- return lhs << "background_best_effort";
- case scheduler_class_t::background_recovery:
- return lhs << "background_recovery";
- case scheduler_class_t::client:
- return lhs << "client";
- case scheduler_class_t::repop:
- return lhs << "repop";
- case scheduler_class_t::immediate:
- return lhs << "immediate";
- default:
- return lhs;
- }
-}
-
/**
* Implements Scheduler in terms of OpQueue
*
*/
template <typename T>
class ClassedOpQueueScheduler final : public Scheduler {
- const scheduler_class_t cutoff;
+ const SchedulerClass cutoff;
T queue;
using priority_t = uint64_t;
std::array<
priority_t,
- static_cast<size_t>(scheduler_class_t::immediate)
+ static_cast<size_t>(SchedulerClass::immediate)
> priority_map = {
// Placeholder, gets replaced with configured values
0, 0, 0
};
- static scheduler_class_t get_io_prio_cut(ConfigProxy &conf) {
+ static SchedulerClass get_io_prio_cut(ConfigProxy &conf) {
if (conf.get_val<std::string>("osd_op_queue_cut_off") == "debug_random") {
srand(time(NULL));
return (rand() % 2 < 1) ?
- scheduler_class_t::repop : scheduler_class_t::immediate;
+ SchedulerClass::repop : SchedulerClass::immediate;
} else if (conf.get_val<std::string>("osd_op_queue_cut_off") == "high") {
- return scheduler_class_t::immediate;
+ return SchedulerClass::immediate;
} else {
- return scheduler_class_t::repop;
+ return SchedulerClass::repop;
}
}
- bool use_strict(scheduler_class_t kl) const {
+ bool use_strict(SchedulerClass kl) const {
return static_cast<uint8_t>(kl) >= static_cast<uint8_t>(cutoff);
}
- priority_t get_priority(scheduler_class_t kl) const {
+ priority_t get_priority(SchedulerClass kl) const {
ceph_assert(static_cast<size_t>(kl) <
- static_cast<size_t>(scheduler_class_t::immediate));
+ static_cast<size_t>(SchedulerClass::immediate));
return priority_map[static_cast<size_t>(kl)];
}
queue(std::forward<Args>(args)...)
{
priority_map[
- static_cast<size_t>(scheduler_class_t::background_best_effort)
+ static_cast<size_t>(SchedulerClass::background_best_effort)
] = conf.get_val<uint64_t>("osd_scrub_priority");
priority_map[
- static_cast<size_t>(scheduler_class_t::background_recovery)
+ static_cast<size_t>(SchedulerClass::background_recovery)
] = conf.get_val<uint64_t>("osd_recovery_op_priority");
priority_map[
- static_cast<size_t>(scheduler_class_t::client)
+ static_cast<size_t>(SchedulerClass::client)
] = conf.get_val<uint64_t>("osd_client_op_priority");
priority_map[
- static_cast<size_t>(scheduler_class_t::repop)
+ static_cast<size_t>(SchedulerClass::repop)
] = conf.get_val<uint64_t>("osd_client_op_priority");
}
return queue.empty();
}
- item_t dequeue() final {
+ WorkItem dequeue() final {
return queue.dequeue();
}
~ClassedOpQueueScheduler() final {};
};
-SchedulerRef make_scheduler(ConfigProxy &conf)
+SchedulerRef make_scheduler(CephContext *cct, ConfigProxy &conf, int whoami, uint32_t nshards, int sid,
+ bool is_rotational, bool perf_cnt)
{
const std::string _type = conf.get_val<std::string>("osd_op_queue");
const std::string *type = &_type;
conf->osd_op_pq_min_cost
);
} else if (*type == "mclock_scheduler") {
- return std::make_unique<mClockScheduler>(conf);
+ return std::make_unique<mClockScheduler>(cct, whoami, nshards, sid, is_rotational, perf_cnt);
} else {
ceph_assert("Invalid choice of wq" == 0);
return std::unique_ptr<mClockScheduler>();
#include <ostream>
#include "crimson/common/config_proxy.h"
+#include "common/mclock_common.h"
namespace crimson::osd::scheduler {
-enum class scheduler_class_t : uint8_t {
- background_best_effort = 0,
- background_recovery,
- client,
- repop,
- immediate,
-};
-
-std::ostream &operator<<(std::ostream &, const scheduler_class_t &);
-
using client_t = uint64_t;
-using cost_t = uint64_t;
struct params_t {
- cost_t cost = 1;
+ int cost = 1;
+ unsigned priority = 0;
client_t owner;
- scheduler_class_t klass;
+ SchedulerClass klass;
};
struct item_t {
params_t params;
seastar::promise<> wake;
+ int get_cost() const { return params.cost; }
+ unsigned get_priority() const { return params.priority; }
};
+using WorkItem = std::variant<std::monostate, item_t, double>;
/**
* Base interface for classes responsible for choosing
* op processing order in the OSD.
virtual bool empty() const = 0;
// Return next op to be processed
- virtual item_t dequeue() = 0;
+ virtual WorkItem dequeue() = 0;
// Dump formatted representation for the queue
virtual void dump(ceph::Formatter &f) const = 0;
std::ostream &operator<<(std::ostream &lhs, const Scheduler &);
using SchedulerRef = std::unique_ptr<Scheduler>;
-SchedulerRef make_scheduler(ConfigProxy &);
+SchedulerRef make_scheduler(CephContext *cct, ConfigProxy &, int whoami, uint32_t num_shards,
+ int shard_id, bool is_rotational, bool perf_cnt);
}