]>
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 mClockClientQueue : 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 InnerClient = std::pair<entity_inst_t,osd_op_type_t>; | |
45 | ||
46 | using queue_t = mClockQueue<Request, InnerClient>; | |
47 | ||
48 | queue_t queue; | |
49 | ||
50 | struct mclock_op_tags_t { | |
51 | crimson::dmclock::ClientInfo client_op; | |
52 | crimson::dmclock::ClientInfo osd_subop; | |
53 | crimson::dmclock::ClientInfo snaptrim; | |
54 | crimson::dmclock::ClientInfo recov; | |
55 | crimson::dmclock::ClientInfo scrub; | |
56 | ||
57 | mclock_op_tags_t(CephContext *cct); | |
58 | }; | |
59 | ||
60 | static std::unique_ptr<mclock_op_tags_t> mclock_op_tags; | |
61 | ||
62 | public: | |
63 | ||
64 | mClockClientQueue(CephContext *cct); | |
65 | ||
66 | static crimson::dmclock::ClientInfo | |
67 | op_class_client_info_f(const InnerClient& client); | |
68 | ||
69 | inline unsigned length() const override final { | |
70 | return queue.length(); | |
71 | } | |
72 | ||
73 | // Ops of this priority should be deleted immediately | |
74 | inline void remove_by_class(Client cl, | |
75 | std::list<Request> *out) override final { | |
76 | queue.remove_by_filter( | |
77 | [&cl, out] (const Request& r) -> bool { | |
78 | if (cl == r.second.get_owner()) { | |
79 | out->push_front(r); | |
80 | return true; | |
81 | } else { | |
82 | return false; | |
83 | } | |
84 | }); | |
85 | } | |
86 | ||
87 | void enqueue_strict(Client cl, | |
88 | unsigned priority, | |
89 | Request item) override final; | |
90 | ||
91 | // Enqueue op in the front of the strict queue | |
92 | void enqueue_strict_front(Client cl, | |
93 | unsigned priority, | |
94 | Request item) override final; | |
95 | ||
96 | // Enqueue op in the back of the regular queue | |
97 | void enqueue(Client cl, | |
98 | unsigned priority, | |
99 | unsigned cost, | |
100 | Request item) override final; | |
101 | ||
102 | // Enqueue the op in the front of the regular queue | |
103 | void enqueue_front(Client cl, | |
104 | unsigned priority, | |
105 | unsigned cost, | |
106 | Request item) override final; | |
107 | ||
108 | // Return an op to be dispatch | |
109 | Request dequeue() override final; | |
110 | ||
111 | // Returns if the queue is empty | |
112 | inline bool empty() const override final { | |
113 | return queue.empty(); | |
114 | } | |
115 | ||
116 | // Formatted output of the queue | |
117 | void dump(ceph::Formatter *f) const override final; | |
118 | ||
119 | protected: | |
120 | ||
121 | struct pg_queueable_visitor_t : public boost::static_visitor<osd_op_type_t> { | |
122 | osd_op_type_t operator()(const OpRequestRef& o) const { | |
123 | // don't know if it's a client_op or a | |
124 | return osd_op_type_t::client_op; | |
125 | } | |
126 | ||
127 | osd_op_type_t operator()(const PGSnapTrim& o) const { | |
128 | return osd_op_type_t::bg_snaptrim; | |
129 | } | |
130 | ||
131 | osd_op_type_t operator()(const PGScrub& o) const { | |
132 | return osd_op_type_t::bg_scrub; | |
133 | } | |
134 | ||
135 | osd_op_type_t operator()(const PGRecovery& o) const { | |
136 | return osd_op_type_t::bg_recovery; | |
137 | } | |
138 | }; // class pg_queueable_visitor_t | |
139 | ||
140 | static pg_queueable_visitor_t pg_queueable_visitor; | |
141 | ||
142 | osd_op_type_t get_osd_op_type(const Request& request); | |
143 | InnerClient get_inner_client(const Client& cl, const Request& request); | |
144 | }; // class mClockClientAdapter | |
145 | ||
146 | } // namespace ceph |