BACKPORT: FROMGIT: 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.

Signed-off-by: Yu-Ting Tseng <yutingtseng@google.com>
Acked-by: Carlos Llamas <cmllamas@google.com>
Link: https://lore.kernel.org/r/20240709070047.4055369-4-yutingtseng@google.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

Bug: 363013421
(cherry picked from commit d579b04a52a183db47dfcb7a44304d7747d551e1
 git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc.git
 char-misc-next)
Change-Id: I5dd32abba932ca7d03ae58660143e075ed778b81
[cmllamas: fix merge conflicts due to missing 0567461a7a6e]
Signed-off-by: Carlos Llamas <cmllamas@google.com>
This commit is contained in:
Yu-Ting Tseng 2024-07-09 00:00:47 -07:00 • committed by Carlos Llamas
commit d1e87637cd
4 changed files with 337 additions and 3 deletions

View file

@ -284,6 +284,12 @@ struct binder_frozen_status_info {
__u32 async_recv;
};
struct binder_frozen_state_info {
binder_uintptr_t cookie;
__u32 is_frozen;
__u32 reserved;
};
#define BINDER_WRITE_READ _IOWR('b', 1, struct binder_write_read)
#define BINDER_SET_IDLE_TIMEOUT _IOW('b', 3, __s64)
#define BINDER_SET_MAX_THREADS _IOW('b', 5, __u32)
@ -492,6 +498,17 @@ enum binder_driver_return_protocol {
* asynchronous transaction makes the allocated async buffer size exceed
* detection threshold. No parameters.
*/
BR_FROZEN_BINDER = _IOR('r', 21, struct binder_frozen_state_info),
/*
* The cookie and a boolean (is_frozen) that indicates whether the process
* transitioned into a frozen or an unfrozen state.
*/
BR_CLEAR_FREEZE_NOTIFICATION_DONE = _IOR('r', 22, binder_uintptr_t),
/*
* void *: cookie
*/
};
enum binder_driver_command_protocol {
@ -575,6 +592,25 @@ enum binder_driver_command_protocol {
/*
* binder_transaction_data_sg: the sent command.
*/
BC_REQUEST_FREEZE_NOTIFICATION =
_IOW('c', 19, struct binder_handle_cookie),
/*
* int: handle
* void *: cookie
*/
BC_CLEAR_FREEZE_NOTIFICATION = _IOW('c', 20,
struct binder_handle_cookie),
/*
* int: handle
* void *: cookie
*/
BC_FREEZE_NOTIFICATION_DONE = _IOW('c', 21, binder_uintptr_t),
/*
* void *: cookie
*/
};
#endif /* _UAPI_LINUX_BINDER_H */