On Mon, Dec 28, 2020 at 02:45:06PM +1000, David Gwynne wrote:
> now that bpf read timeouts are only handled on the bpfread() side,
> there's a simplification that can be made in bpf_catchpacket. the chunk
> in bpf_catchpacket that rotates the buffers when one gets full already
> does a wakeup, so we don't have to check if we have any waiting readers
> and wake them up when a buffer gets full.
> 
> we can use bd_nreaders to omgoptimise bpf_wakeup though. wakeup(9) is
> mpsafe, so we don't have to defer the call to a task. however, we can
> avoid calling wakeup() and therefore trying to take the sched lock and
> all that stuff when we know there's nothing sleeping.
> 
> this also avoids scheduling the task if there's no async stuff set up.
> it's a bit magical because it knows what's inside selwakeup.
> 
> tests? ok?

visa pointed out that i missed a bit relating to kq.

Index: bpf.c
===================================================================
RCS file: /cvs/src/sys/net/bpf.c,v
retrieving revision 1.199
diff -u -p -r1.199 bpf.c
--- bpf.c       26 Dec 2020 16:30:58 -0000      1.199
+++ bpf.c       29 Dec 2020 06:04:58 -0000
@@ -554,7 +554,6 @@ out:
        return (error);
 }
 
-
 /*
  * If there are processes sleeping on this descriptor, wake them up.
  */
@@ -563,14 +562,20 @@ bpf_wakeup(struct bpf_d *d)
 {
        MUTEX_ASSERT_LOCKED(&d->bd_mtx);
 
+       if (d->bd_nreaders)
+               wakeup(d);
+
        /*
         * As long as pgsigio() 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);
-       if (!task_add(systq, &d->bd_wake_task))
-               bpf_put(d);
+       if ((d->bd_async && d->bd_sig) ||
+           (!klist_empty(&d->bd_sel.si_note) || d->bd_sel.si_seltid != 0)) {
+               bpf_get(d);
+               if (!task_add(systq, &d->bd_wake_task))
+                       bpf_put(d);
+       }
 }
 
 void
@@ -578,7 +583,6 @@ bpf_wakeup_cb(void *xd)
 {
        struct bpf_d *d = xd;
 
-       wakeup(d);
        if (d->bd_async && d->bd_sig)
                pgsigio(&d->bd_sigio, d->bd_sig, 0);
 
@@ -1542,17 +1546,6 @@ bpf_catchpacket(struct bpf_d *d, u_char 
                 * reads should be woken up.
                 */
                do_wakeup = 1;
-       }
-
-       if (d->bd_nreaders > 0) {
-               /*
-                * We have one or more threads sleeping in bpfread().
-                * We got a packet, so wake up all readers.
-                */
-               if (d->bd_fbuf != NULL) {
-                       ROTATE_BUFFERS(d);
-                       do_wakeup = 1;
-               }
        }
 
        if (do_wakeup)

Reply via email to