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