[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <2024062106-edge-visiting-23b5@gregkh>
Date: Fri, 21 Jun 2024 08:10:12 +0200
From: Greg KH <gregkh@...uxfoundation.org>
To: Yu-Ting Tseng <yutingtseng@...gle.com>
Cc: cmllamas@...gle.com, tkjos@...gle.com, kernel-team@...roid.com,
linux-kernel@...r.kernel.org
Subject: Re: [PATCH v1] binder: frozen notification
On Tue, Jun 18, 2024 at 03:19:08PM -0700, Yu-Ting Tseng wrote:
> 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 staet 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.
As this is adding a new user/kernel api, where are the corrisponding
changes to userspace to show how this is being used?
> + case BINDER_WORK_FROZEN_BINDER:
> + case BINDER_WORK_UNFROZEN_BINDER: {
> + struct binder_ref_freeze *freeze;
> + struct binder_frozen_state_info info;
> +
> + freeze = container_of(w, struct binder_ref_freeze, work);
> + info.is_frozen = w->type == BINDER_WORK_FROZEN_BINDER;
> + info.cookie = freeze->cookie;
> + freeze->sent = true;
> + binder_enqueue_work_ilocked(w, &proc->delivered_freeze);
> + binder_inner_proc_unlock(proc);
> +
> + if (put_user(BR_FROZEN_BINDER, (uint32_t __user *)ptr))
> + return -EFAULT;
> + ptr += sizeof(uint32_t);
> + if (put_user(info.cookie,
> + (binder_uintptr_t __user *)ptr))
> + return -EFAULT;
> + ptr += sizeof(binder_uintptr_t);
> + if (put_user(info.is_frozen, (uint32_t __user *)ptr))
> + return -EFAULT;
> + ptr += sizeof(uint32_t);
Multiple put_user() calls seems slow to me, why not properly cast this
to a structure and just copy the whole thing at once? That would remove
the multiple checks from happening and take advantage of the fact that
cpus can copy data very quickly.
Or is this not a "hot path" at all where performance matters?
thanks,
greg k-h
Powered by blists - more mailing lists