Mercurial > illumos > illumos-gate
changeset 10212:1abfeb13f29b
PSARC 2009/411 API for per endpoint sctp statistics.
6808307 need access to the included SCTP counters
author | George Shepherd <George.Shepherd@Sun.COM> |
---|---|
date | Thu, 30 Jul 2009 10:07:41 -0700 |
parents | 8b17464a5cbb |
children | 167616def81b |
files | usr/src/uts/common/inet/sctp/sctp_asconf.c usr/src/uts/common/inet/sctp/sctp_common.c usr/src/uts/common/inet/sctp/sctp_impl.h usr/src/uts/common/inet/sctp/sctp_input.c usr/src/uts/common/inet/sctp/sctp_opt_data.c usr/src/uts/common/inet/sctp/sctp_output.c usr/src/uts/common/inet/sctp/sctp_timer.c usr/src/uts/common/netinet/sctp.h |
diffstat | 8 files changed, 127 insertions(+), 14 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/uts/common/inet/sctp/sctp_asconf.c Thu Jul 30 09:40:30 2009 -0600 +++ b/usr/src/uts/common/inet/sctp/sctp_asconf.c Thu Jul 30 10:07:41 2009 -0700 @@ -881,7 +881,7 @@ fp->strikes++; sctp->sctp_strikes++; - SCTP_CALC_RXT(fp, sctp->sctp_rto_max); + SCTP_CALC_RXT(sctp, fp); nfp = sctp_rotate_faddr(sctp, fp); sctp->sctp_cchunk_pend = 0;
--- a/usr/src/uts/common/inet/sctp/sctp_common.c Thu Jul 30 09:40:30 2009 -0600 +++ b/usr/src/uts/common/inet/sctp/sctp_common.c Thu Jul 30 10:07:41 2009 -0700 @@ -203,6 +203,7 @@ if (fp->rto > sctp->sctp_rto_max) { fp->rto = sctp->sctp_rto_max; } + SCTP_MAX_RTO(sctp, fp); } /* @@ -1864,6 +1865,7 @@ } fp->cwnd = sctps->sctps_slow_start_initial * fp->sfa_pmss; fp->rto = MIN(sctp->sctp_rto_initial, sctp->sctp_init_rto_max); + SCTP_MAX_RTO(sctp, fp); fp->srtt = -1; fp->rtt_updates = 0; fp->strikes = 0;
--- a/usr/src/uts/common/inet/sctp/sctp_impl.h Thu Jul 30 09:40:30 2009 -0600 +++ b/usr/src/uts/common/inet/sctp/sctp_impl.h Thu Jul 30 10:07:41 2009 -0700 @@ -167,10 +167,24 @@ (fp)->timer_running = 0; \ } -#define SCTP_CALC_RXT(fp, max) \ -{ \ - if (((fp)->rto <<= 1) > (max)) \ - (fp)->rto = (max); \ +/* For per endpoint association statistics */ +#define SCTP_MAX_RTO(sctp, fp) { \ + /* \ + * Record the maximum observed RTO, \ + * sctp_maxrto is zeroed elsewhere \ + * at the end of each stats request. \ + */ \ + (sctp)->sctp_maxrto = \ + MAX((sctp)->sctp_maxrto, (fp)->rto); \ + DTRACE_PROBE2(sctp__maxrto, sctp_t *, \ + sctp, struct sctp_faddr_s, fp); \ +} + +#define SCTP_CALC_RXT(sctp, fp) \ +{ \ + if (((fp)->rto <<= 1) > (sctp)->sctp_rto_max) \ + (fp)->rto = (sctp)->sctp_rto_max; \ + SCTP_MAX_RTO(sctp, fp); \ } @@ -938,6 +952,25 @@ pid_t sctp_cpid; /* Process id when this was opened */ uint64_t sctp_open_time; /* time when this was opened */ + + /* additional source data for per endpoint association statistics */ + uint64_t sctp_outseqtsns; /* TSN rx > expected TSN */ + uint64_t sctp_osacks; /* total sacks sent */ + uint64_t sctp_isacks; /* total sacks received */ + uint64_t sctp_idupchunks; /* rx dups, ord or unord */ + uint64_t sctp_gapcnt; /* total gap acks rx */ + + /* + * When non-zero, this is the maximum observed RTO since assoc stats + * were last requested. When zero, no RTO update has occurred since + * the previous user request for stats on this endpoint. + */ + int sctp_maxrto; + /* + * The stored value of sctp_maxrto passed to user during the previous + * user request for stats on this endpoint. + */ + int sctp_prev_maxrto; } sctp_t; #define SCTP_TXQ_LEN(sctp) ((sctp)->sctp_unsent + (sctp)->sctp_unacked)
--- a/usr/src/uts/common/inet/sctp/sctp_input.c Thu Jul 30 09:40:30 2009 -0600 +++ b/usr/src/uts/common/inet/sctp/sctp_input.c Thu Jul 30 10:07:41 2009 -0700 @@ -1201,6 +1201,7 @@ (sctp)->sctp_force_sack = 1; \ } else if (SEQ_GT(tsn, sctp->sctp_ftsn)) { \ /* Got a gap; record it */ \ + BUMP_LOCAL(sctp->sctp_outseqtsns); \ dprint(2, ("data_chunk: acking gap %x\n", tsn)); \ sctp_ack_add(&sctp->sctp_sack_info, tsn, \ &sctp->sctp_sack_gaps); \ @@ -1217,6 +1218,7 @@ /* Check for duplicates */ if (SEQ_LT(tsn, sctp->sctp_ftsn)) { dprint(4, ("sctp_data_chunk: dropping duplicate\n")); + BUMP_LOCAL(sctp->sctp_idupchunks); sctp->sctp_force_sack = 1; sctp_add_dup(dc->sdh_tsn, dups); return; @@ -1230,6 +1232,7 @@ dprint(4, ("sctp_data_chunk: dropping dup > " "cumtsn\n")); + BUMP_LOCAL(sctp->sctp_idupchunks); sctp->sctp_force_sack = 1; sctp_add_dup(dc->sdh_tsn, dups); return; @@ -1617,6 +1620,7 @@ } BUMP_LOCAL(sctp->sctp_obchunks); + BUMP_LOCAL(sctp->sctp_osacks); } mblk_t * @@ -2514,6 +2518,7 @@ sctp_stack_t *sctps = sctp->sctp_sctps; BUMP_LOCAL(sctp->sctp_ibchunks); + BUMP_LOCAL(sctp->sctp_isacks); chunklen = ntohs(sch->sch_len); if (chunklen < (sizeof (*sch) + sizeof (*sc))) return (0); @@ -2574,6 +2579,7 @@ */ fp = sctp->sctp_current; fp->rto = fp->srtt + 4 * fp->rttvar; + SCTP_MAX_RTO(sctp, fp); /* Resend the ZWP */ pkt = sctp_rexmit_packet(sctp, &meta, &mp1, fp, &pkt_len); @@ -2596,6 +2602,7 @@ */ fp = sctp->sctp_current; fp->rto = fp->srtt + 4 * fp->rttvar; + SCTP_MAX_RTO(sctp, fp); sctp->sctp_zero_win_probe = B_FALSE; /* This is probably not required */ if (!sctp->sctp_rexmitting) { @@ -2615,6 +2622,7 @@ } } num_gaps = ntohs(sc->ssc_numfrags); + UPDATE_LOCAL(sctp->sctp_gapcnt, num_gaps); if (num_gaps == 0 || mp == NULL || !SCTP_CHUNK_ISSENT(mp) || chunklen < (sizeof (*sch) + sizeof (*sc) + num_gaps * sizeof (*ssf))) {
--- a/usr/src/uts/common/inet/sctp/sctp_opt_data.c Thu Jul 30 09:40:30 2009 -0600 +++ b/usr/src/uts/common/inet/sctp/sctp_opt_data.c Thu Jul 30 10:07:41 2009 -0700 @@ -884,6 +884,53 @@ case SCTP_PRSCTP: *i1 = sctp->sctp_prsctp_aware ? 1 : 0; break; + + case SCTP_GET_ASSOC_STATS: { + sctp_assoc_stats_t *sas; + + if (buflen < sizeof (sctp_assoc_stats_t)) { + retval = EINVAL; + break; + } + + sas = (sctp_assoc_stats_t *)ptr; + + /* + * Copy the current stats to the stats struct. + */ + sas->sas_rtxchunks = sctp->sctp_rxtchunks; + sas->sas_gapcnt = sctp->sctp_gapcnt; + sas->sas_outseqtsns = sctp->sctp_outseqtsns; + sas->sas_osacks = sctp->sctp_osacks; + sas->sas_isacks = sctp->sctp_isacks; + sas->sas_octrlchunks = sctp->sctp_obchunks; + sas->sas_ictrlchunks = sctp->sctp_ibchunks; + sas->sas_oodchunks = sctp->sctp_odchunks; + sas->sas_iodchunks = sctp->sctp_idchunks; + sas->sas_ouodchunks = sctp->sctp_oudchunks; + sas->sas_iuodchunks = sctp->sctp_iudchunks; + sas->sas_idupchunks = sctp->sctp_idupchunks; + + /* + * Copy out the maximum observed RTO since the + * time this data was last requested + */ + if (sctp->sctp_maxrto == 0) { + /* unchanged during obervation period */ + sas->sas_maxrto = sctp->sctp_prev_maxrto; + } else { + /* record new period maximum */ + sas->sas_maxrto = sctp->sctp_maxrto; + } + /* Record the value sent to the user this period */ + sctp->sctp_prev_maxrto = sas->sas_maxrto; + + /* Mark beginning of a new observation period */ + sctp->sctp_maxrto = 0; + + *optlen = sizeof (sctp_assoc_stats_t); + break; + } case SCTP_I_WANT_MAPPED_V4_ADDR: case SCTP_MAXSEG: case SCTP_DISABLE_FRAGMENTS:
--- a/usr/src/uts/common/inet/sctp/sctp_output.c Thu Jul 30 09:40:30 2009 -0600 +++ b/usr/src/uts/common/inet/sctp/sctp_output.c Thu Jul 30 10:07:41 2009 -0700 @@ -1817,7 +1817,7 @@ oldfp->strikes++; sctp->sctp_strikes++; - SCTP_CALC_RXT(oldfp, sctp->sctp_rto_max); + SCTP_CALC_RXT(sctp, oldfp); if (oldfp != fp && oldfp->suna != 0) SCTP_FADDR_TIMER_RESTART(sctp, oldfp, fp->rto); SCTP_FADDR_TIMER_RESTART(sctp, fp, fp->rto); @@ -2032,7 +2032,7 @@ restart_timer: oldfp->strikes++; sctp->sctp_strikes++; - SCTP_CALC_RXT(oldfp, sctp->sctp_rto_max); + SCTP_CALC_RXT(sctp, oldfp); /* * If there is still some data in the oldfp, restart the * retransmission timer. If there is no data, the heartbeat will
--- a/usr/src/uts/common/inet/sctp/sctp_timer.c Thu Jul 30 09:40:30 2009 -0600 +++ b/usr/src/uts/common/inet/sctp/sctp_timer.c Thu Jul 30 10:07:41 2009 -0700 @@ -20,7 +20,7 @@ */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -506,8 +506,7 @@ sctp->sctp_rto_initial; goto dead_addr; } else { - SCTP_CALC_RXT(fp, - sctp->sctp_rto_max); + SCTP_CALC_RXT(sctp, fp); fp->hb_expiry = now + fp->rto; } break; @@ -571,7 +570,6 @@ sctp_rexmit_timer(sctp_t *sctp, sctp_faddr_t *fp) { mblk_t *mp; - uint32_t rto_max = sctp->sctp_rto_max; sctp_stack_t *sctps = sctp->sctp_sctps; ASSERT(fp != NULL); @@ -649,7 +647,6 @@ BUMP_MIB(&sctps->sctps_mib, sctpTimRetrans); sctp_add_sendq(sctp, mp); } - rto_max = sctp->sctp_init_rto_max; break; case SCTPS_COOKIE_ECHOED: { ipha_t *iph; @@ -668,7 +665,6 @@ iph->ipha_ident = 0; sctp_add_sendq(sctp, mp); BUMP_MIB(&sctps->sctps_mib, sctpTimRetrans); - rto_max = sctp->sctp_init_rto_max; break; } case SCTPS_SHUTDOWN_SENT: @@ -693,7 +689,7 @@ fp->strikes++; sctp->sctp_strikes++; - SCTP_CALC_RXT(fp, rto_max); + SCTP_CALC_RXT(sctp, fp); SCTP_FADDR_TIMER_RESTART(sctp, fp, fp->rto); } @@ -744,6 +740,7 @@ fp->rto = sctp->sctp_rto_max; } + SCTP_MAX_RTO(sctp, fp); fp->rtt_updates++; }
--- a/usr/src/uts/common/netinet/sctp.h Thu Jul 30 09:40:30 2009 -0600 +++ b/usr/src/uts/common/netinet/sctp.h Thu Jul 30 10:07:41 2009 -0700 @@ -79,6 +79,11 @@ #define SCTP_PRSCTP 23 /* + * SCTP socket option used to read per endpoint association statistics. + */ +#define SCTP_GET_ASSOC_STATS 24 + +/* * Ancillary data identifiers */ #define SCTP_SNDRCV 0x100 @@ -481,6 +486,27 @@ }; /* + * A socket user request reads local per endpoint association stats. + * All stats are counts except sas_maxrto, which is the max value + * since the last user request for stats on this endpoint. + */ +typedef struct sctp_assoc_stats { + uint64_t sas_rtxchunks; /* Retransmitted Chunks */ + uint64_t sas_gapcnt; /* Gap Acknowledgements Received */ + uint64_t sas_maxrto; /* Maximum Observed RTO this period */ + uint64_t sas_outseqtsns; /* TSN received > next expected */ + uint64_t sas_osacks; /* SACKs sent */ + uint64_t sas_isacks; /* SACKs received */ + uint64_t sas_octrlchunks; /* Control chunks sent - no dups */ + uint64_t sas_ictrlchunks; /* Control chunks received - no dups */ + uint64_t sas_oodchunks; /* Ordered data chunks sent */ + uint64_t sas_iodchunks; /* Ordered data chunks received */ + uint64_t sas_ouodchunks; /* Unordered data chunks sent */ + uint64_t sas_iuodchunks; /* Unordered data chunks received */ + uint64_t sas_idupchunks; /* Dups received (ordered+unordered) */ +} sctp_assoc_stats_t; + +/* * Private ioctl option structure */ struct sctpopt {