Mercurial > illumos > illumos-gate
changeset 9738:70ba742e2254
6831148 System panics while running UDP stress test with cassini driver
author | Cathy Zhou <Cathy.Zhou@Sun.COM> |
---|---|
date | Wed, 27 May 2009 11:56:36 -0700 |
parents | f100be4364e0 |
children | 6d565cf1d9cc |
files | usr/src/uts/common/inet/ip/ip_if.c usr/src/uts/common/io/softmac/softmac_dev.c usr/src/uts/common/io/softmac/softmac_fp.c usr/src/uts/common/sys/softmac_impl.h |
diffstat | 4 files changed, 78 insertions(+), 24 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/uts/common/inet/ip/ip_if.c Wed May 27 12:45:22 2009 -0400 +++ b/usr/src/uts/common/inet/ip/ip_if.c Wed May 27 11:56:36 2009 -0700 @@ -3054,6 +3054,9 @@ idd->idd_tx_cb_dh = direct.di_tx_cb_dh; idd->idd_tx_fctl_df = (ip_dld_fctl_t)direct.di_tx_fctl_df; idd->idd_tx_fctl_dh = direct.di_tx_fctl_dh; + ASSERT(idd->idd_tx_cb_df != NULL); + ASSERT(idd->idd_tx_fctl_df != NULL); + ASSERT(idd->idd_tx_df != NULL); /* * One time registration of flow enable callback function */
--- a/usr/src/uts/common/io/softmac/softmac_dev.c Wed May 27 12:45:22 2009 -0400 +++ b/usr/src/uts/common/io/softmac/softmac_dev.c Wed May 27 11:56:36 2009 -0700 @@ -180,6 +180,8 @@ ASSERT(!sup->su_tx_busy); ASSERT(!sup->su_bound); ASSERT(!sup->su_taskq_scheduled); + ASSERT(sup->su_tx_notify_func == NULL); + ASSERT(sup->su_tx_notify_arg == NULL); ASSERT(list_is_empty(&sup->su_req_list)); list_destroy(&sup->su_req_list); @@ -656,10 +658,22 @@ } else if (sup->su_tx_busy && SOFTMAC_CANPUTNEXT(sup->su_slp->sl_wq)) { /* * The flow-conctol of the dedicated-lower-stream is - * relieved, relieve the flow-control of the - * upper-stream too. + * relieved. If DLD_CAPAB_DIRECT is enabled, call tx_notify + * callback to relieve the flow-control of the specific client, + * otherwise relieve the flow-control of all the upper-stream + * using the traditional STREAM mechanism. */ - sup->su_tx_flow_mp = getq(wq); + if (sup->su_tx_notify_func != NULL) { + sup->su_tx_inprocess++; + mutex_exit(&sup->su_mutex); + sup->su_tx_notify_func(sup->su_tx_notify_arg, + (mac_tx_cookie_t)sup); + mutex_enter(&sup->su_mutex); + if (--sup->su_tx_inprocess == 0) + cv_signal(&sup->su_cv); + } + ASSERT(sup->su_tx_flow_mp == NULL); + VERIFY((sup->su_tx_flow_mp = getq(wq)) != NULL); sup->su_tx_busy = B_FALSE; } mutex_exit(&sup->su_mutex);
--- a/usr/src/uts/common/io/softmac/softmac_fp.c Wed May 27 12:45:22 2009 -0400 +++ b/usr/src/uts/common/io/softmac/softmac_fp.c Wed May 27 11:56:36 2009 -0700 @@ -196,11 +196,32 @@ return (0); } -/* ARGSUSED */ static mac_tx_notify_handle_t -softmac_client_tx_notify(void *txcb, mac_tx_notify_t func, void *arg) +softmac_client_tx_notify(softmac_upper_t *sup, mac_tx_notify_t func, void *arg) { - return (NULL); + ASSERT(MUTEX_HELD(&sup->su_mutex)); + + if (func != NULL) { + sup->su_tx_notify_func = func; + sup->su_tx_notify_arg = arg; + } else { + /* + * Wait for all tx_notify_func call to be done. + */ + while (sup->su_tx_inprocess != 0) + cv_wait(&sup->su_cv, &sup->su_mutex); + + sup->su_tx_notify_func = NULL; + sup->su_tx_notify_arg = NULL; + } + return ((mac_tx_notify_handle_t)sup); +} + +static boolean_t +softmac_tx_is_flow_blocked(softmac_upper_t *sup, mac_tx_cookie_t cookie) +{ + ASSERT(cookie == (mac_tx_cookie_t)sup); + return (sup->su_tx_busy); } static int @@ -223,15 +244,10 @@ slp->sl_rxinfo = &sup->su_direct_rxinfo; direct->di_tx_df = (uintptr_t)softmac_fastpath_wput_data; direct->di_tx_dh = sup; - - /* - * We relying on the STREAM flow-control to backenable - * the IP stream. Therefore, no notify callback needs to - * be registered. But IP requires this to be a valid function - * pointer. - */ + direct->di_tx_fctl_df = (uintptr_t)softmac_tx_is_flow_blocked; + direct->di_tx_fctl_dh = sup; direct->di_tx_cb_df = (uintptr_t)softmac_client_tx_notify; - direct->di_tx_cb_dh = NULL; + direct->di_tx_cb_dh = sup; sup->su_direct = B_TRUE; return (0); @@ -933,9 +949,16 @@ while (sup->su_tx_inprocess != 0) cv_wait(&sup->su_cv, &sup->su_mutex); + /* + * Note that this function is called either when the stream is closed, + * or the stream is unbound (fastpath-slowpath-switch). Therefore, + * No need to call the tx_notify callback. + */ + sup->su_tx_notify_func = NULL; + sup->su_tx_notify_arg = NULL; if (sup->su_tx_busy) { ASSERT(sup->su_tx_flow_mp == NULL); - sup->su_tx_flow_mp = getq(sup->su_wq); + VERIFY((sup->su_tx_flow_mp = getq(sup->su_wq)) != NULL); sup->su_tx_busy = B_FALSE; } @@ -995,18 +1018,22 @@ return (NULL); } - if ((flag & MAC_DROP_ON_NO_DESC) != 0) { - freemsg(mp); - return ((mac_tx_cookie_t)wq); - } - if (sup->su_tx_busy) { - putnext(wq, mp); - return ((mac_tx_cookie_t)wq); + if ((flag & MAC_DROP_ON_NO_DESC) != 0) + freemsg(mp); + else + putnext(wq, mp); + return ((mac_tx_cookie_t)sup); } mutex_enter(&sup->su_mutex); if (!sup->su_tx_busy) { + /* + * If DLD_CAPAB_DIRECT is enabled, the notify callback will be + * called when the flow control can be disabled. Otherwise, + * put the tx_flow_mp into the wq to make use of the old + * streams flow control. + */ ASSERT(sup->su_tx_flow_mp != NULL); (void) putq(sup->su_wq, sup->su_tx_flow_mp); sup->su_tx_flow_mp = NULL; @@ -1014,8 +1041,12 @@ qenable(wq); } mutex_exit(&sup->su_mutex); - putnext(wq, mp); - return ((mac_tx_cookie_t)wq); + + if ((flag & MAC_DROP_ON_NO_DESC) != 0) + freemsg(mp); + else + putnext(wq, mp); + return ((mac_tx_cookie_t)sup); } boolean_t
--- a/usr/src/uts/common/sys/softmac_impl.h Wed May 27 12:45:22 2009 -0400 +++ b/usr/src/uts/common/sys/softmac_impl.h Wed May 27 11:56:36 2009 -0700 @@ -323,6 +323,12 @@ * Whether this stream is already scheduled in softmac_taskq_list. */ boolean_t su_taskq_scheduled; /* softmac_taskq_lock */ + + /* + * The DLD_CAPAB_DIRECT related notify callback. + */ + mac_tx_notify_t su_tx_notify_func; /* su_mutex */ + void *su_tx_notify_arg; /* su_mutex */ } softmac_upper_t; #define SOFTMAC_EQ_PENDING(sup, mp) { \