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