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);
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to