On Tue, May 28, 2019 at 3:24 PM Fred Klassen <fklassen@xxxxxxxxxxx> wrote: > > This enhancement adds options that facilitate load testing with > additional TX CMSG options, and to optionally print results of > various send CMSG operations. > > These options are especially useful in isolating situations > where error-queue messages are lost when combined with other > CMSG operations (e.g. SO_ZEROCOPY). > > New options: > > -a - count all CMSG messages and match to sent messages > -T - add TX CMSG that requests TX software timestamps > -H - similar to -T except request TX hardware timestamps > -P - call poll() before reading error queue > -v - print detailed results > > v2: Enhancements as per Willem de Bruijn <willemb@xxxxxxxxxx> > - Updated control and buffer parameters for recvmsg > - poll() parameter cleanup > - fail on bad audit results > - remove TOS options > - improved reporting > > Signed-off-by: Fred Klassen <fklassen@xxxxxxxxxxx> > --- > +static void flush_cmsg(struct cmsghdr *cmsg) > { > - struct msghdr msg = {0}; /* flush */ > + switch (cmsg->cmsg_level) { > + case SOL_SOCKET: > + if (cmsg->cmsg_type == SO_TIMESTAMPING) { > + int i; > + > + i = (cfg_tx_ts == SOF_TIMESTAMPING_TX_HARDWARE) ? 2 : 0; > + struct scm_timestamping *tss; > + > + tss = (struct scm_timestamping *)CMSG_DATA(cmsg); > + if (tss->ts[i].tv_sec == 0) > + stat_tx_ts_errors++; > + } else { > + error(1, 0, > + "unknown SOL_SOCKET cmsg type=%u level=%u\n", > + cmsg->cmsg_type, cmsg->cmsg_level); > + } > + break; > + case SOL_IP: > + case SOL_IPV6: > + switch (cmsg->cmsg_type) { > + case IP_RECVERR: > + case IPV6_RECVERR: > + { > + struct sock_extended_err *err; > + > + err = (struct sock_extended_err *)CMSG_DATA(cmsg); > + switch (err->ee_origin) { > + case SO_EE_ORIGIN_TIMESTAMPING: > + // Got a TX timestamp from error queue > + stat_tx_ts++; > + break; > + case SO_EE_ORIGIN_ICMP: > + case SO_EE_ORIGIN_ICMP6: > + if (cfg_verbose) > + fprintf(stderr, > + "received ICMP error: type=%u, code=%u\n", > + err->ee_type, err->ee_code); > + break; > + case SO_EE_ORIGIN_ZEROCOPY: > + { > + __u32 lo = err->ee_info; > + __u32 hi = err->ee_data; > + > + if (hi == lo - 1) { > + // TX was aborted > + stat_zcopy_errors++; > + if (cfg_verbose) > + fprintf(stderr, > + "Zerocopy TX aborted: lo=%u hi=%u\n", > + lo, hi); > + } else if (hi == lo) { > + // single ID acknowledged > + stat_zcopies++; > + } else { > + // range of IDs acknowledged > + stat_zcopies += hi - lo + 1; > + } > + break; > + } > + case SO_EE_ORIGIN_LOCAL: > + if (cfg_verbose) > + fprintf(stderr, > + "received packet with local origin: %u\n", > + err->ee_origin); > + break; > + default: > + error(0, 1, here and two following, error(1, 0, ..); > + "received packet with origin: %u", > + err->ee_origin); > + } > + > + break; > + } > + default: > + error(0, 1, "unknown IP msg type=%u level=%u\n", > + cmsg->cmsg_type, cmsg->cmsg_level); > + break; > + } > + break; > + default: > + error(0, 1, "unknown cmsg type=%u level=%u\n", > + cmsg->cmsg_type, cmsg->cmsg_level); > + } > +}