lkml.org 
[lkml]   [2020]   [Jun]   [30]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Date
SubjectRe: [PATCH v2 00/15] Make the user mode driver code a better citizen
Alexei Starovoitov <alexei.starovoitov@gmail.com> writes:

2> On Mon, Jun 29, 2020 at 02:55:05PM -0500, Eric W. Biederman wrote:
>>
>> I have tested thes changes by booting with the code compiled in and
>> by killing "bpfilter_umh" and running iptables -vnL to restart
>> the userspace driver.
>>
>> I have compiled tested each change with and without CONFIG_BPFILTER
>> enabled.
>
> With
> CONFIG_BPFILTER=y
> CONFIG_BPFILTER_UMH=m
> it doesn't build:
>
> ERROR: modpost: "kill_pid_info" [net/bpfilter/bpfilter.ko] undefined!
>
> I've added:
> +EXPORT_SYMBOL(kill_pid_info);
> to continue testing...

I am rather surprised I thought Tetsuo had already compile tested
modules.


> I suspect patch 13 is somehow responsible:
> + if (tgid) {
> + kill_pid_info(SIGKILL, SEND_SIG_PRIV, tgid);
> + wait_event(tgid->wait_pidfd, !pid_task(tgid, PIDTYPE_TGID));
> + bpfilter_umh_cleanup(info);
> + }
>
> I cannot figure out why it hangs. Some sort of race ?
> Since adding short delay between kill and wait makes it work.

Having had a chance to sleep kill_pid_info was a thinko, as was
!pid_task. It should have been !pid_has_task as that takes the proper
rcu locking.

I don't know if that is going to be enough to fix the wait_event
but those are obvious bugs that need to be fixed.

diff --git a/net/bpfilter/bpfilter_kern.c b/net/bpfilter/bpfilter_kern.c
index 91474884ddb7..3e1874030daa 100644
--- a/net/bpfilter/bpfilter_kern.c
+++ b/net/bpfilter/bpfilter_kern.c
@@ -19,8 +19,8 @@ static void shutdown_umh(void)
struct pid *tgid = info->tgid;

if (tgid) {
- kill_pid_info(SIGKILL, SEND_SIG_PRIV, tgid);
- wait_event(tgid->wait_pidfd, !pid_task(tgid, PIDTYPE_TGID));
+ kill_pid(tgid, SIGKILL, 1);
+ wait_event(tgid->wait_pidfd, !pid_has_task(tgid, PIDTYPE_TGID));
bpfilter_umh_cleanup(info);
}
}
> And then did:
> while true; do iptables -L;rmmod bpfilter; done
>
> Unfortunately sometimes 'rmmod bpfilter' hangs in wait_event().

Hmm. The wake up happens just of tgid->wait_pidfd happens just before
release_task is called so there is a race. As it is possible to wake
up and then go back to sleep before pid_has_task becomes false.

So I think I need a friendly helper that does:

bool task_has_exited(struct pid *tgid)
{
bool exited = false;
rcu_read_lock();
tsk = pid_task(tgid, PIDTYPE_TGID);
exited = !!tsk;
if (tsk) {
exited = !!tsk->exit_state;
out:
rcu_unlock();
return exited;
}
There should be a sensible way to do that.

Eric


\
 
 \ /
  Last update: 2020-06-30 14:35    [W:0.331 / U:0.296 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site