if_clone: Extend if_clone_create() by an extra parameter Currently, if_clone_create() accepts one caddr_t parameter that is passed with the ifreq->ifr_data for the SIOCIFCREATE2 ioctl. Extend this function by another caddr_t parameter so that callers could pass extra data to the ifc->ifc_create() handler and won't conflict with the SIOCIFCREATE2 ioctl calls. This extension will be used by tun(4) and tap(4) in a following commit. Suggested-by: dillon Reviewed-by: dillon
ifnet: Make ifnet and ifindex2ifnet MPSAFE - Accessing to these two global variables from non-netisr threads uses ifnet lock. This kind of accessing is from - Accessing to ifindex2ifnet from netisrs are lockless MPSAFE. - Netisrs no longer access ifnet, instead they access ifnet array as of this commit, which is lockless MPSAFE. Rules for accessing ifnet and ifindex2ifnet is commented near the declaration of the related global variables/functions in net/if_var.h.
ifnet: Properly protect if_multiaddrs using ifnet serializers - Protect ifnet.if_multiaddrs using ifnet serializers. Add some comment in the places, where only main serailizer is necessary. - Fix if_delallmulti(). Using TAILQ_FOREACH_MUTABLE is incorrect for deleting an ifmultiaddr from ifnet.if_multiaddrs. Since deleting one ifmultiaddr may cause additional ifmultiaddr deletion (e.g. the AF_LINK ifmultiaddr for AF_INET ifmultiaddr). - Change IN_LOOKUP_MULTI and IN6_LOOKUP_MULTI macros into inline functions. - Redispatch multicast IP packets to netisr0 for further processing. Software based IP packet hash function is changed. And hash value fixup for multicast IP packets is added to the beginning of ip_input(); this is mainly for IP packets, whose hash is calculated by hardware. - For wlan's multicast hardware filter updating, we no longer need to release wlan serializer and mess up w/ the if_ioctl setting. In netisr0, read and test ifma_refcount for AF_INET ifmultiaddr is MPSAFE w/o ifnet serializers, since its ifma_refcount is only altered in netisr0. In netisr0, any operation on in_multi, which is obtained from the corresponding ifmuliaddr's ifma_protospec, is MPSAFE w/o ifnet serializers, since ifmultiaddr for AF_INET is only set and cleared in netisr0. While I'm here also redispatch IP packets w/o hash to the proper netisrs, on ip_input() path. And unnecessary critical sections in in_{add,del}multi() are removed.
ifsq: Let ifaltq_subque know its related hardware TX queue's serializer This avoids following operations on packet transmission hot path: - Dereferening device driver supplied serialize function pointers - Locating hardware TX queue's serializer Comparing to the lwkt_serialize functions, the above two operations are costful. Driver changes: - For device drivers which use the default ifnet serializer, no additional code will be needed, if_attach() will assign ifnet serializer to ifaltq_subque. - For device drivers which use independent serializers for main function, RX queues and TX queues, ifsq_set_hw_serialize() must be called to properly assign the hardware TX queue's serializer to ifaltq_subque. Drivers in this category are bce(4), emx(4), igb(4) and jme(4).
if: Multiple TX queue support step 1 of many; introduce ifaltq subqueue Put the plain queue information, e.g. queue header and tail, serializer, packet staging scoreboard and ifnet.if_start schedule netmsg etc. into its own structure (subqueue). ifaltq structure could have multiple of subqueues based on the count that drivers can specify. Subqueue's enqueue, dequeue, purging and states updating are protected by the subqueue's serializer, so for hardwares supporting multiple TX queues, contention on queuing operation could be greatly reduced. The subqueue is passed to if_start to let the driver know which hardware TX queue to work on. Only the related driver's TX queue serializer will be held, so for hardwares supporting multiple TX queues, contention on driver's TX queue serializer could be greatly reduced. Bunch of ifsq_ prefixed functions are added, which is used to perform various operations on subqueues. Commonly used ifq_ prefixed functions are still kept mainly for the drivers which do not support multiple TX queues (well, these functions also ease the netif/ convertion in this step :). All of the pseudo network devices under sys/net are converted to use the new subqueue operation. netproto/802_11 is converted too. igb(4) is converted to use the new subqueue operation, the rest of the network drivers are only changed for the if_start interface modification. For ALTQs which have packet scheduler enabled, only the first subqueue is used (*). (*) Whether we should utilize multiple TX queues if ALTQ's packet scheduler is enabled is quite questionable. Mainly because hardware's multiple TX queue packet dequeue mechanism could have negative impact on ALTQ's packet scheduler's decision.
if: Move if_cpuid into ifaltq; prepare multiple TX queues support if_cpuid and if_npoll_cpuid are merged and moved into ifaltq as altq_cpuid, which indicates the owner CPU of the tx queue. Since we already have code in if_start_dispatch() to catching tx queue owner CPU changes, this merging is quite safe.