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
236236 __u32 async_recv;
237237 };
238238
239+struct binder_frozen_state_info {
240+ binder_uintptr_t cookie;
241+ __u32 is_frozen;
242+ __u32 reserved;
243+};
244+
239245 /* struct binder_extened_error - extended error information
240246 * @id: identifier for the failed operation
241247 * @command: command as defined by binder_driver_return_protocol
@@ -467,6 +473,17 @@ enum binder_driver_return_protocol { · 225 unmodified lines
467473 /*
468474 * The target of the last async transaction is frozen. No parameters.
469475 */
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+ */
470487 };
471488
472489 enum binder_driver_command_protocol {
@@ -550,6 +567,25 @@ enum binder_driver_command_protocol { · 77 unmodified lines
550567 /*
551568 * binder_transaction_data_sg: the sent command.
552569 */
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+ */
553589 };
554590
555591 #endif /* _UAPI_LINUX_BINDER_H */