blob: 9c96c4182d2ce6eed20aad49c35233b857ab9103 [file] [log] [blame]
Steven Morelandcda60852021-04-14 23:45:32 +00001/*
2 * Copyright (C) 2021 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <BnBinderRpcBenchmark.h>
18#include <android-base/logging.h>
19#include <benchmark/benchmark.h>
20#include <binder/Binder.h>
Steven Moreland1ebdc702021-07-28 18:46:15 -070021#include <binder/IPCThreadState.h>
22#include <binder/IServiceManager.h>
23#include <binder/ProcessState.h>
Yifan Hongaecdd172021-09-21 14:53:13 -070024#include <binder/RpcCertificateFormat.h>
25#include <binder/RpcCertificateVerifier.h>
Steven Morelandcda60852021-04-14 23:45:32 +000026#include <binder/RpcServer.h>
Steven Morelandbdb53ab2021-05-05 17:57:41 +000027#include <binder/RpcSession.h>
Yifan Honge0e53282021-09-23 18:37:21 -070028#include <binder/RpcTlsTestUtils.h>
Yifan Hongaecdd172021-09-21 14:53:13 -070029#include <binder/RpcTlsUtils.h>
30#include <binder/RpcTransportRaw.h>
31#include <binder/RpcTransportTls.h>
32#include <openssl/ssl.h>
Steven Morelandcda60852021-04-14 23:45:32 +000033
34#include <thread>
35
Steven Moreland656e9d12021-07-29 17:33:53 -070036#include <signal.h>
Steven Moreland1ebdc702021-07-28 18:46:15 -070037#include <sys/prctl.h>
Steven Morelandcda60852021-04-14 23:45:32 +000038#include <sys/types.h>
39#include <unistd.h>
40
41using android::BBinder;
Steven Moreland1ebdc702021-07-28 18:46:15 -070042using android::defaultServiceManager;
Steven Morelandcda60852021-04-14 23:45:32 +000043using android::IBinder;
44using android::interface_cast;
Steven Moreland1ebdc702021-07-28 18:46:15 -070045using android::IPCThreadState;
46using android::IServiceManager;
Steven Morelandcda60852021-04-14 23:45:32 +000047using android::OK;
Steven Moreland1ebdc702021-07-28 18:46:15 -070048using android::ProcessState;
Yifan Hongaecdd172021-09-21 14:53:13 -070049using android::RpcAuthPreSigned;
50using android::RpcCertificateFormat;
51using android::RpcCertificateVerifier;
Yifan Hong9809add2021-09-23 19:06:58 -070052using android::RpcCertificateVerifierNoOp;
Steven Morelandcda60852021-04-14 23:45:32 +000053using android::RpcServer;
Steven Morelandbdb53ab2021-05-05 17:57:41 +000054using android::RpcSession;
Yifan Hongaecdd172021-09-21 14:53:13 -070055using android::RpcTransportCtxFactory;
56using android::RpcTransportCtxFactoryRaw;
57using android::RpcTransportCtxFactoryTls;
Steven Morelandcda60852021-04-14 23:45:32 +000058using android::sp;
Steven Moreland2372f9d2021-08-05 15:42:01 -070059using android::status_t;
60using android::statusToString;
Steven Moreland1ebdc702021-07-28 18:46:15 -070061using android::String16;
Steven Morelandcda60852021-04-14 23:45:32 +000062using android::binder::Status;
63
64class MyBinderRpcBenchmark : public BnBinderRpcBenchmark {
65 Status repeatString(const std::string& str, std::string* out) override {
66 *out = str;
67 return Status::ok();
68 }
Steven Morelandce240ce2021-08-05 13:02:37 -070069 Status repeatBinder(const sp<IBinder>& binder, sp<IBinder>* out) override {
70 *out = binder;
71 return Status::ok();
72 }
73 Status repeatBytes(const std::vector<uint8_t>& bytes, std::vector<uint8_t>* out) override {
74 *out = bytes;
Steven Morelandcda60852021-04-14 23:45:32 +000075 return Status::ok();
76 }
77};
78
Steven Moreland1ebdc702021-07-28 18:46:15 -070079enum Transport {
80 KERNEL,
81 RPC,
Yifan Hongaecdd172021-09-21 14:53:13 -070082 RPC_TLS,
Steven Moreland1ebdc702021-07-28 18:46:15 -070083};
Steven Morelandcda60852021-04-14 23:45:32 +000084
Steven Morelandce240ce2021-08-05 13:02:37 -070085static const std::initializer_list<int64_t> kTransportList = {
Steven Moreland1ebdc702021-07-28 18:46:15 -070086#ifdef __BIONIC__
Steven Morelandce240ce2021-08-05 13:02:37 -070087 Transport::KERNEL,
Steven Moreland1ebdc702021-07-28 18:46:15 -070088#endif
Yifan Hongaecdd172021-09-21 14:53:13 -070089 Transport::RPC,
90 Transport::RPC_TLS,
91};
92
Yifan Hongaecdd172021-09-21 14:53:13 -070093std::unique_ptr<RpcTransportCtxFactory> makeFactoryTls() {
94 auto pkey = android::makeKeyPairForSelfSignedCert();
95 CHECK_NE(pkey.get(), nullptr);
96 auto cert = android::makeSelfSignedCert(pkey.get(), android::kCertValidSeconds);
97 CHECK_NE(cert.get(), nullptr);
98
Yifan Hongdc767652021-09-23 19:38:38 -070099 auto verifier = std::make_shared<RpcCertificateVerifierNoOp>(OK);
Yifan Hongaecdd172021-09-21 14:53:13 -0700100 auto auth = std::make_unique<RpcAuthPreSigned>(std::move(pkey), std::move(cert));
101 return RpcTransportCtxFactoryTls::make(verifier, std::move(auth));
102}
Steven Moreland1ebdc702021-07-28 18:46:15 -0700103
104static sp<RpcSession> gSession = RpcSession::make();
Steven Moreland67f85902023-03-15 01:13:49 +0000105static sp<IBinder> gRpcBinder;
Yifan Hong9809add2021-09-23 19:06:58 -0700106// Certificate validation happens during handshake and does not affect the result of benchmarks.
107// Skip certificate validation to simplify the setup process.
Yifan Hongaecdd172021-09-21 14:53:13 -0700108static sp<RpcSession> gSessionTls = RpcSession::make(makeFactoryTls());
Steven Moreland67f85902023-03-15 01:13:49 +0000109static sp<IBinder> gRpcTlsBinder;
Steven Moreland1ebdc702021-07-28 18:46:15 -0700110#ifdef __BIONIC__
111static const String16 kKernelBinderInstance = String16(u"binderRpcBenchmark-control");
112static sp<IBinder> gKernelBinder;
113#endif
114
115static sp<IBinder> getBinderForOptions(benchmark::State& state) {
116 Transport transport = static_cast<Transport>(state.range(0));
117 switch (transport) {
118#ifdef __BIONIC__
119 case KERNEL:
120 return gKernelBinder;
121#endif
122 case RPC:
Steven Moreland67f85902023-03-15 01:13:49 +0000123 return gRpcBinder;
Yifan Hongaecdd172021-09-21 14:53:13 -0700124 case RPC_TLS:
Steven Moreland67f85902023-03-15 01:13:49 +0000125 return gRpcTlsBinder;
Steven Moreland1ebdc702021-07-28 18:46:15 -0700126 default:
127 LOG(FATAL) << "Unknown transport value: " << transport;
128 return nullptr;
Steven Morelandcda60852021-04-14 23:45:32 +0000129 }
130}
Steven Morelandcda60852021-04-14 23:45:32 +0000131
Steven Moreland90b82892023-05-11 00:10:26 +0000132static void SetLabel(benchmark::State& state) {
133 Transport transport = static_cast<Transport>(state.range(0));
134 switch (transport) {
135#ifdef __BIONIC__
136 case KERNEL:
137 state.SetLabel("kernel");
138 break;
139#endif
140 case RPC:
141 state.SetLabel("rpc");
142 break;
143 case RPC_TLS:
144 state.SetLabel("rpc_tls");
145 break;
146 default:
147 LOG(FATAL) << "Unknown transport value: " << transport;
148 }
149}
150
Steven Morelandcda60852021-04-14 23:45:32 +0000151void BM_pingTransaction(benchmark::State& state) {
Steven Moreland1ebdc702021-07-28 18:46:15 -0700152 sp<IBinder> binder = getBinderForOptions(state);
Steven Morelandcda60852021-04-14 23:45:32 +0000153
154 while (state.KeepRunning()) {
155 CHECK_EQ(OK, binder->pingBinder());
156 }
Steven Moreland90b82892023-05-11 00:10:26 +0000157
158 SetLabel(state);
Steven Morelandcda60852021-04-14 23:45:32 +0000159}
Steven Morelandce240ce2021-08-05 13:02:37 -0700160BENCHMARK(BM_pingTransaction)->ArgsProduct({kTransportList});
Steven Morelandcda60852021-04-14 23:45:32 +0000161
Steven Morelandce240ce2021-08-05 13:02:37 -0700162void BM_repeatTwoPageString(benchmark::State& state) {
Steven Moreland1ebdc702021-07-28 18:46:15 -0700163 sp<IBinder> binder = getBinderForOptions(state);
164
Steven Morelandcda60852021-04-14 23:45:32 +0000165 sp<IBinderRpcBenchmark> iface = interface_cast<IBinderRpcBenchmark>(binder);
166 CHECK(iface != nullptr);
167
168 // Googlers might see go/another-look-at-aidl-hidl-perf
169 //
170 // When I checked in July 2019, 99.5% of AIDL transactions and 99.99% of HIDL
171 // transactions were less than one page in size (system wide during a test
172 // involving media and camera). This is why this diverges from
173 // binderThroughputTest and hwbinderThroughputTest. Future consideration - get
174 // this data on continuous integration. Here we are testing sending a
175 // transaction of twice this size. In other cases, we should focus on
176 // benchmarks of particular usecases. If individual binder transactions like
177 // the ones tested here are fast, then Android performance will be dominated
178 // by how many binder calls work together (and by factors like the scheduler,
179 // thermal throttling, core choice, etc..).
180 std::string str = std::string(getpagesize() * 2, 'a');
181 CHECK_EQ(str.size(), getpagesize() * 2);
182
183 while (state.KeepRunning()) {
184 std::string out;
185 Status ret = iface->repeatString(str, &out);
186 CHECK(ret.isOk()) << ret;
187 }
Steven Moreland90b82892023-05-11 00:10:26 +0000188
189 SetLabel(state);
Steven Morelandcda60852021-04-14 23:45:32 +0000190}
Steven Morelandce240ce2021-08-05 13:02:37 -0700191BENCHMARK(BM_repeatTwoPageString)->ArgsProduct({kTransportList});
192
193void BM_throughputForTransportAndBytes(benchmark::State& state) {
194 sp<IBinder> binder = getBinderForOptions(state);
195 sp<IBinderRpcBenchmark> iface = interface_cast<IBinderRpcBenchmark>(binder);
196 CHECK(iface != nullptr);
197
198 std::vector<uint8_t> bytes = std::vector<uint8_t>(state.range(1));
199 for (size_t i = 0; i < bytes.size(); i++) {
200 bytes[i] = i % 256;
201 }
202
203 while (state.KeepRunning()) {
204 std::vector<uint8_t> out;
205 Status ret = iface->repeatBytes(bytes, &out);
206 CHECK(ret.isOk()) << ret;
207 }
Steven Moreland90b82892023-05-11 00:10:26 +0000208
209 SetLabel(state);
Steven Morelandce240ce2021-08-05 13:02:37 -0700210}
211BENCHMARK(BM_throughputForTransportAndBytes)
212 ->ArgsProduct({kTransportList,
213 {64, 1024, 2048, 4096, 8182, 16364, 32728, 65535, 65536, 65537}});
Steven Morelandcda60852021-04-14 23:45:32 +0000214
215void BM_repeatBinder(benchmark::State& state) {
Steven Morelandb9c49622021-08-10 17:39:10 -0700216 sp<IBinder> binder = getBinderForOptions(state);
Steven Morelandcda60852021-04-14 23:45:32 +0000217 CHECK(binder != nullptr);
218 sp<IBinderRpcBenchmark> iface = interface_cast<IBinderRpcBenchmark>(binder);
219 CHECK(iface != nullptr);
220
221 while (state.KeepRunning()) {
222 // force creation of a new address
223 sp<IBinder> binder = sp<BBinder>::make();
224
225 sp<IBinder> out;
226 Status ret = iface->repeatBinder(binder, &out);
227 CHECK(ret.isOk()) << ret;
228 }
Steven Moreland90b82892023-05-11 00:10:26 +0000229
230 SetLabel(state);
Steven Morelandcda60852021-04-14 23:45:32 +0000231}
Steven Morelandce240ce2021-08-05 13:02:37 -0700232BENCHMARK(BM_repeatBinder)->ArgsProduct({kTransportList});
Steven Morelandcda60852021-04-14 23:45:32 +0000233
Yifan Hongaecdd172021-09-21 14:53:13 -0700234void forkRpcServer(const char* addr, const sp<RpcServer>& server) {
235 if (0 == fork()) {
236 prctl(PR_SET_PDEATHSIG, SIGHUP); // racey, okay
237 server->setRootObject(sp<MyBinderRpcBenchmark>::make());
Yifan Hongaecdd172021-09-21 14:53:13 -0700238 CHECK_EQ(OK, server->setupUnixDomainServer(addr));
239 server->join();
240 exit(1);
241 }
242}
243
244void setupClient(const sp<RpcSession>& session, const char* addr) {
245 status_t status;
246 for (size_t tries = 0; tries < 5; tries++) {
247 usleep(10000);
248 status = session->setupUnixDomainClient(addr);
249 if (status == OK) break;
250 }
251 CHECK_EQ(status, OK) << "Could not connect: " << addr << ": " << statusToString(status).c_str();
252}
253
Steven Morelandcda60852021-04-14 23:45:32 +0000254int main(int argc, char** argv) {
255 ::benchmark::Initialize(&argc, argv);
256 if (::benchmark::ReportUnrecognizedArguments(argc, argv)) return 1;
257
Steven Moreland1ebdc702021-07-28 18:46:15 -0700258#ifdef __BIONIC__
259 if (0 == fork()) {
260 prctl(PR_SET_PDEATHSIG, SIGHUP); // racey, okay
261 CHECK_EQ(OK,
262 defaultServiceManager()->addService(kKernelBinderInstance,
263 sp<MyBinderRpcBenchmark>::make()));
264 IPCThreadState::self()->joinThreadPool();
Steven Moreland656e9d12021-07-29 17:33:53 -0700265 exit(1);
Steven Moreland1ebdc702021-07-28 18:46:15 -0700266 }
267
268 ProcessState::self()->setThreadPoolMaxThreadCount(1);
269 ProcessState::self()->startThreadPool();
270
271 gKernelBinder = defaultServiceManager()->waitForService(kKernelBinderInstance);
272 CHECK_NE(nullptr, gKernelBinder.get());
273#endif
274
Yifan Hongaecdd172021-09-21 14:53:13 -0700275 std::string tmp = getenv("TMPDIR") ?: "/tmp";
276
277 std::string addr = tmp + "/binderRpcBenchmark";
278 (void)unlink(addr.c_str());
279 forkRpcServer(addr.c_str(), RpcServer::make(RpcTransportCtxFactoryRaw::make()));
280 setupClient(gSession, addr.c_str());
Steven Moreland67f85902023-03-15 01:13:49 +0000281 gRpcBinder = gSession->getRootObject();
Yifan Hongaecdd172021-09-21 14:53:13 -0700282
283 std::string tlsAddr = tmp + "/binderRpcTlsBenchmark";
284 (void)unlink(tlsAddr.c_str());
285 forkRpcServer(tlsAddr.c_str(), RpcServer::make(makeFactoryTls()));
286 setupClient(gSessionTls, tlsAddr.c_str());
Steven Moreland67f85902023-03-15 01:13:49 +0000287 gRpcTlsBinder = gSessionTls->getRootObject();
Steven Morelandcda60852021-04-14 23:45:32 +0000288
289 ::benchmark::RunSpecifiedBenchmarks();
Steven Moreland3ae982a2021-05-05 18:16:11 +0000290 return 0;
Steven Morelandcda60852021-04-14 23:45:32 +0000291}