CVSROOT:        /cvs
Module name:    src
Changes by:     d...@cvs.openbsd.org    2015/08/16 06:17:16

Modified files:
        sys/net        : bpf.c bpfdesc.h 

Log message:
make bpf_mtap mpsafe by using SRPs.

this was originally implemented by jmatthew@ last year, and updated
by us both during s2k15.

there are four data structures that need to be looked after.

the first is the bpf interface itself. it is allocated and freed
at the same time as an actual interface, so if you're able to send
or receive packets, you're able to run bpf on an interface too.
dont need to do any work there.

the second are bpf descriptors. these represent userland attaching
to a bpf interface, so you can have many of them on a single bpf
interface. they were arranged in a singly linked list before. now
the head and next pointers are replaced with SRP pointers and
followed by srp_enter. the list updates are serialised by the kernel
lock.

the third are the bpf filters. there is an inbound and outbound
filter on each bpf descriptor, ann a process can replace them at
any time. the pointers from the descriptor to those is also changed
to be accessed via srp_enter. updates are serialised by the kernel
lock.

the fourth thing is the ring that bpf writes to for userland to
read. there's one of these per descriptor. because these are only
updated when a filter matches (which is hopefully a relatively rare
event), we take the kernel lock to serialise the writes to the ring.

all this together means you can run bpf against a packet without
taking the kernel lock unless you actually caught a packet and need
to send it to userland. even better, you can run bpf in parallel,
so if we ever support multiple rings on a single interface, we can
run bpf on each ring on different cpus safely.

ive hit this pretty hard in production at work (yay dhcrelay) on
myx (which does rx outside the biglock).

ok jmatthew@ mpi@ millert@

Reply via email to