]>
Commit | Line | Data |
---|---|---|
224ce89b WB |
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) 2016 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 | ||
16 | #pragma once | |
17 | ||
18 | #include <ostream> | |
19 | ||
20 | #include "boost/variant.hpp" | |
21 | ||
22 | #include "common/config.h" | |
23 | #include "common/ceph_context.h" | |
24 | #include "osd/PGQueueable.h" | |
25 | ||
26 | #include "common/mClockPriorityQueue.h" | |
27 | ||
28 | ||
29 | namespace ceph { | |
30 | ||
31 | using Request = std::pair<spg_t, PGQueueable>; | |
32 | using Client = entity_inst_t; | |
33 | ||
34 | ||
35 | // This class exists to bridge the ceph code, which treats the class | |
36 | // as the client, and the queue, where the class is | |
37 | // osd_op_type_t. So this adpater class will transform calls | |
38 | // appropriately. | |
39 | class mClockOpClassQueue : public OpQueue<Request, Client> { | |
40 | ||
41 | enum class osd_op_type_t { | |
42 | client_op, osd_subop, bg_snaptrim, bg_recovery, bg_scrub }; | |
43 | ||
44 | using queue_t = mClockQueue<Request, osd_op_type_t>; | |
45 | ||
46 | queue_t queue; | |
47 | ||
48 | struct mclock_op_tags_t { | |
49 | crimson::dmclock::ClientInfo client_op; | |
50 | crimson::dmclock::ClientInfo osd_subop; | |
51 | crimson::dmclock::ClientInfo snaptrim; | |
52 | crimson::dmclock::ClientInfo recov; | |
53 | crimson::dmclock::ClientInfo scrub; | |
54 | ||
55 | mclock_op_tags_t(CephContext *cct); | |
56 | }; | |
57 | ||
58 | static std::unique_ptr<mclock_op_tags_t> mclock_op_tags; | |
59 | ||
60 | public: | |
61 | ||
62 | mClockOpClassQueue(CephContext *cct); | |
63 | ||
64 | static crimson::dmclock::ClientInfo | |
65 | op_class_client_info_f(const osd_op_type_t& op_type); | |
66 | ||
67 | inline unsigned length() const override final { | |
68 | return queue.length(); | |
69 | } | |
70 | ||
71 | // Ops of this priority should be deleted immediately | |
72 | inline void remove_by_class(Client cl, | |
73 | std::list<Request> *out) override final { | |
74 | queue.remove_by_filter( | |
75 | [&cl, out] (const Request& r) -> bool { | |
76 | if (cl == r.second.get_owner()) { | |
77 | out->push_front(r); | |
78 | return true; | |
79 | } else { | |
80 | return false; | |
81 | } | |
82 | }); | |
83 | } | |
84 | ||
85 | inline void enqueue_strict(Client cl, | |
86 | unsigned priority, | |
87 | Request item) override final { | |
88 | queue.enqueue_strict(get_osd_op_type(item), priority, item); | |
89 | } | |
90 | ||
91 | // Enqueue op in the front of the strict queue | |
92 | inline void enqueue_strict_front(Client cl, | |
93 | unsigned priority, | |
94 | Request item) override final { | |
95 | queue.enqueue_strict_front(get_osd_op_type(item), priority, item); | |
96 | } | |
97 | ||
98 | // Enqueue op in the back of the regular queue | |
99 | inline void enqueue(Client cl, | |
100 | unsigned priority, | |
101 | unsigned cost, | |
102 | Request item) override final { | |
103 | queue.enqueue(get_osd_op_type(item), priority, cost, item); | |
104 | } | |
105 | ||
106 | // Enqueue the op in the front of the regular queue | |
107 | inline void enqueue_front(Client cl, | |
108 | unsigned priority, | |
109 | unsigned cost, | |
110 | Request item) override final { | |
111 | queue.enqueue_front(get_osd_op_type(item), priority, cost, item); | |
112 | } | |
113 | ||
114 | // Returns if the queue is empty | |
115 | inline bool empty() const override final { | |
116 | return queue.empty(); | |
117 | } | |
118 | ||
119 | // Return an op to be dispatch | |
120 | inline Request dequeue() override final { | |
121 | return queue.dequeue(); | |
122 | } | |
123 | ||
124 | // Formatted output of the queue | |
125 | void dump(ceph::Formatter *f) const override final; | |
126 | ||
127 | protected: | |
128 | ||
129 | struct pg_queueable_visitor_t : public boost::static_visitor<osd_op_type_t> { | |
130 | osd_op_type_t operator()(const OpRequestRef& o) const { | |
131 | // don't know if it's a client_op or a | |
132 | return osd_op_type_t::client_op; | |
133 | } | |
134 | ||
135 | osd_op_type_t operator()(const PGSnapTrim& o) const { | |
136 | return osd_op_type_t::bg_snaptrim; | |
137 | } | |
138 | ||
139 | osd_op_type_t operator()(const PGScrub& o) const { | |
140 | return osd_op_type_t::bg_scrub; | |
141 | } | |
142 | ||
143 | osd_op_type_t operator()(const PGRecovery& o) const { | |
144 | return osd_op_type_t::bg_recovery; | |
145 | } | |
146 | }; // class pg_queueable_visitor_t | |
147 | ||
148 | static pg_queueable_visitor_t pg_queueable_visitor; | |
149 | ||
150 | osd_op_type_t get_osd_op_type(const Request& request); | |
151 | }; // class mClockOpClassAdapter | |
152 | ||
153 | } // namespace ceph |