]>
git.proxmox.com Git - ceph.git/blob - ceph/src/seastar/src/core/fsqual.cc
2 * Copyright 2016 ScyllaDB
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.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
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
22 #include <seastar/core/posix.hh>
23 #include <seastar/util/defer.hh>
24 #include <seastar/core/linux-aio.hh>
26 #include <sys/resource.h>
31 #include <type_traits>
32 #include <seastar/core/fsqual.hh>
36 using namespace seastar::internal
;
37 using namespace seastar::internal::linux_abi
;
39 // Runs func(), and also adds the number of context switches
40 // that happened during func() to counter.
41 template <typename Counter
, typename Func
>
42 typename
std::invoke_result_t
<Func
>
43 with_ctxsw_counting(Counter
& counter
, Func
&& func
) {
46 count_guard(Counter
& counter
) : counter(counter
) {
52 static Counter
nvcsw() {
54 getrusage(RUSAGE_THREAD
, &usage
);
55 return usage
.ru_nvcsw
;
58 count_guard
g(counter
);
62 bool 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");
66 auto cleanup
= defer([&] () noexcept
{ io_destroy(ioctx
); });
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());
71 fd
.truncate(nr
* 4096);
74 auto buf
= aligned_alloc(4096, 4096);
75 auto del
= defer([&] () noexcept
{ ::free(buf
); });
76 for (int i
= 0; i
< nr
; ++i
) {
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");
88 n
= io_getevents(ioctx
, 1, 1, &ioev
, nullptr);
89 throw_system_error_on((n
== -1) && (errno
!= EINTR
) , "io_getevents");
92 throw_kernel_error(long(ioev
.res
));
93 assert(long(ioev
.res
) == bufsize
);
95 auto rate
= float(ctxsw
) / nr
;
98 auto verdict
= ok
? "GOOD" : "BAD";
99 std::cout
<< "context switch per appending io: " << rate
100 << " (" << verdict
<< ")\n";