]> git.proxmox.com Git - ceph.git/blame - ceph/src/os/filestore/WBThrottle.h
buildsys: change download over to reef release
[ceph.git] / ceph / src / os / filestore / WBThrottle.h
CommitLineData
7c673cae
FG
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) 2013 Inktank Storage, 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#ifndef WBTHROTTLE_H
16#define WBTHROTTLE_H
17
18#include "include/unordered_map.h"
19#include <boost/tuple/tuple.hpp>
7c673cae
FG
20#include "common/Formatter.h"
21#include "common/hobject.h"
22#include "include/interval_set.h"
9f95a23c 23#include "include/common_fwd.h"
7c673cae
FG
24#include "FDCache.h"
25#include "common/Thread.h"
26#include "common/ceph_context.h"
27
7c673cae
FG
28enum {
29 l_wbthrottle_first = 999090,
30 l_wbthrottle_bytes_dirtied,
31 l_wbthrottle_bytes_wb,
32 l_wbthrottle_ios_dirtied,
33 l_wbthrottle_ios_wb,
34 l_wbthrottle_inodes_dirtied,
35 l_wbthrottle_inodes_wb,
36 l_wbthrottle_last
37};
38
39/**
40 * WBThrottle
41 *
42 * Tracks, throttles, and flushes outstanding IO
43 */
44class WBThrottle : Thread, public md_config_obs_t {
45 ghobject_t clearing;
46 /* *_limits.first is the start_flusher limit and
47 * *_limits.second is the hard limit
48 */
49
50 /// Limits on unflushed bytes
f67539c2 51 std::pair<uint64_t, uint64_t> size_limits;
7c673cae
FG
52
53 /// Limits on unflushed ios
f67539c2 54 std::pair<uint64_t, uint64_t> io_limits;
7c673cae
FG
55
56 /// Limits on unflushed objects
f67539c2 57 std::pair<uint64_t, uint64_t> fd_limits;
7c673cae
FG
58
59 uint64_t cur_ios; /// Currently unflushed IOs
60 uint64_t cur_size; /// Currently unflushed bytes
61
62 /**
63 * PendingWB tracks the ios pending on an object.
64 */
65 class PendingWB {
66 public:
67 bool nocache;
68 uint64_t size;
69 uint64_t ios;
70 PendingWB() : nocache(true), size(0), ios(0) {}
71 void add(bool _nocache, uint64_t _size, uint64_t _ios) {
72 if (!_nocache)
73 nocache = false; // only nocache if all writes are nocache
74 size += _size;
75 ios += _ios;
76 }
77 };
78
79 CephContext *cct;
80 PerfCounters *logger;
81 bool stopping;
9f95a23c
TL
82 ceph::mutex lock = ceph::make_mutex("WBThrottle::lock");
83 ceph::condition_variable cond;
7c673cae
FG
84
85
86 /**
87 * Flush objects in lru order
88 */
f67539c2
TL
89 std::list<ghobject_t> lru;
90 ceph::unordered_map<ghobject_t, std::list<ghobject_t>::iterator> rev_lru;
7c673cae 91 void remove_object(const ghobject_t &oid) {
9f95a23c 92 ceph_assert(ceph_mutex_is_locked(lock));
f67539c2 93 ceph::unordered_map<ghobject_t, std::list<ghobject_t>::iterator>::iterator iter =
7c673cae
FG
94 rev_lru.find(oid);
95 if (iter == rev_lru.end())
96 return;
97
98 lru.erase(iter->second);
99 rev_lru.erase(iter);
100 }
101 ghobject_t pop_object() {
11fdf7f2 102 ceph_assert(!lru.empty());
7c673cae
FG
103 ghobject_t oid(lru.front());
104 lru.pop_front();
105 rev_lru.erase(oid);
106 return oid;
107 }
108 void insert_object(const ghobject_t &oid) {
11fdf7f2 109 ceph_assert(rev_lru.find(oid) == rev_lru.end());
7c673cae
FG
110 lru.push_back(oid);
111 rev_lru.insert(make_pair(oid, --lru.end()));
112 }
113
f67539c2 114 ceph::unordered_map<ghobject_t, std::pair<PendingWB, FDRef> > pending_wbs;
7c673cae
FG
115
116 /// get next flush to perform
117 bool get_next_should_flush(
9f95a23c 118 std::unique_lock<ceph::mutex>& locker,
7c673cae
FG
119 boost::tuple<ghobject_t, FDRef, PendingWB> *next ///< [out] next to flush
120 ); ///< @return false if we are shutting down
121public:
122 enum FS {
123 BTRFS,
124 XFS
125 };
126
127private:
128 FS fs;
129
130 void set_from_conf();
131 bool beyond_limit() const {
132 if (cur_ios < io_limits.first &&
133 pending_wbs.size() < fd_limits.first &&
134 cur_size < size_limits.first)
135 return false;
136 else
137 return true;
138 }
139 bool need_flush() const {
140 if (cur_ios < io_limits.second &&
141 pending_wbs.size() < fd_limits.second &&
142 cur_size < size_limits.second)
143 return false;
144 else
145 return true;
146 }
147
148public:
149 explicit WBThrottle(CephContext *cct);
150 ~WBThrottle() override;
151
152 void start();
153 void stop();
154 /// Set fs as XFS or BTRFS
155 void set_fs(FS new_fs) {
9f95a23c 156 std::lock_guard l{lock};
7c673cae
FG
157 fs = new_fs;
158 set_from_conf();
159 }
160
161 /// Queue wb on oid, fd taking throttle (does not block)
162 void queue_wb(
163 FDRef fd, ///< [in] FDRef to oid
164 const ghobject_t &oid, ///< [in] object
165 uint64_t offset, ///< [in] offset written
166 uint64_t len, ///< [in] length written
167 bool nocache ///< [in] try to clear out of cache after write
168 );
169
170 /// Clear all wb (probably due to sync)
171 void clear();
172
173 /// Clear object
174 void clear_object(const ghobject_t &oid);
175
176 /// Block until there is throttle available
177 void throttle();
178
179 /// md_config_obs_t
180 const char** get_tracked_conf_keys() const override;
11fdf7f2 181 void handle_conf_change(const ConfigProxy& conf,
7c673cae
FG
182 const std::set<std::string> &changed) override;
183
184 /// Thread
185 void *entry() override;
186};
187
188#endif