1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 * Ceph - scalable distributed file system
6 * Copyright (C) 2016 Red Hat Inc.
8 * This is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License version 2.1, as published by the Free Software
11 * Foundation. See file COPYING.
22 #include "boost/variant.hpp"
24 #include "dmclock/src/dmclock_server.h"
26 #include "osd/scheduler/OpScheduler.h"
27 #include "common/config.h"
28 #include "include/cmp.h"
29 #include "common/ceph_context.h"
30 #include "common/mClockPriorityQueue.h"
31 #include "osd/scheduler/OpSchedulerItem.h"
34 namespace ceph::osd::scheduler
{
36 using client_id_t
= uint64_t;
37 using profile_id_t
= uint64_t;
39 struct client_profile_id_t
{
40 client_id_t client_id
;
41 profile_id_t profile_id
;
44 WRITE_EQ_OPERATORS_2(client_profile_id_t
, client_id
, profile_id
)
45 WRITE_CMP_OPERATORS_2(client_profile_id_t
, client_id
, profile_id
)
48 struct scheduler_id_t
{
49 op_scheduler_class class_id
;
50 client_profile_id_t client_profile_id
;
53 WRITE_EQ_OPERATORS_2(scheduler_id_t
, class_id
, client_profile_id
)
54 WRITE_CMP_OPERATORS_2(scheduler_id_t
, class_id
, client_profile_id
)
57 * Scheduler implementation based on mclock.
59 * TODO: explain configs
61 class mClockScheduler
: public OpScheduler
, md_config_obs_t
{
63 class ClientRegistry
{
65 crimson::dmclock::ClientInfo
,
66 static_cast<size_t>(op_scheduler_class::immediate
)
67 > internal_client_infos
= {
68 // Placeholder, gets replaced with configured values
69 crimson::dmclock::ClientInfo(1, 1, 1),
70 crimson::dmclock::ClientInfo(1, 1, 1)
73 crimson::dmclock::ClientInfo default_external_client_info
= {1, 1, 1};
74 std::map
<client_profile_id_t
,
75 crimson::dmclock::ClientInfo
> external_client_infos
;
76 const crimson::dmclock::ClientInfo
*get_external_client(
77 const client_profile_id_t
&client
) const;
79 void update_from_config(const ConfigProxy
&conf
);
80 const crimson::dmclock::ClientInfo
*get_info(
81 const scheduler_id_t
&id
) const;
84 using mclock_queue_t
= crimson::dmclock::PullPriorityQueue
<
90 mclock_queue_t scheduler
;
91 std::list
<OpSchedulerItem
> immediate
;
93 static scheduler_id_t
get_scheduler_id(const OpSchedulerItem
&item
) {
94 return scheduler_id_t
{
95 item
.get_scheduler_class(),
104 mClockScheduler(CephContext
*cct
);
106 // Enqueue op in the back of the regular queue
107 void enqueue(OpSchedulerItem
&&item
) final
;
109 // Enqueue the op in the front of the regular queue
110 void enqueue_front(OpSchedulerItem
&&item
) final
;
112 // Return an op to be dispatch
113 OpSchedulerItem
dequeue() final
;
115 // Returns if the queue is empty
116 bool empty() const final
{
117 return immediate
.empty() && scheduler
.empty();
120 // Formatted output of the queue
121 void dump(ceph::Formatter
&f
) const final
;
123 void print(std::ostream
&ostream
) const final
{
124 ostream
<< "mClockScheduler";
127 const char** get_tracked_conf_keys() const final
;
128 void handle_conf_change(const ConfigProxy
& conf
,
129 const std::set
<std::string
> &changed
) final
;