diff options
| author | Cathy Zhou <Cathy.Zhou@Sun.COM> | 2009-05-27 11:56:36 -0700 |
|---|---|---|
| committer | Cathy Zhou <Cathy.Zhou@Sun.COM> | 2009-05-27 11:56:36 -0700 |
| commit | 79eeb64527c881659e23b60088c32ae3736a7a2c (patch) | |
| tree | 2e4ceea8eb60e09cf3825983d2d9b43e699bc29b /usr/src/uts/common/io/softmac | |
| parent | 802a905753962a193df60d7a1c76ccec8136e5eb (diff) | |
| download | illumos-gate-79eeb64527c881659e23b60088c32ae3736a7a2c.tar.gz | |
6831148 System panics while running UDP stress test with cassini driver
Diffstat (limited to 'usr/src/uts/common/io/softmac')
| -rw-r--r-- | usr/src/uts/common/io/softmac/softmac_dev.c | 20 | ||||
| -rw-r--r-- | usr/src/uts/common/io/softmac/softmac_fp.c | 73 |
2 files changed, 69 insertions, 24 deletions
diff --git a/usr/src/uts/common/io/softmac/softmac_dev.c b/usr/src/uts/common/io/softmac/softmac_dev.c index 0a64e11a8a..317a89360c 100644 --- a/usr/src/uts/common/io/softmac/softmac_dev.c +++ b/usr/src/uts/common/io/softmac/softmac_dev.c @@ -180,6 +180,8 @@ softmac_upper_destructor(void *buf, void *arg) 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 @@ softmac_drv_wsrv(queue_t *wq) } 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); diff --git a/usr/src/uts/common/io/softmac/softmac_fp.c b/usr/src/uts/common/io/softmac/softmac_fp.c index 4086007daf..7a10aa68b7 100644 --- a/usr/src/uts/common/io/softmac/softmac_fp.c +++ b/usr/src/uts/common/io/softmac/softmac_fp.c @@ -196,11 +196,32 @@ softmac_capab_perim(softmac_upper_t *sup, void *data, uint_t flags) 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 @@ softmac_capab_direct(softmac_upper_t *sup, void *data, uint_t flags) 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 @@ softmac_fastpath_tear(softmac_upper_t *sup) 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 @@ softmac_fastpath_wput_data(softmac_upper_t *sup, mblk_t *mp, uintptr_t f_hint, 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 @@ softmac_fastpath_wput_data(softmac_upper_t *sup, mblk_t *mp, uintptr_t f_hint, 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 |
