aboutsummaryrefslogtreecommitdiff
path: root/en/devices/architecture/hidl/binder-ipc.html
blob: 811bc3b7c054c3418e758018fcfed1bcb37a4e5a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
<html devsite>
  <head>
    <title>Using Binder IPC</title>
    <meta name="project_path" value="/_project.yaml" />
    <meta name="book_path" value="/_book.yaml" />
  </head>
  <body>
  <!--
      Copyright 2017 The Android Open Source Project

      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at

          http://www.apache.org/licenses/LICENSE-2.0

      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      See the License for the specific language governing permissions and
      limitations under the License.
  -->


<p>This page describes changes to the binder driver in Android O, provides
details on using binder IPC, and lists required SELinux policy.</p>

<h2 id=binder-changes>Changes to binder driver</h2>

<p>Starting in Android O, the Android framework and HALs now communicate with
each other using binder. As this communication dramatically increases binder
traffic, Android O includes several improvements designed to keep binder IPC
fast. SoC vendors and OEMs integrating the latest version of the driver should
review the list of these improvements, relevant SHAs for the 3.18, 4.4, and 4.9
kernels, and required userspace changes.</p>

<h3 id=contexts>Multiple binder domains (contexts)</h3>
<em>In common-3.10, common-3.18, common-4.4, common-4.9, and upstream</em>
<p>
To cleanly split the binder traffic between framework (device-independent) and
vendor (device-specific) code, Android O introduces the concept of a <em>binder
context</em>. Each binder context has its own device node and its own context
(service) manager. You can access the context manager only through the device
node to which it belongs and, when passing a binder node through a certain
context, it is accessible from that same context only by another process, thus
completely isolating the domains from each other. For details on using, see
<a href="#vndbinder">vndbinder</a> and
<a href="#vndservicemanager">vndservicemanager</a>.
</p>


<h3 id=scatter>Scatter-gather</h3>
<em>In common-3.10, common-3.18, common-4.4, common-4.9, and upstream</em>
<p>
In previous releases of Android, every piece of data in a binder call was copied
three times:
</p>
<ul>
<li>Once to serialize it into a
<code><a href="https://developer.android.com/reference/android/os/Parcel.html">Parcel</a></code>
in the calling process</li>
<li>Once in the kernel driver to copy the <code>Parcel</code> to the target
process</li>
<li>Once to unserialize the <code>Parcel</code> in the target process</li>
</ul>

<p>
Android O uses
<a href="https://en.wikipedia.org/wiki/Vectored_I/O">scatter-gather
optimization</a> to reduce the number of copies from 3 to 1. Instead of
serializing data in a <code>Parcel</code> first, data remains in its original
structure and memory layout and the driver immediately copies it to the target
process. After the data is in the target process, the structure and memory
layout is the same and the data can be read without requiring another copy.
</p>

<h3 id=locking>Fine-grained locking</h3>
<em>In common-3.18, common-4.4, common-4.9, and upstream</em>

<p>
In previous Android releases, the binder driver used a global lock to protect
against concurrent access to critical data structures. While there was minimal
contention for the lock, the main problem was that if a low-priority thread
obtained the lock and then got preempted, it could seriously delay
higher-priority threads needing to obtain the same lock. This caused jank in the
platform.
</p>
<p>
Initial attempts to resolve this problem involved disabling preemption while
holding the global lock. However, this was more of a hack than a true solution,
and was eventually rejected by upstream and discarded. Subsequent attempts
focused on making locking more fine-grained, a version of which has been running
on Pixel devices since January 2017. While the majority of those changes were
made public, substantial improvements were made in future versions.
</p>
<p>
After identifying small issues in the fine-grained locking implementation, we
devised an improved solution with a different locking architecture and submitted
the changes in the 3.18, 4.4, and 4.9 common branches. We continue to test this
implementation on a large number of different devices; as we are unaware of any
outstanding issues, this is the recommended implementation for devices shipping
with Android O.
</p>
<p class="note"><strong>Note:</strong> We strongly encourage budgeting
sufficient testing hours for fine-grained locking.
</p>
<h3 id=rt-priority>Real-time priority inheritance</h3>
<em>In common-3.18, common-4.4, common-4.9 (upstream coming soon)</em>

<p>
The binder driver has always supported nice priority inheritance. As an
increasing number of processes in Android run at real-time priority, in some
cases it now makes sense that if a real-time thread makes a binder call, the
thread in the process that handles that call also runs at real-time priority. To
support these use cases, Android O now implements real-time priority inheritance
in the binder driver.
</p>
<p>
In addition to transaction-level priority inheritance, <em>node priority
inheritance</em> allows a node (binder service object) to specify a minimum
priority at which calls into this node should be executed. Previous versions of
Android already supported node priority inheritance with nice values, but
Android O adds support for real-time scheduling policies node inheritance.
</p>
<p class="note"><strong>Note:</strong> The Android performance team found that
real-time priority inheritance caused unwanted side-effects in the framework
binder domain (<code>/dev/binder</code>), so real-time priority inheritance is
<strong>disabled</strong> for that domain.
</p>

<h3 id=userspace>Userspace changes</h3>
<p>
Android O includes all userspace changes required to work with the current
binder driver in the common kernel with one exception: The original
implementation to disable real-time priority inheritance for
<code>/dev/binder</code> used an
<a href="https://android.googlesource.com/kernel/msm/+/868f6ee048c6ff51dbd92353dd5c68bea4419c78" class="external">ioctl</a>. Subsequent development switched control of priority
inheritance to a more fine-grained method that is per binder mode (and not per
context). Thus, the ioctl is not in the Android common branch and is instead
<a href="https://android-review.googlesource.com/#/c/421861/" class="external">submitted
in our common kernels</a>.
</p>
<p>
The effect of this change is that real-time priority inheritance is disabled by
default for <em>every</em> node. The Android performance team has found it
beneficial to enable real-time priority inheritance for all nodes in the
<code>hwbinder</code> domain. To achieve that same effect, cherry-pick
<a href="https://android-review.googlesource.com/#/c/440359/" class="external">this
change</a> in userspace.
</p>
<h3 id=shas>SHAs for common kernels</h3>
<p>
To obtain necessary changes to the binder driver, sync to the SHAs below (or
later):
</p>
<ul>
<li>Common-3.18<br>
cc8b90c121de ANDROID: binder: don't check prio permissions on restore.</li>
<li>Common-4.4<br>
76b376eac7a2 ANDROID: binder: don't check prio permissions on restore.</li>
<li>Common-4.9<br>
ecd972d4f9b5 ANDROID: binder: don't check prio permissions on restore.</li>
</ul>

<h2 id=ipc>Using binder IPC</h2>
<p>Historically, vendor processes have used binder interprocess communication
(IPC) to communicate. In Android O, the <code>/dev/binder</code> device node
becomes exclusive to framework processes, meaning vendor processes no longer
have access to it. Vendor processes can access <code>/dev/hwbinder</code>, but
must convert their AIDL interfaces to use HIDL. For vendors who want to continue
using AIDL interfaces between vendor processes, Android supports binder IPC as
described below.</p>

<h3 id=vndbinder>vndbinder</h3>
<p>Android O supports a new binder domain for use by vendor services, accessed
using <code>/dev/vndbinder</code> instead of <code>/dev/binder</code>. With the
addition of <code>/dev/vndbinder</code>, Android now has the following three
IPC domains:</p>

<table>
  <tr>
   <th>IPC Domain</th>
   <th>Description</th>
  </tr>
  <tr>
   <td><code>/dev/binder</code></td>
   <td>IPC between framework/app processes with AIDL interfaces</td>
  </tr>
  <tr>
   <td><code>/dev/hwbinder</code></td>
   <td>IPC between framework/vendor processes with HIDL interfaces
   <br>IPC between vendor processes with HIDL interfaces</td>
  </tr>
  <tr>
   <td><code>/dev/vndbinder</code></td>
   <td>IPC between vendor/vendor processes with AIDL Interfaces</td>
  </tr>
</table>

<p>For <code>/dev/vndbinder</code> to appear, ensure the kernel configuration
item <code>CONFIG_ANDROID_BINDER_DEVICES</code> is set to
<code>"binder,hwbinder,vndbinder"</code> (this is the default in Android's
common kernel trees).</p>

<p>Normally, vendor processes don't open the binder driver directly and instead
link against the <code>libbinder</code> userspace library, which opens the
binder driver. Adding a method for <code>::android::ProcessState()</code>
selects the binder driver for <code>libbinder</code>. Vendor processes should
call this method <strong>before</strong> calling into <code>ProcessState,</code>
<code>IPCThreadState</code>, or before making any binder calls in general. To
use, place the following call after the <code>main()</code> of a vendor process
(client and server):</p>

<pre class="prettyprint">ProcessState::initWithDriver("/dev/vndbinder");</pre>

<h3 id=vndservicemanager>vndservicemanager</h3>
<p>Previously, binder services were registered with <code>servicemanager</code>,
where they could be retrieved by other processes. In Android O,
<code>servicemanager</code> is now used exclusively by framework and app
processes and vendor processes can no longer access it.</p>

<p>However, vendor services can now use <code>vndservicemanager</code>, a new
instance of <code>servicemanager</code> that uses <code>/dev/vndbinder</code>
instead of <code>/dev/binder</code> and which is built from the same sources as
framework <code>servicemanager</code>. Vendor processes do not need to make
changes to talk to <code>vndservicemanager</code>; when a vendor process opens
/<code>dev/vndbinder</code>, service lookups automatically go to
<code>vndservicemanager</code>.</p>

<p>The <code>vndservicemanager</code> binary is included in Android's default
device makefiles.</p>

<h2 id=selinux>SELinux policy</h2>
<p>Vendor processes that want to use binder functionality to communicate with
each other need the following:</p>
<ol>
<li>Access to <code>/dev/vndbinder</code>.</li>
<li>Binder <code>{transfer, call}</code> hooks into
<code>vndservicemanager</code>.</li>
<li><code>binder_call(A, B)</code> for any vendor domain A that wants to call
into vendor domain B over the vendor binder interface.</li>
<li>Permission to <code>{add, find}</code> services in
<code>vndservicemanager</code>.</li>
</ol>

<p>To fulfill requirements 1 and 2, use the <code>vndbinder_use()</code>
macro:</p>

<pre class="prettyprint">vndbinder_use(some_vendor_process_domain);</pre>

<p>To fulfill requirement 3, the <code>binder_call(A, B)</code> for vendor
processes A and B that need to talk over binder can stay in place, and doesn't
need renaming.</p>

<p>To fulfill requirement 4, you must make changes in the way service names,
service labels, and rules are handled.</p>

<p>For details on SELinux, see
<a href="https://source.android.com/security/selinux/">Security-Enhanced Linux
in Android</a>. For details on SELinux in Android 8.0, see
<a href="/security/selinux/images/SELinux_Treble.pdf">SELinux for Android
8.0</a>.</p>

<h3 id=names>Service names</h3>
<p>Previously, vendor processes registered service names in a
<code>service_contexts</code> file and added corresponding rules for accessing
that file. Example <code>service_contexts</code> file from
<code>device/google/marlin/sepolicy</code>:</p>

<pre class="devsite-click-to-copy">
AtCmdFwd                              u:object_r:atfwd_service:s0
cneservice                            u:object_r:cne_service:s0
qti.ims.connectionmanagerservice      u:object_r:imscm_service:s0
rcs                                   u:object_r:radio_service:s0
uce                                   u:object_r:uce_service:s0
vendor.qcom.PeripheralManager         u:object_r:per_mgr_service:s0
</pre>

<p>In Android O, <code>vndservicemanager</code> loads the
<code>vndservice_contexts</code> file instead. Vendor services migrating to
<code>vndservicemanager</code> (and which are already in the old
<code>service_contexts</code> file) should be added to the new
<code>vndservice_contexts</code> file.</p>

<h3 id=labels>Service labels</h3>
<p>Previously, service labels such as <code>u:object_r:atfwd_service:s0</code>
were defined in a <code>service.te</code> file. Example:</p>

<pre class="prettyprint">type atfwd_service,      service_manager_type;</pre>

<p>In Android O, you must change the type to
<code>vndservice_manager_type</code> and move the rule to the
<code>vndservice.te</code> file. Example:</p>

<pre class="prettyprint">type atfwd_service,      vndservice_manager_type;</pre>

<h3 id=rules>Servicemanager rules</h3>
<p>Previously, rules granted domains access to add or find services from
<code>servicemanager</code>. Example:</p>

<pre class="prettyprint">
allow atfwd atfwd_service:service_manager find;
allow some_vendor_app atfwd_service:service_manager add;
</pre>

<p>In Android O, such rules can stay in place and use the same class. Example:
</p>

<pre class="prettyprint">
allow atfwd atfwd_service:service_manager find;
allow some_vendor_app atfwd_service:service_manager add;
</pre>

  </body>
</html>