Date: Thu, 12 Feb 2009 17:57:28 +0000 (UTC) From: Randall Stewart <rrs@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-7@freebsd.org Subject: svn commit: r188524 - in stable/7/sys: . netinet Message-ID: <200902121757.n1CHvSVo062783@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: rrs Date: Thu Feb 12 17:57:28 2009 New Revision: 188524 URL: http://svn.freebsd.org/changeset/base/188524 Log: MFC of 182367 and 182403 - Make strict-sacks be the default. - Change it so that without INVARIANTs there are no panics in SCTP. - sctp_timer changes so that we have a recovery mechanism when the sent list is out of order. <AND> Fixes compile error when INVARIANTs is on. Adds an empty goto to keep the compiler happy. Modified: stable/7/sys/ (props changed) stable/7/sys/netinet/sctp_indata.c stable/7/sys/netinet/sctp_lock_bsd.h stable/7/sys/netinet/sctp_output.c stable/7/sys/netinet/sctp_sysctl.h stable/7/sys/netinet/sctp_timer.c stable/7/sys/netinet/sctp_timer.h stable/7/sys/netinet/sctp_var.h stable/7/sys/netinet/sctputil.c Modified: stable/7/sys/netinet/sctp_indata.c ============================================================================== --- stable/7/sys/netinet/sctp_indata.c Thu Feb 12 17:31:39 2009 (r188523) +++ stable/7/sys/netinet/sctp_indata.c Thu Feb 12 17:57:28 2009 (r188524) @@ -386,12 +386,21 @@ abandon: if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) { goto abandon; } else { +#ifdef INVARIANTS if ((stcb->asoc.control_pdapi == NULL) || (stcb->asoc.control_pdapi->tail_mbuf == NULL)) { panic("This should not happen control_pdapi NULL?"); } /* if we did not panic, it was a EOM */ panic("Bad chunking ??"); - return; +#else + if ((stcb->asoc.control_pdapi == NULL) || (stcb->asoc.control_pdapi->tail_mbuf == NULL)) { + SCTP_PRINTF("This should not happen control_pdapi NULL?\n"); + } + SCTP_PRINTF("Bad chunking ??\n"); + SCTP_PRINTF("Dumping re-assembly queue this will probably hose the association\n"); + +#endif + goto abandon; } } cntDel++; Modified: stable/7/sys/netinet/sctp_lock_bsd.h ============================================================================== --- stable/7/sys/netinet/sctp_lock_bsd.h Thu Feb 12 17:31:39 2009 (r188523) +++ stable/7/sys/netinet/sctp_lock_bsd.h Thu Feb 12 17:57:28 2009 (r188524) @@ -365,14 +365,20 @@ extern int sctp_logoff_stuff; do { \ atomic_add_int(&SCTP_BASE_INFO(ipi_count_chunk), 1); \ } while (0) - +#ifdef INVARIANTS #define SCTP_DECR_CHK_COUNT() \ do { \ if(SCTP_BASE_INFO(ipi_count_chunk) == 0) \ panic("chunk count to 0?"); \ atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_chunk), 1); \ } while (0) - +#else +#define SCTP_DECR_CHK_COUNT() \ + do { \ + if(SCTP_BASE_INFO(ipi_count_chunk) != 0) \ + atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_chunk), 1); \ + } while (0) +#endif #define SCTP_INCR_READQ_COUNT() \ do { \ atomic_add_int(&SCTP_BASE_INFO(ipi_count_readq),1); \ Modified: stable/7/sys/netinet/sctp_output.c ============================================================================== --- stable/7/sys/netinet/sctp_output.c Thu Feb 12 17:31:39 2009 (r188523) +++ stable/7/sys/netinet/sctp_output.c Thu Feb 12 17:57:28 2009 (r188524) @@ -11381,6 +11381,7 @@ sctp_send_operr_to(struct mbuf *m, int i struct ip *iph; struct udphdr *udp = NULL; struct mbuf *mout; + #ifdef INET6 #ifdef SCTP_DEBUG struct sockaddr_in6 lsa6, fsa6; Modified: stable/7/sys/netinet/sctp_sysctl.h ============================================================================== --- stable/7/sys/netinet/sctp_sysctl.h Thu Feb 12 17:31:39 2009 (r188523) +++ stable/7/sys/netinet/sctp_sysctl.h Thu Feb 12 17:57:28 2009 (r188524) @@ -152,7 +152,7 @@ struct sctp_sysctl { #define SCTPCTL_STRICT_SACKS_DESC "Enable SCTP Strict SACK checking" #define SCTPCTL_STRICT_SACKS_MIN 0 #define SCTPCTL_STRICT_SACKS_MAX 1 -#define SCTPCTL_STRICT_SACKS_DEFAULT 0 +#define SCTPCTL_STRICT_SACKS_DEFAULT 1 /* loopback_nocsum: Enable NO Csum on packets sent on loopback */ #define SCTPCTL_LOOPBACK_NOCSUM_DESC "Enable NO Csum on packets sent on loopback" Modified: stable/7/sys/netinet/sctp_timer.c ============================================================================== --- stable/7/sys/netinet/sctp_timer.c Thu Feb 12 17:31:39 2009 (r188523) +++ stable/7/sys/netinet/sctp_timer.c Thu Feb 12 17:57:28 2009 (r188524) @@ -561,6 +561,49 @@ sctp_backoff_on_timeout(struct sctp_tcb } } +void +sctp_recover_sent_list(struct sctp_tcb *stcb) +{ + struct sctp_tmit_chunk *chk, *tp2; + struct sctp_association *asoc; + + asoc = &stcb->asoc; + chk = TAILQ_FIRST(&stcb->asoc.sent_queue); + for (; chk != NULL; chk = tp2) { + tp2 = TAILQ_NEXT(chk, sctp_next); + if ((compare_with_wrap(stcb->asoc.last_acked_seq, + chk->rec.data.TSN_seq, + MAX_TSN)) || + (stcb->asoc.last_acked_seq == chk->rec.data.TSN_seq)) { + + SCTP_PRINTF("Found chk:%p tsn:%x <= last_acked_seq:%x\n", + chk, chk->rec.data.TSN_seq, stcb->asoc.last_acked_seq); + TAILQ_REMOVE(&asoc->sent_queue, chk, sctp_next); + if (chk->pr_sctp_on) { + if (asoc->pr_sctp_cnt != 0) + asoc->pr_sctp_cnt--; + } + if (chk->data) { + /* sa_ignore NO_NULL_CHK */ + sctp_free_bufspace(stcb, asoc, chk, 1); + sctp_m_freem(chk->data); + if (PR_SCTP_BUF_ENABLED(chk->flags)) { + asoc->sent_queue_cnt_removeable--; + } + } + chk->data = NULL; + asoc->sent_queue_cnt--; + sctp_free_a_chunk(stcb, chk); + } + } + SCTP_PRINTF("after recover order is as follows\n"); + chk = TAILQ_FIRST(&stcb->asoc.sent_queue); + for (; chk != NULL; chk = tp2) { + tp2 = TAILQ_NEXT(chk, sctp_next); + SCTP_PRINTF("chk:%p TSN:%x\n", chk, chk->rec.data.TSN_seq); + } +} + static int sctp_mark_all_for_resend(struct sctp_tcb *stcb, struct sctp_nets *net, @@ -583,6 +626,7 @@ sctp_mark_all_for_resend(struct sctp_tcb unsigned int cnt_mk; uint32_t orig_flight, orig_tf; uint32_t tsnlast, tsnfirst; + int recovery_cnt = 0; /* none in flight now */ @@ -635,6 +679,7 @@ sctp_mark_all_for_resend(struct sctp_tcb /* Now on to each chunk */ num_mk = cnt_mk = 0; tsnfirst = tsnlast = 0; +start_again: chk = TAILQ_FIRST(&stcb->asoc.sent_queue); for (; chk != NULL; chk = tp2) { tp2 = TAILQ_NEXT(chk, sctp_next); @@ -643,8 +688,22 @@ sctp_mark_all_for_resend(struct sctp_tcb MAX_TSN)) || (stcb->asoc.last_acked_seq == chk->rec.data.TSN_seq)) { /* Strange case our list got out of order? */ - SCTP_PRINTF("Our list is out of order?\n"); - panic("Out of order list"); + SCTP_PRINTF("Our list is out of order? last_acked:%x chk:%x", + (unsigned int)stcb->asoc.last_acked_seq, (unsigned int)chk->rec.data.TSN_seq); + recovery_cnt++; +#ifdef INVARIANTS + panic("last acked >= chk on sent-Q"); + /* to keep compiler happy */ + goto start_again; +#else + SCTP_PRINTF("Recover attempts a restart cnt:%d\n", recovery_cnt); + sctp_recover_sent_list(stcb); + if (recovery_cnt < 10) { + goto start_again; + } else { + SCTP_PRINTF("Recovery fails %d times??\n", recovery_cnt); + } +#endif } if ((chk->whoTo == net) && (chk->sent < SCTP_DATAGRAM_ACKED)) { /* Modified: stable/7/sys/netinet/sctp_timer.h ============================================================================== --- stable/7/sys/netinet/sctp_timer.h Thu Feb 12 17:31:39 2009 (r188523) +++ stable/7/sys/netinet/sctp_timer.h Thu Feb 12 17:57:28 2009 (r188524) @@ -99,6 +99,8 @@ void sctp_audit_retranmission_queue(stru void sctp_iterator_timer(struct sctp_iterator *it); +void sctp_recover_sent_list(struct sctp_tcb *stcb); + #endif #endif Modified: stable/7/sys/netinet/sctp_var.h ============================================================================== --- stable/7/sys/netinet/sctp_var.h Thu Feb 12 17:31:39 2009 (r188523) +++ stable/7/sys/netinet/sctp_var.h Thu Feb 12 17:57:28 2009 (r188524) @@ -160,6 +160,9 @@ extern struct pr_usrreqs sctp_usrreqs; } \ } +#ifdef INVARIANTS + + #define sctp_sbfree(ctl, stcb, sb, m) { \ uint32_t val; \ val = atomic_fetchadd_int(&(sb)->sb_cc,-(SCTP_BUF_LEN((m)))); \ @@ -186,6 +189,35 @@ extern struct pr_usrreqs sctp_usrreqs; } +#else + +#define sctp_sbfree(ctl, stcb, sb, m) { \ + uint32_t val; \ + val = atomic_fetchadd_int(&(sb)->sb_cc,-(SCTP_BUF_LEN((m)))); \ + if (val < SCTP_BUF_LEN((m))) { \ + (sb)->sb_cc = 0;\ + } \ + val = atomic_fetchadd_int(&(sb)->sb_mbcnt,-(MSIZE)); \ + if (val < MSIZE) { \ + (sb)->sb_mbcnt = 0; \ + } \ + if (((ctl)->do_not_ref_stcb == 0) && stcb) {\ + val = atomic_fetchadd_int(&(stcb)->asoc.sb_cc,-(SCTP_BUF_LEN((m)))); \ + if (val < SCTP_BUF_LEN((m))) {\ + (stcb)->asoc.sb_cc = 0; \ + } \ + val = atomic_fetchadd_int(&(stcb)->asoc.my_rwnd_control_len,-(MSIZE)); \ + if (val < MSIZE) { \ + (stcb)->asoc.my_rwnd_control_len = 0; \ + } \ + } \ + if (SCTP_BUF_TYPE(m) != MT_DATA && SCTP_BUF_TYPE(m) != MT_HEADER && \ + SCTP_BUF_TYPE(m) != MT_OOBDATA) \ + atomic_subtract_int(&(sb)->sb_ctl,SCTP_BUF_LEN((m))); \ +} + +#endif + #define sctp_sballoc(stcb, sb, m) { \ atomic_add_int(&(sb)->sb_cc,SCTP_BUF_LEN((m))); \ atomic_add_int(&(sb)->sb_mbcnt, MSIZE); \ Modified: stable/7/sys/netinet/sctputil.c ============================================================================== --- stable/7/sys/netinet/sctputil.c Thu Feb 12 17:31:39 2009 (r188523) +++ stable/7/sys/netinet/sctputil.c Thu Feb 12 17:57:28 2009 (r188524) @@ -922,7 +922,9 @@ sctp_init_asoc(struct sctp_inpcb *m, str asoc->my_vtag = override_tag; } else { SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ENOMEM); +#ifdef INVARIANTS panic("Huh is_in_timewait fails"); +#endif return (ENOMEM); } @@ -4848,6 +4850,7 @@ sctp_find_ifa_by_addr(struct sockaddr *a vrf = sctp_find_vrf(vrf_id); if (vrf == NULL) { +stage_right: if (holds_lock == 0) SCTP_IPI_ADDR_RUNLOCK(); return (NULL); @@ -4868,7 +4871,13 @@ sctp_find_ifa_by_addr(struct sockaddr *a } LIST_FOREACH(sctp_ifap, hash_head, next_bucket) { if (sctp_ifap == NULL) { +#ifdef INVARIANTS panic("Huh LIST_FOREACH corrupt"); + goto stage_right; +#else + SCTP_PRINTF("LIST corrupt of sctp_ifap's?\n"); + goto stage_right; +#endif } if (addr->sa_family != sctp_ifap->address.sa.sa_family) continue; @@ -5918,7 +5927,12 @@ out: * the atomic add to the refcnt. */ if (stcb == NULL) { +#ifdef INVARIANTS panic("stcb for refcnt has gone NULL?"); + goto stage_left; +#else + goto stage_left; +#endif } atomic_add_int(&stcb->asoc.refcnt, -1); freecnt_applied = 0; @@ -5940,6 +5954,7 @@ out: so->so_rcv.sb_cc); } } +stage_left: if (wakeup_read_socket) { sctp_sorwakeup(inp, so); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200902121757.n1CHvSVo062783>