]> git.proxmox.com Git - ceph.git/blame - ceph/src/seastar/src/core/fsqual.cc
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / seastar / src / core / fsqual.cc
CommitLineData
11fdf7f2
TL
1/*
2 * Copyright 2016 ScyllaDB
3 */
4/*
5 * This file is open source software, licensed to you under the terms
6 * of the Apache License, Version 2.0 (the "License"). See the NOTICE file
7 * distributed with this work for additional information regarding copyright
8 * ownership. You may not use this file except in compliance with the License.
9 *
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing,
15 * software distributed under the License is distributed on an
16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 * KIND, either express or implied. See the License for the
18 * specific language governing permissions and limitations
19 * under the License.
20 */
21
22#include <seastar/core/posix.hh>
23#include <seastar/util/defer.hh>
24#include <seastar/core/linux-aio.hh>
25#include <sys/time.h>
26#include <sys/resource.h>
27#include <fcntl.h>
28#include <iostream>
29#include <unistd.h>
30#include <cstdlib>
31#include <type_traits>
32#include <seastar/core/fsqual.hh>
33
34namespace seastar {
35
36using namespace seastar::internal;
37using namespace seastar::internal::linux_abi;
38
39// Runs func(), and also adds the number of context switches
40// that happened during func() to counter.
41template <typename Counter, typename Func>
20effc67 42typename std::invoke_result_t<Func>
11fdf7f2
TL
43with_ctxsw_counting(Counter& counter, Func&& func) {
44 struct count_guard {
45 Counter& counter;
46 count_guard(Counter& counter) : counter(counter) {
47 counter -= nvcsw();
48 }
49 ~count_guard() {
50 counter += nvcsw();
51 }
52 static Counter nvcsw() {
53 struct rusage usage;
54 getrusage(RUSAGE_THREAD, &usage);
55 return usage.ru_nvcsw;
56 }
57 };
58 count_guard g(counter);
59 return func();
60}
61
62bool filesystem_has_good_aio_support(sstring directory, bool verbose) {
63 aio_context_t ioctx = {};
64 auto r = io_setup(1, &ioctx);
65 throw_system_error_on(r == -1, "io_setup");
20effc67 66 auto cleanup = defer([&] () noexcept { io_destroy(ioctx); });
11fdf7f2
TL
67 auto fname = directory + "/fsqual.tmp";
68 auto fd = file_desc::open(fname, O_CREAT|O_EXCL|O_RDWR|O_DIRECT, 0600);
69 unlink(fname.c_str());
70 auto nr = 1000;
71 fd.truncate(nr * 4096);
72 auto bufsize = 4096;
73 auto ctxsw = 0;
74 auto buf = aligned_alloc(4096, 4096);
1e59de90 75 auto del = defer([&] () noexcept { ::free(buf); });
11fdf7f2
TL
76 for (int i = 0; i < nr; ++i) {
77 struct iocb cmd;
78 cmd = make_write_iocb(fd.get(), bufsize*i, buf, bufsize);
79 struct iocb* cmds[1] = { &cmd };
80 with_ctxsw_counting(ctxsw, [&] {
81 auto r = io_submit(ioctx, 1, cmds);
82 throw_system_error_on(r == -1, "io_submit");
83 assert(r == 1);
84 });
85 struct io_event ioev;
86 int n = -1;
87 do {
88 n = io_getevents(ioctx, 1, 1, &ioev, nullptr);
89 throw_system_error_on((n == -1) && (errno != EINTR) , "io_getevents");
90 } while (n == -1);
91 assert(n == 1);
92 throw_kernel_error(long(ioev.res));
93 assert(long(ioev.res) == bufsize);
94 }
95 auto rate = float(ctxsw) / nr;
96 bool ok = rate < 0.1;
97 if (verbose) {
98 auto verdict = ok ? "GOOD" : "BAD";
99 std::cout << "context switch per appending io: " << rate
100 << " (" << verdict << ")\n";
101 }
102 return ok;
103}
104
105}