kernel - Initial commit for Existential structural tracking
authorMatthew Dillon <dillon@apollo.backplane.com>
Mon, 12 Oct 2020 22:57:46 +0000 (15:57 -0700)
committerMatthew Dillon <dillon@apollo.backplane.com>
Tue, 13 Oct 2020 01:58:49 +0000 (18:58 -0700)
commit8f7f5bd589c484ba65824877064d823fc93cd50d
tree50eca42224a9f4611ed1b23e0575c530a4c11598
parent34399089e1192d5f0ff81c8c43d392649fb6aa2a
kernel - Initial commit for Existential structural tracking

* Initial commit for exislock (existance-lock) support, based on
  cpu tick interlocks.  Requires a bit more work.

  (see also previous commit 'Add missing sys/exislock.h' which wasn't
  actually missing at the time).

  This is a type-safe critical section plus a cache-friendly soft-lock
  type for system data structures that allows interlocking against structural
  existance and usability.

  The critical path has no atomic operations or cache ping-ponging.  Cache
  ping-ponging occurs at most once per pseudo_tick (once every 2 real
  ticks) to reset the timeout field.

* Implements a global 'pseudo_ticks' counter.  This counter is only able
  to count when all cpus are armed.  All cpus are armed on every 1->0
  transition of their mycpu->gd_exislockcnt field.  This, while the
  interlock is held, the global pseudo_ticks counter will increment
  by at most one, then stall.

  The cpus are disarmed when this increment occurs on even ticks
  and rearmed (if gd_exislockcnt is 0) on odd ticks.  This the global
  pseudo_ticks counter increments at roughly hz / 2 under most conditions.

  This means that even when the per-cpu type-safe critical section is
  under very heavy load, cycling constantly, the global pseudo_ticks
  still tends to increment on a regular basis becaues there are a lot
  of 1->0 transitions occurring on each cpu.  Importantly, the cpus do
  not need to be synchronized in order for pseudo_ticks to increment.

* This codebase will be used to implement type-safe storage and
  lockless hash-table based caches.  It works like this:

  - You use exis_hold() and exis_drop() around the type-safe
    code sections.

    While held, the global pseudo_ticks variable is guaranteed to
    increment no more than once (due to a prior arming condition).

  - You access the hash table or other robust structural topology
    (with or without locks depending), then call exis_isusable() on
    the structure you get to determine if it is usable.  If TRUE is
    returned, the structure will remain type-safe and will not be
    repurposed for the duration of the exis_hold().

    You then proceed to use the structure as needed, with or without
    further locking depending on what you are doing.  For example,
    accessing stat information from a vnode structure could potentially
    proceed without further locking.
sys/kern/kern_clock.c
sys/kern/vfs_mount.c
sys/sys/exislock.h
sys/sys/globaldata.h