A. Background Relevant background Multidata 2 information (in the materials directory): "Multidata V.2: VA-Disjoint Packet Extents Framework Interface Design Specification" (mmd2.pdf) This case is dependent on the following cases: PSARC 2002/276 - TCP Multi-Data Transmit PSARC 2003/263 - DL_CAPABILITY-ignorant intermediate module detection B. Problem The original Multidata interface specification [1] limits the number of payload buffer to at most one per M_MULTIDATA message. While this is adequate for packets whose payload areas are contained within the corresponding payload buffers, it does not work well for those which span across disjoint ones (e.g. an IP packet containing a TCP segment whose areas extend beyond a payload buffer into the next, both of which are disjointed apart at the virtual address spaces). See the above background materials and bugid 4801229 for more details. C. Solution This fast-track proposal introduces minor modifications to the original interfaces, in order to allow for more than one VA-contiguous payload buffers per Multidata, as well as to further refine their usage model. The requested release binding is Minor. Stability level of the new interfaces is Consolidation Private, with the expectation that it will become Contracted Consolidation Private once contracts appear with the appropriate driver groups are finalized. Newly Exported Interfaces: +-----------------------+----------------------------------+-----------------+ |Interface | Classification | Comments | |-----------------------+----------------------------------+-----------------| |MULTIDATA_MAX_PBUFS | Consolidation Private | sys/multidata.h | |PDESC_HDR_ADD | Consolidation Private | sys/multidata.h | |PDESC_PLD_INIT | Consolidation Private | sys/multidata.h | |PDESC_PLD_SPAN_SIZE | Consolidation Private | sys/multidata.h | |PDESC_PLDL | Consolidation Private | sys/multidata.h | |PDESC_PLD_SPAN_TRIM | Consolidation Private | sys/multidata.h | |PDESC_PLD_SPAN_CLEAR | Consolidation Private | sys/multidata.h | |PDESC_PLD_SPAN_ADD | Consolidation Private | sys/multidata.h | |mmd_addpldbuf | Consolidation Private | sys/multidata.h | |mmd_transform_link | Consolidation Private | sys/multidata.h | |mmd_getsize | Consolidation Private | sys/multidata.h | +-----------------------+----------------------------------+-----------------+ Modified Exported Interfaces: +-----------------------+----------------------------------+-----------------+ |Interface | Classification | Comments | |-----------------------+----------------------------------+-----------------| |MDT_CURRENT_VERSION | Consolidation Private | sys/dlpi.h | |struct dl_capab_mdt_t | Consolidation Private | sys/dlpi.h | | | | | |struct gld_mac_info_t | Consolidation Private | sys/gld.h | | | | | |struct mbufinfo_t | Consolidation Private | sys/multidata.h | |struct pdescinfo_t | Consolidation Private | sys/multidata.h | |PDESC_PLDSIZE | Consolidation Private | sys/multidata.h | |PDESC_PLDL | Consolidation Private | sys/multidata.h | |mmd_alloc() | Consolidation Private | sys/multidata.h | |mmd_getregions() | Consolidation Private | sys/multidata.h | |mmd_getcnt() | Consolidation Private | sys/multidata.h | |mmd_addpdesc() | Consolidation Private | sys/multidata.h | |mmd_adjpdesc() | Consolidation Private | sys/multidata.h | |mmd_transform() | Consolidation Private | sys/multidata.h | |mmd_addpattr() | Consolidation Private | sys/multidata.h | +-----------------------+----------------------------------+-----------------+ Imported Interfaces: +-----------------------+----------------------------------+-----------------+ |Interface | Classification | Comments | |-----------------------+----------------------------------+-----------------| |dl_mid_t | Consolidation Private | PSARC 2003/263 | +-----------------------+----------------------------------+-----------------+ Changes in , #define MDT_CURRENT_VERSION 0x02 #define MDT_VERSION_2 0x02 /* * Multidata Transmit sub-capability (follows dl_capability_sub_t) */ typedef struct { t_uscalar_t mdt_version; /* interface version */ t_uscalar_t mdt_flags; /* flags */ t_uscalar_t mdt_hdr_head; /* minimum leading header space */ t_uscalar_t mdt_hdr_tail; /* minimum trailing header space */ t_uscalar_t mdt_max_pld; /* maximum doable payload buffers */ t_uscalar_t mdt_span_limit; /* maximum per-packet span */ dl_mid_t mdt_mid; /* module ID token */ } dl_capab_mdt_t; /* * Additional values for flags */ #define DL_CAPAB_MDT_TCPSO 0x010 /* TCP/IPv4 segmentation offload */ #define DL_CAPAB_MDT_TCPSO_V6 0x020 /* TCP/IPv6 segmentation offload */ Changes in , typedef struct gld_mac_info { ... int gldm_mdt_sgl; /* SET BY DRIVER */ int gldm_mdt_segs; /* SET BY DRIVER */ } gld_mac_info_t; Changes in , /* * Maximum number of payload areas for a single packet descriptor. */ #define MULTIDATA_MAX_PBUFS 16 /* * Multidata buffer information. */ typedef struct mbufinfo_s { uchar_t *hbuf_rptr; /* start address of header buffer */ uchar_t *hbuf_wptr; /* end address of header buffer */ uint_t pbuf_cnt; /* number of payload buffer */ struct pbuf_ary_s { uchar_t *pbuf_rptr; /* start address of payload buffer */ uchar_t *pbuf_wptr; /* end address of payload buffer */ } pbuf_ary[MULTIDATA_MAX_PBUFS]; } mbufinfo_t; /* * Multidata packet descriptor information. */ typedef struct pdescinfo_s { uint_t flags; /* misc. flags */ uchar_t *hdr_base; /* start address of header area */ uchar_t *hdr_rptr; /* start address of header data */ uchar_t *hdr_wptr; /* end address of header data */ uchar_t *hdr_lim; /* end address of header area */ uint_t pld_cnt; /* number of payload area */ struct pld_ary_s { int pld_pbuf_idx; /* payload buffer index */ uchar_t *pld_rptr; /* start address of payload data */ uchar_t *pld_wptr; /* pointer to end of payload data */ } pld_ary[MULTIDATA_MAX_PBUFS]; } pdescinfo_t; #define PDESC_HDR_ADD(p, base, head, len, tail) { \ (p)->hdr_base = (base); \ (p)->hdr_rptr = (base) + (head); \ (p)->hdr_wptr = (p)->hdr_rptr + (len); \ (p)->hdr_lim = (p)->hdr_wptr + (tail); \ } #define PDESC_PLD_INIT(p) ((p)->pld_cnt = 0) #define PDESC_PLD_SPAN_SIZE(p, n) \ ((p)->pld_ary[(n)].pld_wptr - (p)->pld_ary[(n)].pld_rptr) #define PDESC_PLDL(p, n) PDESC_PLD_SPAN_SIZE(p, n) #define PDESC_PLD_SPAN_TRIM(p, n, b) { \ ((p)->pld_ary[(n)].pld_wptr -= (b)); \ ASSERT((p)->pld_ary[(n)].pld_wptr >= (p)->pld_ary[(n)].pld_rptr); \ } #define PDESC_PLD_SPAN_CLEAR(p, n) \ PDESC_PLD_SPAN_TRIM(p, n, PDESC_PLD_SPAN_SIZE(p, n)) #define PDESC_PLD_SPAN_ADD(p, pbuf_idx, rptr, len) { \ ASSERT((p)->pld_cnt < MULTIDATA_MAX_PBUFS); \ (p)->pld_ary[(p)->pld_cnt].pld_pbuf_idx = (pbuf_idx); \ (p)->pld_ary[(p)->pld_cnt].pld_rptr = (rptr); \ (p)->pld_ary[(p)->pld_cnt].pld_wptr = (rptr) + (len); \ (p)->pld_cnt++; \ } extern multidata_t *mmd_alloc(mblk_t *, mblk_t **, int); extern int mmd_addpldbuf(multidata_t *, mblk_t *); extern void mmd_getregions(multidata_t *, mbufinfo_t *); extern uint_t mmd_getcnt(multidata_t *, uint_t *, uint_t *); extern pdesc_t *mmd_addpdesc(multidata_t *, pdescinfo_t *, int *, int); extern pdesc_t *mmd_adjpdesc(pdesc_t *, pdescinfo_t *); extern mblk_t *mmd_transform(pdesc_t *); extern mblk_t *mmd_transform_link(pdesc_t *); extern pattr_t *mmd_addpattr(multidata_t *, pdesc_t *, pattrinfo_t *, boolean_t, int); extern void mmd_getsize(multidata_t *, uint_t *, uint_t *); D. References [1] Masputra. Multidata Interface Design Specification. Sep 2002. http://sac.sfbay/PSARC/2002/276/materials/mmd.pdf. [2] Masputra, DiMambro, Poon. An efficient networking transmit mechanism for Solaris: Multi-Data Transmit (MDT). May 2002. http://sac.sfbay/PSARC/2002/276/materials/mdt.pdf.