History

binder: frozen notification

Frozen processes present a significant challenge in binder transactions. When a process is frozen, it cannot, by design, accept and/or respond to binder transactions. As a result, the sender needs to adjust its behavior, such as postponing transactions until the peer process unfreezes. However, there is currently no way to subscribe to these state change events, making it impossible to implement frozen-aware behaviors efficiently. Introduce a binder API for subscribing to frozen state change events. This allows programs to react to changes in peer process state, mitigating issues related to binder transactions sent to frozen processes. Implementation details: For a given binder_ref, the state of frozen notification can be one of the followings: 1. Userspace doesn't want a notification. binder_ref->freeze is null. 2. Userspace wants a notification but none is in flight. list_empty(&binder_ref->freeze->work.entry) = true 3. A notification is in flight and waiting to be read by userspace. binder_ref_freeze.sent is false. 4. A notification was read by userspace and kernel is waiting for an ack. binder_ref_freeze.sent is true. When a notification is in flight, new state change events are coalesced into the existing binder_ref_freeze struct. If userspace hasn't picked up the notification yet, the driver simply rewrites the state. Otherwise, the notification is flagged as requiring a resend, which will be performed once userspace acks the original notification that's inflight. See https://r.android.com/3070045 for how userspace is going to use this feature.

Yu-Ting Tseng committed 2 years ago

Commit d579b041 parent 104831a3 files · +337 −4Browse files

Showing the changes to include/uapi/linux/android (1 of 3 files). Show all

Unified · Split

include/uapi/linux/android/binder.h+36−0
@@ -236,6 +236,12 @@ struct binder_frozen_status_info { · 235 unmodified lines
236 __u32 async_recv;236 __u32 async_recv;
237};237};
238 238
239struct binder_frozen_state_info {
240 binder_uintptr_t cookie;
241 __u32 is_frozen;
242 __u32 reserved;
243};
244
239/* struct binder_extened_error - extended error information245/* struct binder_extened_error - extended error information
240 * @id: identifier for the failed operation246 * @id: identifier for the failed operation
241 * @command: command as defined by binder_driver_return_protocol247 * @command: command as defined by binder_driver_return_protocol
@@ -467,6 +473,17 @@ enum binder_driver_return_protocol { · 225 unmodified lines
467 /*473 /*
468 * The target of the last async transaction is frozen. No parameters.474 * The target of the last async transaction is frozen. No parameters.
469 */475 */
476
477 BR_FROZEN_BINDER = _IOR('r', 21, struct binder_frozen_state_info),
478 /*
479 * The cookie and a boolean (is_frozen) that indicates whether the process
480 * transitioned into a frozen or an unfrozen state.
481 */
482
483 BR_CLEAR_FREEZE_NOTIFICATION_DONE = _IOR('r', 22, binder_uintptr_t),
484 /*
485 * void *: cookie
486 */
470};487};
471 488
472enum binder_driver_command_protocol {489enum binder_driver_command_protocol {
@@ -550,6 +567,25 @@ enum binder_driver_command_protocol { · 77 unmodified lines
550 /*567 /*
551 * binder_transaction_data_sg: the sent command.568 * binder_transaction_data_sg: the sent command.
552 */569 */
570
571 BC_REQUEST_FREEZE_NOTIFICATION =
572 _IOW('c', 19, struct binder_handle_cookie),
573 /*
574 * int: handle
575 * void *: cookie
576 */
577
578 BC_CLEAR_FREEZE_NOTIFICATION = _IOW('c', 20,
579 struct binder_handle_cookie),
580 /*
581 * int: handle
582 * void *: cookie
583 */
584
585 BC_FREEZE_NOTIFICATION_DONE = _IOW('c', 21, binder_uintptr_t),
586 /*
587 * void *: cookie
588 */
553};589};
554 590
555#endif /* _UAPI_LINUX_BINDER_H */591#endif /* _UAPI_LINUX_BINDER_H */