From owner-svn-src-all@FreeBSD.ORG Sun May 8 09:11:59 2011 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 92184106566B; Sun, 8 May 2011 09:11:59 +0000 (UTC) (envelope-from tuexen@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 8382C8FC08; Sun, 8 May 2011 09:11:59 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id p489Bx5U037827; Sun, 8 May 2011 09:11:59 GMT (envelope-from tuexen@svn.freebsd.org) Received: (from tuexen@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id p489BxTW037814; Sun, 8 May 2011 09:11:59 GMT (envelope-from tuexen@svn.freebsd.org) Message-Id: <201105080911.p489BxTW037814@svn.freebsd.org> From: Michael Tuexen Date: Sun, 8 May 2011 09:11:59 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r221627 - head/sys/netinet X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 08 May 2011 09:11:59 -0000 Author: tuexen Date: Sun May 8 09:11:59 2011 New Revision: 221627 URL: http://svn.freebsd.org/changeset/base/221627 Log: Fix a locking issue showing up on Mac OS X when subscribing to authentication events. DTLS/SCTP renegotiations trigger the bug. MFC after: 2 weeks. Modified: head/sys/netinet/sctp_auth.c head/sys/netinet/sctp_auth.h head/sys/netinet/sctp_indata.c head/sys/netinet/sctp_input.c head/sys/netinet/sctp_input.h head/sys/netinet/sctp_output.c head/sys/netinet/sctp_output.h head/sys/netinet/sctp_pcb.c head/sys/netinet/sctp_timer.c head/sys/netinet/sctp_usrreq.c head/sys/netinet/sctp_var.h head/sys/netinet/sctputil.c Modified: head/sys/netinet/sctp_auth.c ============================================================================== --- head/sys/netinet/sctp_auth.c Sun May 8 09:11:04 2011 (r221626) +++ head/sys/netinet/sctp_auth.c Sun May 8 09:11:59 2011 (r221627) @@ -598,7 +598,11 @@ sctp_auth_key_acquire(struct sctp_tcb *s } void -sctp_auth_key_release(struct sctp_tcb *stcb, uint16_t key_id) +sctp_auth_key_release(struct sctp_tcb *stcb, uint16_t key_id, int so_locked +#if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING) + SCTP_UNUSED +#endif +) { sctp_sharedkey_t *skey; @@ -616,7 +620,7 @@ sctp_auth_key_release(struct sctp_tcb *s if ((skey->refcount <= 1) && (skey->deactivated)) { /* notify ULP that key is no longer used */ sctp_ulp_notify(SCTP_NOTIFY_AUTH_FREE_KEY, stcb, - key_id, 0, SCTP_SO_LOCKED); + key_id, 0, so_locked); SCTPDBG(SCTP_DEBUG_AUTH2, "%s: stcb %p key %u no longer used, %d\n", __FUNCTION__, stcb, key_id, skey->refcount); Modified: head/sys/netinet/sctp_auth.h ============================================================================== --- head/sys/netinet/sctp_auth.h Sun May 8 09:11:04 2011 (r221626) +++ head/sys/netinet/sctp_auth.h Sun May 8 09:11:59 2011 (r221627) @@ -156,7 +156,9 @@ sctp_copy_skeylist(const struct sctp_key /* ref counts on shared keys, by key id */ extern void sctp_auth_key_acquire(struct sctp_tcb *stcb, uint16_t keyid); -extern void sctp_auth_key_release(struct sctp_tcb *stcb, uint16_t keyid); +extern void +sctp_auth_key_release(struct sctp_tcb *stcb, uint16_t keyid, + int so_locked); /* hmac list handling */ Modified: head/sys/netinet/sctp_indata.c ============================================================================== --- head/sys/netinet/sctp_indata.c Sun May 8 09:11:04 2011 (r221626) +++ head/sys/netinet/sctp_indata.c Sun May 8 09:11:59 2011 (r221627) @@ -375,7 +375,7 @@ abandon: chk->data = NULL; } /* Now free the address and data */ - sctp_free_a_chunk(stcb, chk); + sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED); /* sa_ignore FREED_MEMORY */ } return; @@ -479,7 +479,7 @@ abandon: sctp_ucount_decr(asoc->cnt_on_reasm_queue); /* free up the chk */ chk->data = NULL; - sctp_free_a_chunk(stcb, chk); + sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED); if (asoc->fragmented_delivery_inprogress == 0) { /* @@ -1011,7 +1011,7 @@ sctp_queue_data_for_reasm(struct sctp_tc sctp_m_freem(chk->data); chk->data = NULL; } - sctp_free_a_chunk(stcb, chk); + sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED); return; } else { last_flags = at->rec.data.rcv_flags; @@ -2416,7 +2416,7 @@ sctp_sack_check(struct sctp_tcb *stcb, i stcb->sctp_ep, stcb, NULL, SCTP_FROM_SCTP_INDATA + SCTP_LOC_18); } sctp_send_shutdown(stcb, stcb->asoc.primary_destination); - sctp_send_sack(stcb); + sctp_send_sack(stcb, SCTP_SO_NOT_LOCKED); } else { int is_a_gap; @@ -2466,7 +2466,7 @@ sctp_sack_check(struct sctp_tcb *stcb, i * there are gaps or duplicates. */ (void)SCTP_OS_TIMER_STOP(&stcb->asoc.dack_timer.timer); - sctp_send_sack(stcb); + sctp_send_sack(stcb, SCTP_SO_NOT_LOCKED); } } else { if (!SCTP_OS_TIMER_PENDING(&stcb->asoc.dack_timer.timer)) { @@ -3993,7 +3993,7 @@ sctp_express_handle_sack(struct sctp_tcb SCTP_LOG_FREE_SENT); } asoc->sent_queue_cnt--; - sctp_free_a_chunk(stcb, tp1); + sctp_free_a_chunk(stcb, tp1, SCTP_SO_NOT_LOCKED); } else { break; } @@ -4709,7 +4709,7 @@ sctp_handle_sack(struct mbuf *m, int off 0, SCTP_LOG_FREE_SENT); } - sctp_free_a_chunk(stcb, tp1); + sctp_free_a_chunk(stcb, tp1, SCTP_SO_NOT_LOCKED); wake_him++; } if (TAILQ_EMPTY(&asoc->sent_queue) && (asoc->total_flight > 0)) { @@ -5260,7 +5260,7 @@ sctp_flush_reassm_for_str_seq(struct sct sctp_m_freem(chk->data); chk->data = NULL; } - sctp_free_a_chunk(stcb, chk); + sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED); } else if (SCTP_SSN_GT(chk->rec.data.stream_seq, seq)) { /* * If the stream_seq is > than the purging one, we @@ -5431,7 +5431,7 @@ sctp_handle_forward_tsn(struct sctp_tcb sctp_m_freem(chk->data); chk->data = NULL; } - sctp_free_a_chunk(stcb, chk); + sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED); } else { /* * Ok we have gone beyond the end of the fwd-tsn's Modified: head/sys/netinet/sctp_input.c ============================================================================== --- head/sys/netinet/sctp_input.c Sun May 8 09:11:04 2011 (r221626) +++ head/sys/netinet/sctp_input.c Sun May 8 09:11:59 2011 (r221627) @@ -193,7 +193,11 @@ outnow: */ int -sctp_is_there_unsent_data(struct sctp_tcb *stcb) +sctp_is_there_unsent_data(struct sctp_tcb *stcb, int so_locked +#if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING) + SCTP_UNUSED +#endif +) { int unsent_data = 0; unsigned int i; @@ -242,7 +246,7 @@ sctp_is_there_unsent_data(struct sctp_tc sctp_m_freem(sp->data); sp->data = NULL; } - sctp_free_a_strmoq(stcb, sp); + sctp_free_a_strmoq(stcb, sp, so_locked); } else { unsent_data++; break; @@ -301,7 +305,7 @@ sctp_process_init(struct sctp_init_chunk chk->data = NULL; } } - sctp_free_a_chunk(stcb, chk); + sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED); /* sa_ignore FREED_MEMORY */ } } @@ -323,7 +327,7 @@ sctp_process_init(struct sctp_init_chunk sp->net = NULL; } /* Free the chunk */ - sctp_free_a_strmoq(stcb, sp); + sctp_free_a_strmoq(stcb, sp, SCTP_SO_NOT_LOCKED); /* sa_ignore FREED_MEMORY */ } } @@ -902,7 +906,7 @@ sctp_handle_shutdown(struct sctp_shutdow sctp_timer_stop(SCTP_TIMER_TYPE_SHUTDOWN, stcb->sctp_ep, stcb, net, SCTP_FROM_SCTP_INPUT + SCTP_LOC_8); } /* Now is there unsent data on a stream somewhere? */ - some_on_streamwheel = sctp_is_there_unsent_data(stcb); + some_on_streamwheel = sctp_is_there_unsent_data(stcb, SCTP_SO_NOT_LOCKED); if (!TAILQ_EMPTY(&asoc->send_queue) || !TAILQ_EMPTY(&asoc->sent_queue) || @@ -3127,7 +3131,7 @@ sctp_handle_ecn_cwr(struct sctp_cwr_chun chk->data = NULL; } stcb->asoc.ctrl_queue_cnt--; - sctp_free_a_chunk(stcb, chk); + sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED); if (override == 0) { break; } @@ -3367,7 +3371,7 @@ process_chunk_drop(struct sctp_tcb *stcb case SCTP_SELECTIVE_ACK: case SCTP_NR_SELECTIVE_ACK: /* resend the sack */ - sctp_send_sack(stcb); + sctp_send_sack(stcb, SCTP_SO_NOT_LOCKED); break; case SCTP_HEARTBEAT_REQUEST: /* resend a demand HB */ @@ -3376,7 +3380,7 @@ process_chunk_drop(struct sctp_tcb *stcb * Only retransmit if we KNOW we wont destroy the * tcb */ - (void)sctp_send_hb(stcb, 1, net); + (void)sctp_send_hb(stcb, 1, net, SCTP_SO_NOT_LOCKED); } break; case SCTP_SHUTDOWN: @@ -3547,7 +3551,7 @@ sctp_clean_up_stream_reset(struct sctp_t chk->data = NULL; } asoc->ctrl_queue_cnt--; - sctp_free_a_chunk(stcb, chk); + sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED); /* sa_ignore NO_NULL_CHK */ stcb->asoc.str_reset = NULL; } @@ -3987,7 +3991,7 @@ strres_nochunk: sctp_m_freem(chk->data); chk->data = NULL; } - sctp_free_a_chunk(stcb, chk); + sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED); return (ret_code); } SCTP_BUF_RESV_UF(chk->data, SCTP_MIN_OVERHEAD); Modified: head/sys/netinet/sctp_input.h ============================================================================== --- head/sys/netinet/sctp_input.h Sun May 8 09:11:04 2011 (r221626) +++ head/sys/netinet/sctp_input.h Sun May 8 09:11:59 2011 (r221627) @@ -53,7 +53,7 @@ sctp_reset_in_stream(struct sctp_tcb *st uint16_t * list); -int sctp_is_there_unsent_data(struct sctp_tcb *stcb); +int sctp_is_there_unsent_data(struct sctp_tcb *stcb, int so_locked); #endif #endif Modified: head/sys/netinet/sctp_output.c ============================================================================== --- head/sys/netinet/sctp_output.c Sun May 8 09:11:04 2011 (r221626) +++ head/sys/netinet/sctp_output.c Sun May 8 09:11:59 2011 (r221627) @@ -6178,7 +6178,7 @@ sctp_sendall_iterator(struct sctp_inpcb /* shutdown this assoc */ int cnt; - cnt = sctp_is_there_unsent_data(stcb); + cnt = sctp_is_there_unsent_data(stcb, SCTP_SO_NOT_LOCKED); if (TAILQ_EMPTY(&asoc->send_queue) && TAILQ_EMPTY(&asoc->sent_queue) && @@ -6425,7 +6425,7 @@ sctp_toss_old_cookies(struct sctp_tcb *s chk->data = NULL; } asoc->ctrl_queue_cnt--; - sctp_free_a_chunk(stcb, chk); + sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED); } } } @@ -6454,7 +6454,7 @@ sctp_toss_old_asconf(struct sctp_tcb *st chk->data = NULL; } asoc->ctrl_queue_cnt--; - sctp_free_a_chunk(stcb, chk); + sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED); } } } @@ -6553,7 +6553,11 @@ all_done: } static void -sctp_clean_up_ctl(struct sctp_tcb *stcb, struct sctp_association *asoc) +sctp_clean_up_ctl(struct sctp_tcb *stcb, struct sctp_association *asoc, int so_locked +#if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING) + SCTP_UNUSED +#endif +) { struct sctp_tmit_chunk *chk, *nchk; @@ -6580,7 +6584,7 @@ sctp_clean_up_ctl(struct sctp_tcb *stcb, asoc->ctrl_queue_cnt--; if (chk->rec.chunk_id.id == SCTP_FORWARD_CUM_TSN) asoc->fwd_tsn_cnt--; - sctp_free_a_chunk(stcb, chk); + sctp_free_a_chunk(stcb, chk, so_locked); } else if (chk->rec.chunk_id.id == SCTP_STREAM_RESET) { /* special handling, we must look into the param */ if (chk != asoc->str_reset) { @@ -6660,7 +6664,12 @@ sctp_move_to_outqueue(struct sctp_tcb *s int *locked, int *giveup, int eeor_mode, - int *bail) + int *bail, + int so_locked +#if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING) + SCTP_UNUSED +#endif +) { /* Move from the stream to the send_queue keeping track of the total */ struct sctp_association *asoc; @@ -6731,7 +6740,7 @@ one_more_time: sctp_m_freem(sp->data); sp->data = NULL; } - sctp_free_a_strmoq(stcb, sp); + sctp_free_a_strmoq(stcb, sp, so_locked); /* we can't be locked to it */ *locked = 0; stcb->asoc.locked_on_sending = NULL; @@ -6897,7 +6906,7 @@ dont_do_it: chk->last_mbuf = NULL; if (chk->data == NULL) { sp->some_taken = some_taken; - sctp_free_a_chunk(stcb, chk); + sctp_free_a_chunk(stcb, chk, so_locked); *bail = 1; to_move = 0; goto out_of; @@ -7001,7 +7010,7 @@ dont_do_it: atomic_add_int(&sp->length, to_move); chk->data = NULL; *bail = 1; - sctp_free_a_chunk(stcb, chk); + sctp_free_a_chunk(stcb, chk, so_locked); to_move = 0; goto out_of; } else { @@ -7018,7 +7027,7 @@ dont_do_it: panic("prepend failes HELP?"); #else SCTP_PRINTF("prepend fails HELP?\n"); - sctp_free_a_chunk(stcb, chk); + sctp_free_a_chunk(stcb, chk, so_locked); #endif *bail = 1; to_move = 0; @@ -7140,7 +7149,7 @@ dont_do_it: sctp_m_freem(sp->data); sp->data = NULL; } - sctp_free_a_strmoq(stcb, sp); + sctp_free_a_strmoq(stcb, sp, so_locked); /* we can't be locked to it */ *locked = 0; @@ -7163,7 +7172,11 @@ out_of: static void sctp_fill_outqueue(struct sctp_tcb *stcb, - struct sctp_nets *net, int frag_point, int eeor_mode, int *quit_now) + struct sctp_nets *net, int frag_point, int eeor_mode, int *quit_now, int so_locked +#if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING) + SCTP_UNUSED +#endif +) { struct sctp_association *asoc; struct sctp_stream_out *strq, *strqn; @@ -7200,7 +7213,7 @@ sctp_fill_outqueue(struct sctp_tcb *stcb giveup = 0; bail = 0; moved_how_much = sctp_move_to_outqueue(stcb, strq, goal_mtu, frag_point, &locked, - &giveup, eeor_mode, &bail); + &giveup, eeor_mode, &bail, so_locked); if (moved_how_much) stcb->asoc.ss_functions.sctp_ss_scheduled(stcb, net, asoc, strq, moved_how_much); @@ -7440,7 +7453,7 @@ nothing_to_send: if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_LOGGING_ENABLE) { sctp_log_cwnd(stcb, net, 4, SCTP_CWND_LOG_FILL_OUTQ_CALLED); } - sctp_fill_outqueue(stcb, net, frag_point, eeor_mode, &quit_now); + sctp_fill_outqueue(stcb, net, frag_point, eeor_mode, &quit_now, so_locked); if (quit_now) { /* memory alloc failure */ no_data_chunks = 1; @@ -8378,7 +8391,7 @@ no_data_fill: } else { *reason_code = 5; } - sctp_clean_up_ctl(stcb, asoc); + sctp_clean_up_ctl(stcb, asoc, so_locked); return (0); } @@ -8403,7 +8416,7 @@ sctp_queue_op_err(struct sctp_tcb *stcb, chk->copy_by_ref = 0; SCTP_BUF_PREPEND(op_err, sizeof(struct sctp_chunkhdr), M_DONTWAIT); if (op_err == NULL) { - sctp_free_a_chunk(stcb, chk); + sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED); return; } chk->send_size = 0; @@ -8992,7 +9005,7 @@ sctp_chunk_retransmission(struct sctp_in return (0); } else { /* Clean up the fwd-tsn list */ - sctp_clean_up_ctl(stcb, asoc); + sctp_clean_up_ctl(stcb, asoc, so_locked); return (0); } } @@ -9446,7 +9459,7 @@ sctp_chunk_output(struct sctp_inpcb *inp * running, if so piggy-back the sack. */ if (SCTP_OS_TIMER_PENDING(&stcb->asoc.dack_timer.timer)) { - sctp_send_sack(stcb); + sctp_send_sack(stcb, so_locked); (void)SCTP_OS_TIMER_STOP(&stcb->asoc.dack_timer.timer); } while (asoc->sent_queue_retran_cnt) { @@ -9730,7 +9743,7 @@ send_forward_tsn(struct sctp_tcb *stcb, chk->whoTo = NULL; chk->data = sctp_get_mbuf_for_msg(MCLBYTES, 0, M_DONTWAIT, 1, MT_DATA); if (chk->data == NULL) { - sctp_free_a_chunk(stcb, chk); + sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED); return; } SCTP_BUF_RESV_UF(chk->data, SCTP_MIN_OVERHEAD); @@ -9875,7 +9888,11 @@ sctp_fill_in_rest: } void -sctp_send_sack(struct sctp_tcb *stcb) +sctp_send_sack(struct sctp_tcb *stcb, int so_locked +#if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING) + SCTP_UNUSED +#endif +) { /*- * Queue up a SACK or NR-SACK in the control queue. @@ -10017,7 +10034,7 @@ sctp_send_sack(struct sctp_tcb *stcb) sctp_m_freem(a_chk->data); a_chk->data = NULL; } - sctp_free_a_chunk(stcb, a_chk); + sctp_free_a_chunk(stcb, a_chk, so_locked); /* sa_ignore NO_NULL_CHK */ if (stcb->asoc.delayed_ack) { sctp_timer_stop(SCTP_TIMER_TYPE_RECV, @@ -10691,7 +10708,11 @@ sctp_select_hb_destination(struct sctp_t } int -sctp_send_hb(struct sctp_tcb *stcb, int user_req, struct sctp_nets *u_net) +sctp_send_hb(struct sctp_tcb *stcb, int user_req, struct sctp_nets *u_net, int so_locked +#if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING) + SCTP_UNUSED +#endif +) { struct sctp_tmit_chunk *chk; struct sctp_nets *net; @@ -10747,7 +10768,7 @@ sctp_send_hb(struct sctp_tcb *stcb, int chk->data = sctp_get_mbuf_for_msg(chk->send_size, 0, M_DONTWAIT, 1, MT_HEADER); if (chk->data == NULL) { - sctp_free_a_chunk(stcb, chk); + sctp_free_a_chunk(stcb, chk, so_locked); return (0); } SCTP_BUF_RESV_UF(chk->data, SCTP_MIN_OVERHEAD); @@ -10836,7 +10857,7 @@ sctp_send_hb(struct sctp_tcb *stcb, int sctp_free_remote_addr(chk->whoTo); chk->whoTo = NULL; } - sctp_free_a_chunk((struct sctp_tcb *)NULL, chk); + sctp_free_a_chunk((struct sctp_tcb *)NULL, chk, so_locked); return (-1); } } @@ -10892,7 +10913,7 @@ sctp_send_ecn_echo(struct sctp_tcb *stcb chk->send_size = sizeof(struct sctp_ecne_chunk); chk->data = sctp_get_mbuf_for_msg(chk->send_size, 0, M_DONTWAIT, 1, MT_HEADER); if (chk->data == NULL) { - sctp_free_a_chunk(stcb, chk); + sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED); return; } SCTP_BUF_RESV_UF(chk->data, SCTP_MIN_OVERHEAD); @@ -10955,7 +10976,7 @@ sctp_send_packet_dropped(struct sctp_tcb chk->copy_by_ref = 0; iph = mtod(m, struct ip *); if (iph == NULL) { - sctp_free_a_chunk(stcb, chk); + sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED); return; } switch (iph->ip_v) { @@ -10995,7 +11016,7 @@ sctp_send_packet_dropped(struct sctp_tcb * INIT-ACK, because we can't know if the initiation * tag is correct or not. */ - sctp_free_a_chunk(stcb, chk); + sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED); return; default: break; @@ -11018,7 +11039,7 @@ sctp_send_packet_dropped(struct sctp_tcb chk->data = sctp_get_mbuf_for_msg(MCLBYTES, 0, M_DONTWAIT, 1, MT_DATA); if (chk->data == NULL) { jump_out: - sctp_free_a_chunk(stcb, chk); + sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED); return; } SCTP_BUF_RESV_UF(chk->data, SCTP_MIN_OVERHEAD); @@ -11129,7 +11150,7 @@ sctp_send_cwr(struct sctp_tcb *stcb, str chk->send_size = sizeof(struct sctp_cwr_chunk); chk->data = sctp_get_mbuf_for_msg(chk->send_size, 0, M_DONTWAIT, 1, MT_HEADER); if (chk->data == NULL) { - sctp_free_a_chunk(stcb, chk); + sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED); return; } SCTP_BUF_RESV_UF(chk->data, SCTP_MIN_OVERHEAD); @@ -11418,7 +11439,7 @@ sctp_send_str_reset_req(struct sctp_tcb chk->data = sctp_get_mbuf_for_msg(MCLBYTES, 0, M_DONTWAIT, 1, MT_DATA); if (chk->data == NULL) { - sctp_free_a_chunk(stcb, chk); + sctp_free_a_chunk(stcb, chk, SCTP_SO_LOCKED); SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTP_OUTPUT, ENOMEM); return (ENOMEM); } @@ -12108,7 +12129,7 @@ sctp_copy_it_in(struct sctp_tcb *stcb, *error = sctp_copy_one(sp, uio, resv_in_first); skip_copy: if (*error) { - sctp_free_a_strmoq(stcb, sp); + sctp_free_a_strmoq(stcb, sp, SCTP_SO_LOCKED); sp = NULL; } else { if (sp->sinfo_flags & SCTP_ADDR_OVER) { @@ -13206,7 +13227,7 @@ dataless_eof: SCTP_TCB_LOCK(stcb); hold_tcblock = 1; } - cnt = sctp_is_there_unsent_data(stcb); + cnt = sctp_is_there_unsent_data(stcb, SCTP_SO_LOCKED); if (TAILQ_EMPTY(&asoc->send_queue) && TAILQ_EMPTY(&asoc->sent_queue) && (cnt == 0)) { Modified: head/sys/netinet/sctp_output.h ============================================================================== --- head/sys/netinet/sctp_output.h Sun May 8 09:11:04 2011 (r221626) +++ head/sys/netinet/sctp_output.h Sun May 8 09:11:59 2011 (r221627) @@ -152,9 +152,9 @@ sctp_send_abort_tcb(struct sctp_tcb *, s void send_forward_tsn(struct sctp_tcb *, struct sctp_association *); -void sctp_send_sack(struct sctp_tcb *); +void sctp_send_sack(struct sctp_tcb *, int); -int sctp_send_hb(struct sctp_tcb *, int, struct sctp_nets *); +int sctp_send_hb(struct sctp_tcb *, int, struct sctp_nets *, int); void sctp_send_ecn_echo(struct sctp_tcb *, struct sctp_nets *, uint32_t); Modified: head/sys/netinet/sctp_pcb.c ============================================================================== --- head/sys/netinet/sctp_pcb.c Sun May 8 09:11:04 2011 (r221626) +++ head/sys/netinet/sctp_pcb.c Sun May 8 09:11:59 2011 (r221627) @@ -4988,7 +4988,7 @@ sctp_free_assoc(struct sctp_inpcb *inp, } sctp_free_spbufspace(stcb, asoc, sp); if (sp->holds_key_ref) - sctp_auth_key_release(stcb, sp->auth_keyid); + sctp_auth_key_release(stcb, sp->auth_keyid, SCTP_SO_LOCKED); /* Free the zone stuff */ SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_strmoq), sp); SCTP_DECR_STRMOQ_COUNT(); @@ -5021,7 +5021,7 @@ sctp_free_assoc(struct sctp_inpcb *inp, chk->data = NULL; } if (chk->holds_key_ref) - sctp_auth_key_release(stcb, chk->auth_keyid); + sctp_auth_key_release(stcb, chk->auth_keyid, SCTP_SO_LOCKED); SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_chunk), chk); SCTP_DECR_CHK_COUNT(); atomic_subtract_int(&SCTP_BASE_INFO(ipi_free_chunks), 1); @@ -5043,7 +5043,7 @@ sctp_free_assoc(struct sctp_inpcb *inp, } } if (chk->holds_key_ref) - sctp_auth_key_release(stcb, chk->auth_keyid); + sctp_auth_key_release(stcb, chk->auth_keyid, SCTP_SO_LOCKED); if (chk->whoTo) { sctp_free_remote_addr(chk->whoTo); chk->whoTo = NULL; @@ -5067,7 +5067,7 @@ sctp_free_assoc(struct sctp_inpcb *inp, } } if (chk->holds_key_ref) - sctp_auth_key_release(stcb, chk->auth_keyid); + sctp_auth_key_release(stcb, chk->auth_keyid, SCTP_SO_LOCKED); sctp_free_remote_addr(chk->whoTo); SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_chunk), chk); SCTP_DECR_CHK_COUNT(); @@ -5081,7 +5081,7 @@ sctp_free_assoc(struct sctp_inpcb *inp, chk->data = NULL; } if (chk->holds_key_ref) - sctp_auth_key_release(stcb, chk->auth_keyid); + sctp_auth_key_release(stcb, chk->auth_keyid, SCTP_SO_LOCKED); sctp_free_remote_addr(chk->whoTo); SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_chunk), chk); SCTP_DECR_CHK_COUNT(); @@ -5095,7 +5095,7 @@ sctp_free_assoc(struct sctp_inpcb *inp, chk->data = NULL; } if (chk->holds_key_ref) - sctp_auth_key_release(stcb, chk->auth_keyid); + sctp_auth_key_release(stcb, chk->auth_keyid, SCTP_SO_LOCKED); sctp_free_remote_addr(chk->whoTo); SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_chunk), chk); SCTP_DECR_CHK_COUNT(); @@ -5108,7 +5108,7 @@ sctp_free_assoc(struct sctp_inpcb *inp, chk->data = NULL; } if (chk->holds_key_ref) - sctp_auth_key_release(stcb, chk->auth_keyid); + sctp_auth_key_release(stcb, chk->auth_keyid, SCTP_SO_LOCKED); sctp_free_remote_addr(chk->whoTo); SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_chunk), chk); SCTP_DECR_CHK_COUNT(); @@ -6895,7 +6895,7 @@ sctp_drain_mbufs(struct sctp_inpcb *inp, sctp_m_freem(chk->data); chk->data = NULL; } - sctp_free_a_chunk(stcb, chk); + sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED); } } /* Ok that was fun, now we will drain all the inbound streams? */ @@ -6958,7 +6958,7 @@ sctp_drain_mbufs(struct sctp_inpcb *inp, asoc->last_revoke_count = cnt; (void)SCTP_OS_TIMER_STOP(&stcb->asoc.dack_timer.timer); /* sa_ignore NO_NULL_CHK */ - sctp_send_sack(stcb); + sctp_send_sack(stcb, SCTP_SO_NOT_LOCKED); sctp_chunk_output(stcb->sctp_ep, stcb, SCTP_OUTPUT_FROM_DRAIN, SCTP_SO_NOT_LOCKED); reneged_asoc_ids[reneged_at] = sctp_get_associd(stcb); reneged_at++; Modified: head/sys/netinet/sctp_timer.c ============================================================================== --- head/sys/netinet/sctp_timer.c Sun May 8 09:11:04 2011 (r221626) +++ head/sys/netinet/sctp_timer.c Sun May 8 09:11:59 2011 (r221627) @@ -597,7 +597,7 @@ sctp_recover_sent_list(struct sctp_tcb * } } asoc->sent_queue_cnt--; - sctp_free_a_chunk(stcb, chk); + sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED); } } SCTP_PRINTF("after recover order is as follows\n"); @@ -1056,7 +1056,7 @@ sctp_t3rxt_timer(struct sctp_inpcb *inp, * no recent feed back in an RTO or * more, request a RTT update */ - if (sctp_send_hb(stcb, 1, net) < 0) + if (sctp_send_hb(stcb, 1, net, SCTP_SO_NOT_LOCKED) < 0) /* * Less than 0 means we lost * the assoc @@ -1120,7 +1120,7 @@ sctp_t3rxt_timer(struct sctp_inpcb *inp, * but is in PF state, a PF-heartbeat needs to be sent * manually. */ - if (sctp_send_hb(stcb, 1, net) < 0) + if (sctp_send_hb(stcb, 1, net, SCTP_SO_NOT_LOCKED) < 0) /* Return less than 0 means we lost the association */ return (1); } @@ -1598,7 +1598,7 @@ sctp_heartbeat_timer(struct sctp_inpcb * } /* Send a new HB, this will do threshold managment, pick a new dest */ if (cnt_of_unconf == 0) { - if (sctp_send_hb(stcb, 0, NULL) < 0) { + if (sctp_send_hb(stcb, 0, NULL, SCTP_SO_NOT_LOCKED) < 0) { return (1); } } else { @@ -1620,7 +1620,7 @@ sctp_heartbeat_timer(struct sctp_inpcb * net->src_addr_selected = 0; } } - ret = sctp_send_hb(stcb, 1, net); + ret = sctp_send_hb(stcb, 1, net, SCTP_SO_NOT_LOCKED); if (ret < 0) return 1; else if (ret == 0) { Modified: head/sys/netinet/sctp_usrreq.c ============================================================================== --- head/sys/netinet/sctp_usrreq.c Sun May 8 09:11:04 2011 (r221626) +++ head/sys/netinet/sctp_usrreq.c Sun May 8 09:11:59 2011 (r221627) @@ -3997,7 +3997,7 @@ sctp_setopt(struct socket *so, int optna /************************NET SPECIFIC SET ******************/ if (paddrp->spp_flags & SPP_HB_DEMAND) { /* on demand HB */ - if (sctp_send_hb(stcb, 1, net) < 0) { + if (sctp_send_hb(stcb, 1, net, SCTP_SO_LOCKED) < 0) { /* asoc destroyed */ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); error = EINVAL; Modified: head/sys/netinet/sctp_var.h ============================================================================== --- head/sys/netinet/sctp_var.h Sun May 8 09:11:04 2011 (r221626) +++ head/sys/netinet/sctp_var.h Sun May 8 09:11:59 2011 (r221627) @@ -87,9 +87,9 @@ extern struct pr_usrreqs sctp_usrreqs; } \ } -#define sctp_free_a_strmoq(_stcb, _strmoq) { \ +#define sctp_free_a_strmoq(_stcb, _strmoq, _so_locked) { \ if ((_strmoq)->holds_key_ref) { \ - sctp_auth_key_release(stcb, sp->auth_keyid); \ + sctp_auth_key_release(stcb, sp->auth_keyid, _so_locked); \ (_strmoq)->holds_key_ref = 0; \ } \ SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_strmoq), (_strmoq)); \ @@ -105,9 +105,9 @@ extern struct pr_usrreqs sctp_usrreqs; } \ } -#define sctp_free_a_chunk(_stcb, _chk) { \ +#define sctp_free_a_chunk(_stcb, _chk, _so_locked) { \ if ((_chk)->holds_key_ref) {\ - sctp_auth_key_release((_stcb), (_chk)->auth_keyid); \ + sctp_auth_key_release((_stcb), (_chk)->auth_keyid, _so_locked); \ (_chk)->holds_key_ref = 0; \ } \ if (_stcb) { \ Modified: head/sys/netinet/sctputil.c ============================================================================== --- head/sys/netinet/sctputil.c Sun May 8 09:11:04 2011 (r221626) +++ head/sys/netinet/sctputil.c Sun May 8 09:11:59 2011 (r221627) @@ -1634,7 +1634,7 @@ sctp_timeout_handler(void *t) } { SCTP_STAT_INCR(sctps_timosack); stcb->asoc.timosack++; - sctp_send_sack(stcb); + sctp_send_sack(stcb, SCTP_SO_NOT_LOCKED); } #ifdef SCTP_AUDITING_ENABLED sctp_auditing(4, inp, stcb, net); @@ -3656,7 +3656,7 @@ sctp_report_all_outbound(struct sctp_tcb chk->data = NULL; } } - sctp_free_a_chunk(stcb, chk); + sctp_free_a_chunk(stcb, chk, so_locked); /* sa_ignore FREED_MEMORY */ } /* pending send queue SHOULD be empty */ @@ -3672,7 +3672,7 @@ sctp_report_all_outbound(struct sctp_tcb chk->data = NULL; } } - sctp_free_a_chunk(stcb, chk); + sctp_free_a_chunk(stcb, chk, so_locked); /* sa_ignore FREED_MEMORY */ } for (i = 0; i < asoc->streamoutcnt; i++) { @@ -3697,7 +3697,7 @@ sctp_report_all_outbound(struct sctp_tcb sp->net = NULL; } /* Free the chunk */ - sctp_free_a_strmoq(stcb, sp); + sctp_free_a_strmoq(stcb, sp, so_locked); /* sa_ignore FREED_MEMORY */ } } @@ -5033,7 +5033,7 @@ sctp_user_rcvd(struct sctp_tcb *stcb, ui goto out; } SCTP_STAT_INCR(sctps_wu_sacks_sent); - sctp_send_sack(stcb); + sctp_send_sack(stcb, SCTP_SO_LOCKED); sctp_chunk_output(stcb->sctp_ep, stcb, SCTP_OUTPUT_FROM_USR_RCVD, SCTP_SO_LOCKED);