On Mon, 15 Aug 2016, Martin Pieuchot wrote:
> I'd like to make sure that bpf_tap(9) does not grab the KERNEL_LOCK().
> The reason is to reduce the potential lock ordering problems within PF.
> 
> I'm currently using a mutex to serialize buffer changes, but since
> bpf_wakeup() will still need the KERNEL_LOCK(), I'm using a task for
> that.

Yes, this is a good direction to unblock the network stack work.  
However, I suspect there's a bug below.


> @@ -515,12 +519,28 @@ bpfread(dev_t dev, struct uio *uio, int 
>  void
>  bpf_wakeup(struct bpf_d *d)
>  {
> -     wakeup((caddr_t)d);
> +     /*
> +      * As long as csignal() and selwakeup() need to be protected
> +      * by the KERNEL_LOCK() we have to delay the wakeup to
> +      * another context to keep the hot path KERNEL_LOCK()-free.
> +      */
> +     bpf_get(d);
> +     task_add(systq, &d->bd_wake_task);

We increment the reference count here and decrement it in bpf_wakeup_cb().
However, if the task is already queued here in bpf_wakeup() then won't it
get bumped again and only released once?  I suspect this should be:
        bpf_get(d);
        if (!task_add(systq, &d->bd_wake_task))
                bpf_put(d);

dlg@, am I misremembering when that check is necessary?


Philip Guenther

Reply via email to