Re: [RFC] simple_lmk: Introduce Simple Low Memory Killer for Android

From: Suren Baghdasaryan
Date: Sat Mar 16 2019 - 15:42:54 EST


On Sat, Mar 16, 2019 at 11:57 AM Christian Brauner <christian@xxxxxxxxxx> wrote:
>
> On Sat, Mar 16, 2019 at 11:00:10AM -0700, Daniel Colascione wrote:
> > On Sat, Mar 16, 2019 at 10:31 AM Suren Baghdasaryan <surenb@xxxxxxxxxx> wrote:
> > >
> > > On Fri, Mar 15, 2019 at 11:49 AM Joel Fernandes <joel@xxxxxxxxxxxxxxxxx> wrote:
> > > >
> > > > On Fri, Mar 15, 2019 at 07:24:28PM +0100, Christian Brauner wrote:
> > > > [..]
> > > > > > why do we want to add a new syscall (pidfd_wait) though? Why not just use
> > > > > > standard poll/epoll interface on the proc fd like Daniel was suggesting.
> > > > > > AFAIK, once the proc file is opened, the struct pid is essentially pinned
> > > > > > even though the proc number may be reused. Then the caller can just poll.
> > > > > > We can add a waitqueue to struct pid, and wake up any waiters on process
> > > > > > death (A quick look shows task_struct can be mapped to its struct pid) and
> > > > > > also possibly optimize it using Steve's TIF flag idea. No new syscall is
> > > > > > needed then, let me know if I missed something?
> > > > >
> > > > > Huh, I thought that Daniel was against the poll/epoll solution?
> > > >
> > > > Hmm, going through earlier threads, I believe so now. Here was Daniel's
> > > > reasoning about avoiding a notification about process death through proc
> > > > directory fd: http://lkml.iu.edu/hypermail/linux/kernel/1811.0/00232.html
> > > >
> > > > May be a dedicated syscall for this would be cleaner after all.
> > >
> > > Ah, I wish I've seen that discussion before...
> > > syscall makes sense and it can be non-blocking and we can use
> > > select/poll/epoll if we use eventfd.
> >
> > Thanks for taking a look.
> >
> > > I would strongly advocate for
> > > non-blocking version or at least to have a non-blocking option.
> >
> > Waiting for FD readiness is *already* blocking or non-blocking
> > according to the caller's desire --- users can pass options they want
> > to poll(2) or whatever. There's no need for any kind of special
> > configuration knob or non-blocking option. We already *have* a
> > non-blocking option that works universally for everything.
> >
> > As I mentioned in the linked thread, waiting for process exit should
> > work just like waiting for bytes to appear on a pipe. Process exit
> > status is just another blob of bytes that a process might receive. A
> > process exit handle ought to be just another information source. The
> > reason the unix process API is so awful is that for whatever reason
> > the original designers treated processes as some kind of special kind
> > of resource instead of fitting them into the otherwise general-purpose
> > unix data-handling API. Let's not repeat that mistake.
> >
> > > Something like this:
> > >
> > > evfd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
> > > // register eventfd to receive death notification
> > > pidfd_wait(pid_to_kill, evfd);
> > > // kill the process
> > > pidfd_send_signal(pid_to_kill, ...)
> > > // tend to other things
> >
> > Now you've lost me. pidfd_wait should return a *new* FD, not wire up
> > an eventfd.
> >

Ok, I probably misunderstood your post linked by Joel. I though your
original proposal was based on being able to poll a file under
/proc/pid and then you changed your mind to have a separate syscall
which I assumed would be a blocking one to wait for process exit.
Maybe you can describe the new interface you are thinking about in
terms of userspace usage like I did above? Several lines of code would
explain more than paragraphs of text.

> > Why? Because the new type FD can report process exit *status*
> > information (via read(2) after readability signal) as well as this
> > binary yes-or-no signal *that* a process exited, and this capability
> > is useful if you want to the pidfd interface to be a good
> > general-purpose process management facility to replace the awful
> > wait() family of functions. You can't get an exit status from an
> > eventfd. Wiring up an eventfd the way you've proposed also complicates
> > wait-causality information, complicating both tracing and any priority
> > inheritance we might want in the future (because all the wakeups gets
> > mixed into the eventfd and you can't unscramble an egg). And for what?
> > What do we gain by using an eventfd? Is the reason that exit.c would
> > be able to use eventfd_signal instead of poking a waitqueue directly?
> > How is that better? With an eventfd, you've increased path length on
> > process exit *and* complicated the API for no reason.
> >
> > > ...
> > > // wait for the process to die
> > > poll_wait(evfd, ...);
> > >
> > > This simplifies userspace
> >
> > Not relative to an exit handle it doesn't.
> >
> > >, allows it to wait for multiple events using
> > > epoll
> >
> > So does a process exit status handle.
> >
> > > and I think kernel implementation will be also quite simple
> > > because it already implements eventfd_signal() that takes care of
> > > waitqueue handling.
> >
> > What if there are multiple eventfds registered for the death of a
> > process? In any case, you need some mechanism to find, upon process
> > death, a list of waiters, then wake each of them up. That's either a
> > global search or a search in some list rooted in a task-related
> > structure (either struct task or one of its friends). Using an eventfd
> > here adds nothing, since upon death, you need this list search
> > regardless, and as I mentioned above, eventfd-wiring just makes the
> > API worse.
> >
> > > If pidfd_send_signal could be extended to have an optional eventfd
> > > parameter then we would not even have to add a new syscall.
> >
> > There is nothing wrong with adding a new system call. I don't know why
> > there's this idea circulating that adding system calls is something we
> > should bend over backwards to avoid. It's cheap, and support-wise,
> > kernel interface is kernel interface. Sending a signal has *nothing*
> > to do with wiring up some kind of notification and there's no reason
> > to mingle it with some kind of event registration.
>
>
> I agree with Daniel.
> One design goal is to not stuff clearly delinated tasks related to
> process management into the same syscall. That will just leave us with a
> confusing api. Sending signals is part of managing a process while it is
> running. Waiting on a process to end is clearly separate from that.
> It's important to keep in mind that the goal of the pidfd work is to end
> up with an api that is of use to all of user space concerned with
> process management not just a specific project.

I'm not bent on adding or not adding a new syscall as long as
functionality is there.
Thanks!