udp: Dispatch UDP datagrams to the correct netisr to perform ip_output()
authorSepherosa Ziehau <sephe@dragonflybsd.org>
Sat, 7 Jun 2014 13:17:08 +0000 (21:17 +0800)
committerSepherosa Ziehau <sephe@dragonflybsd.org>
Sat, 7 Jun 2014 13:17:08 +0000 (21:17 +0800)
commit1fe8db0691fe8eab833b067336afd654ac7f8cfc
tree27268e3db40c206663176b4478b38b3434811967
parentb1a3a57cbd213f8bc9b51bf6f3bd59511910cb21
udp: Dispatch UDP datagrams to the correct netisr to perform ip_output()

Redispatch UDP datagrams to the netisr, whose owner CPU matches the
UDP datagrams hash, to do the ip_output().  As measured bt KTR, the
udp_send() spends most of its time in ip_output().

To properly support this, following stuffs are added/changed:
- Add a network private lwkt message flag to indicate the so_port of
  the netmsg should not be matched against the current netisr's msgport.
  This flag is set when we redispatch the UDP datagrams to other netisrs.
- Don't use priority messages for netisr barrier, so at UDP socket close
  time, UDP datagrams pending on other netisr msgport could be properly
  sync'ed.

The UDP datagrams redispatch itself:
- If IP options are ever configured (supposely none), a copy of it will
  be carried along w/ the UDP datagram to the target netisr.  The copy
  is made mainly because it is not safe to access the IP options of the
  inpcb in netisr which does not own the inpcb.
  (*) On the other hand accessing inpcb's multicast options is safe since
  multicast UDP datagrams output and multicast options configuration all
  happen in netisr0.
- Add nm_priv into netmsg_pru_send, which saves flags to be passed to
  ip_output() for the UDP datagram.  This does not changes the size of
  netmsg_pru_send on x86_64 due to the implicit 4bytes padding.
- udp_addrcpu_pkt() is added to calculate the "real" CPU for the UDP
  datagrams.
- Don't use inpcb route cache for redispatched UDP datagrams.  Since:
  o  The cached route is usually not for the UDP datagrams' destination.
  o  Accessing inpcb route cache in the netisr, which is not the owner
     of the inpcb is not safe.

On i7-3770 w/ 82599ES, this increases 18bytes UDP request/response
performance by ~19% (1.12M trasactions/s  ---> 1.34M transactions/s)

This commit also makes lockless firewall state table doable, since input
and output of UDP datagrams, which have same hash, are running in the
same netisr now!
sys/net/netisr.c
sys/net/netmsg.h
sys/netinet/ip_demux.c
sys/netinet/udp_usrreq.c
sys/netinet/udp_var.h