netgraph7: Major rework of netgraph7 internal mechanisms.
authorNuno Antunes <nuno.antunes@gmail.com>
Thu, 9 May 2013 21:59:47 +0000 (21:59 +0000)
committerNuno Antunes <nuno.antunes@gmail.com>
Fri, 11 Jul 2014 09:17:09 +0000 (10:17 +0100)
commitad9efc7b235ec25d20a098e85139e14458b6b2a3
tree03c7a0897ea5fca725ce300f9744db26473d2434
parent872b14d76577642bc1979e9a410b7e291550ab61
netgraph7: Major rework of netgraph7 internal mechanisms.

* Promote the netgraph taskqueue to a fully fledged per-CPU lwkt.

  Currently all work is queued to cpu0 but the idea is to later distribute
  work among the threads.  I also explored the idea of using netisr threads
  instead of our own dedicated threads but I think it would be a bad idea to
  globaly block a netisr thread due to a netgraph token or other lock.

* Embed a struct lwkt_msg in netgraph items.

* Make ng_apply_item() accept only one argument.

* Remove the global worklist and per-node input queues and related routines.

* Always and only queue items coming from interrupt context.

  Items are now always queued, except if they are already being sent from a
  netgraph thread (depth > 1).  The NG_QUEUE and HK_QUEUE flags become no-ops
  but are kept for compatibility reasons.

* Replace the node reader/writer gate with a per-node lwkt shared
  token.

* Remove some #if 0'd code

* netgraph7/ng_socket: Avoid blocking on netisr.

  Previously, the ng_socket code used a sleep/wakeup mechanism to
  prevent returning immediatly from the syscall.  This caused
  netisr_cpu 0 to block globaly until the item was processed,
  which is very inneficient.

  Instead, delay the lwkt_replymsg call in the normal case until the item
  has been processed.  This achieves the same requirement of not returning
  from syscall until the item is processed but is much more elegant.

  Because ngc_send() returns sooner now, we can't allocate the apply
  info from the stack.  Instead, dynamically allocate it from an
  objcache.

* Zeroize an item before returning it to the objcache.

  Objects must be in their initialized state before being returned
  to the object cache.  Do that for netgraph items.

  The above exposed a use after free bug.  An item must remain valid
  until is applied.  If an item has been queued with a registered apply
  callback, free it only after the callback is made.

* Add a function to check and apply the callback in case the item has
  one registered.

* Pass the apply callback error via lwkt_replymsg() directly, instead of
  using a field in the apply_info structure.

* Make sure that ng_socket items don't have their apply callback called
  twice which was causing a panic.

* Items are now only allowed to be freed by ng_apply_item().  NG_FREE_ITEM
  is kept for compatibility reasons but now it simply marks the item for
  deletion and asserts it was not marked already in order to detect
  double frees.

  Hold a reference on the item every time it is sent or forwarded.  When the
  recursion is finished we are finally allowed to free the item on
  ng_apply_item().  Prior to freeing the item, check it for a registered
  callback.

* Let recursion unwinding free the item, even in case of error.

* Go back to using a single item allocation pool, instead of separate data
  and message/function pools.  If there is a performance hit, we'll have to
  deal with it later.  Now, ng_realloc_item() simply changes the item type,
  without allocating a new one from the objcache.

Dragonfly-bug: http://bugs.dragonflybsd.org/issues/2549
sys/netgraph7/netgraph.h
sys/netgraph7/netgraph/ng_base.c
sys/netgraph7/netgraph2.h [new file with mode: 0644]
sys/netgraph7/socket/ng_socket.c