I'm submitting the following fast-track on behalf of Paul Durrant at SolarFlare, who has done some interesting performance work with 10G ethernet.
Template Version: @(#)sac_nextcase 1.66 04/17/08 SMI This information is Copyright 2008 Sun Microsystems 1. Introduction 1.1. Project/Component Working Name: xesballoc: enhanced esballoc 1.2. Name of Document Author/Supplier: Author: Paul Durrant 1.3 Date of This Document: 21 August, 2008 4. Technical Description PROBLEM A high performance NIC driver needs to avoid copying data wherever possible. Thus, it is common on the receive path to encapsulate DMA buffers in a STREAMS block so that they may be passed directly up the stack. The primitive normally used to do this is desballoc(9F). When such a block is freed a callback into the driver is made. This callback is specified by the frtn_t structure: typedef struct free_rtn { void (*free_func)(); caddr_t free_arg; } frtn_t; that was passed to desballoc(9F), and can be used to recover the block that was encapsulated and recycle it. Unfortunately the encapsulating STREAMS block is always freed; so the first action of the driver is usually to allocate a new one, which leads to extra CPU overhead and kmem cache thrashing. SOLUTION We propose a new primitive xesballoc(), which is a variant of desballoc(9F). The semantics of the function itself are identical however the function specified in the frtn_t structure is subtley different. For blocks allocated using desballoc(9f) frtn_t.free_func() is passed a single argumnent: frtn_t.free_arg, effectively giving it a type of: void (*free_func)(caddr_t) For blocks allocated using xesballoc() frtn_t.free_func will be passed a second argument, a pointer to a boolean_t, effectively giving it a type of: void (*free_func)(caddr_t, boolean_t *) If the driver does not modify the boolean then it remains B_FALSE. In this case the STREAMS block will be freed when free_func() returns, as is the case with blocks allocated using desballoc(9F). However, if the driver sets the boolean to B_TRUE then the STREAMS block will not be freed and it is assumed that the driver will recycle this too. NOTES It should be noted that drivers using xesballoc() or desballoc(9F) must be careful not to assume references to the original mblk_t returned by function will be valid when frtn_t.free_func() is called since there is no guarantee that the STREAMS block has not been dupb()ed and the original mblk_t freed. It is guaranteed that the dblk_t will be the same and so the mblk_t should always be accessed via the db_mblk field of the dblk_t to ensure a valid reference. Clearly this point is not so crucial for consumers of desballoc(9F) since the STREAMS block was always freed immediately after the call to frtn_t.free_func(). 6. Resources and Schedule 6.4. Steering Committee requested information 6.4.1. Consolidation C-team Name: ON 6.5. ARC review type: FastTrack 6.6. ARC Exposure: open