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