1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
|
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab
/*
* Ceph - scalable distributed file system
*
* Copyright (C) 2019 Red Hat Inc.
*
* This is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1, as published by the Free Software
* Foundation. See file COPYING.
*
*/
#pragma once
#include <ostream>
#include <variant>
#include "common/ceph_context.h"
#include "common/OpQueue.h"
#include "mon/MonClient.h"
#include "osd/scheduler/OpSchedulerItem.h"
namespace ceph::osd::scheduler {
using client = uint64_t;
using WorkItem = std::variant<std::monostate, OpSchedulerItem, double>;
/**
* Base interface for classes responsible for choosing
* op processing order in the OSD.
*/
class OpScheduler {
public:
// Enqueue op for scheduling
virtual void enqueue(OpSchedulerItem &&item) = 0;
// Enqueue op for processing as though it were enqueued prior
// to other items already scheduled.
virtual void enqueue_front(OpSchedulerItem &&item) = 0;
// Returns true iff there are no ops scheduled
virtual bool empty() const = 0;
// Return next op to be processed
virtual WorkItem dequeue() = 0;
// Dump formatted representation for the queue
virtual void dump(ceph::Formatter &f) const = 0;
// Print human readable brief description with relevant parameters
virtual void print(std::ostream &out) const = 0;
// Apply config changes to the scheduler (if any)
virtual void update_configuration() = 0;
// Get the scheduler type set for the queue
virtual op_queue_type_t get_type() const = 0;
// Destructor
virtual ~OpScheduler() {};
};
std::ostream &operator<<(std::ostream &lhs, const OpScheduler &);
using OpSchedulerRef = std::unique_ptr<OpScheduler>;
OpSchedulerRef make_scheduler(
CephContext *cct, int whoami, uint32_t num_shards, int shard_id,
bool is_rotational, std::string_view osd_objectstore,
op_queue_type_t osd_scheduler, unsigned op_queue_cut_off, MonClient *monc);
/**
* Implements OpScheduler in terms of OpQueue
*
* Templated on queue type to avoid dynamic dispatch, T should implement
* OpQueue<OpSchedulerItem, client>. This adapter is mainly responsible for
* the boilerplate priority cutoff/strict concept which is needed for
* OpQueue based implementations.
*/
template <typename T>
class ClassedOpQueueScheduler final : public OpScheduler {
unsigned cutoff;
T queue;
public:
template <typename... Args>
ClassedOpQueueScheduler(CephContext *cct, unsigned prio_cut, Args&&... args) :
cutoff(prio_cut),
queue(std::forward<Args>(args)...)
{}
void enqueue(OpSchedulerItem &&item) final {
unsigned priority = item.get_priority();
unsigned cost = item.get_cost();
if (priority >= cutoff)
queue.enqueue_strict(
item.get_owner(), priority, std::move(item));
else
queue.enqueue(
item.get_owner(), priority, cost, std::move(item));
}
void enqueue_front(OpSchedulerItem &&item) final {
unsigned priority = item.get_priority();
unsigned cost = item.get_cost();
if (priority >= cutoff)
queue.enqueue_strict_front(
item.get_owner(),
priority, std::move(item));
else
queue.enqueue_front(
item.get_owner(),
priority, cost, std::move(item));
}
bool empty() const final {
return queue.empty();
}
WorkItem dequeue() final {
return queue.dequeue();
}
void dump(ceph::Formatter &f) const final {
return queue.dump(&f);
}
void print(std::ostream &out) const final {
out << "ClassedOpQueueScheduler(queue=";
queue.print(out);
out << ", cutoff=" << cutoff << ")";
}
void update_configuration() final {
// no-op
}
op_queue_type_t get_type() const final {
return queue.get_type();
}
~ClassedOpQueueScheduler() final {};
};
}
|