tech-net archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: passive references
Hi riastradh,
It's cool! It should help our work.
I'm thinking applying psref to bridge member list
that is now using its own version of similar mechanism
(psz + refcount).
To do so, some questions come to me:
- Can psref_acquire and psref_release be used in ioctl
handlers if we use kprempet_disable together?
- Bridge member lists can be accessed via ioctl
that runs in normal LWP context
- Can we use pserialize_read_{enter,exit} for psref
objects?
- Not all critical sections of a bridge member list
are sleepable. If we can use pserialize_read_{enter,exit}
directly for non-sleepable critical sections, it makes
the code simple and efficient
Thanks,
ozaki-r
BTW psref recalls me hazard pointers (and OpenBSD's SRP).
On Mon, Jan 25, 2016 at 4:10 AM, Taylor R Campbell <riastradh%netbsd.org@localhost> wrote:
> To make the network stack scale well to multiple cores, the packet-
> processing path needs to share resources such as routes, tunnels,
> pcbs, &c., between cores without incurring much interprocessor
> synchronization.
>
> It would be nice to use pserialize(9) for this, but many of these
> resources are held by code paths during packet processing that may
> sleep, which is not allowed in a pserialize read section. The two
> obvious ways to resolve this are:
>
> - Change all of these paths so that they don't sleep and can be run
> inside a pserialize read section. This is a major engineering
> effort, because the network stack is such a complex interdependent
> beast.
>
> - Add a reference count to each route, tunnel, pcb, &c. This would
> work to make the network stack *safe* to run on multiple cores, but
> it incurs interprocessor synchronization for each use and hence
> fails to make the network stack *scalable* to multiple cores.
>
> Prompted by discussion with rmind@ and dyoung@, I threw together a
> sketch for an abstraction rmind called `passive references' which can
> be held across sleeps on a single CPU -- e.g., in a softint LWP or
> CPU-bound kthread -- but which incur no interprocessor synchronization
> to acquire and release. This would serve as an intermediary between
> the two options so that we can incrementally adapt the network stack.
>
> The idea is that acquiring a reference puts an entry on a CPU-local
> list, which can be done inside a pserialize read section. Releasing
> the reference removes the entry. When an object is about to be
> destroyed -- e.g., you are unconfiguring a tunnel -- then you mark it
> as unusable so that nobody can acquire new references, and wait until
> there are no references on any CPU's list.
>
> The attached file contains a summary of the design, an example of use,
> and a sketch of an implementation, with input and proof-reading from
> riz@.
>
> Thoughts?
>
>
> A variant of this approach which dyoung@ has used in the past is to
> count the number of references, instead of putting them on a list, on
> each CPU. I first wrote a sketch with a count instead of a list,
> thinking mainly of using this just for ip_encap tunnels, of which
> there are likely relatively few, and not for routes or pcbs.
>
> However, if there are many more objects than references -- as I expect
> to be with most kinds of packet flow that the packet-processing path
> will handle one or two of at a time --, it would waste a lot of space
> to have one count on each CPU for each object, yet the list of all
> references on each CPU (to any object) would be relatively short.
Home |
Main Index |
Thread Index |
Old Index