summaryrefslogtreecommitdiff
path: root/usr
diff options
context:
space:
mode:
authorCathy Zhou <Cathy.Zhou@Sun.COM>2009-05-27 11:56:36 -0700
committerCathy Zhou <Cathy.Zhou@Sun.COM>2009-05-27 11:56:36 -0700
commit79eeb64527c881659e23b60088c32ae3736a7a2c (patch)
tree2e4ceea8eb60e09cf3825983d2d9b43e699bc29b /usr
parent802a905753962a193df60d7a1c76ccec8136e5eb (diff)
downloadillumos-gate-79eeb64527c881659e23b60088c32ae3736a7a2c.tar.gz
6831148 System panics while running UDP stress test with cassini driver
Diffstat (limited to 'usr')
-rw-r--r--usr/src/uts/common/inet/ip/ip_if.c3
-rw-r--r--usr/src/uts/common/io/softmac/softmac_dev.c20
-rw-r--r--usr/src/uts/common/io/softmac/softmac_fp.c73
-rw-r--r--usr/src/uts/common/sys/softmac_impl.h6
4 files changed, 78 insertions, 24 deletions
diff --git a/usr/src/uts/common/inet/ip/ip_if.c b/usr/src/uts/common/inet/ip/ip_if.c
index 67eff68c28..3f4adec52d 100644
--- a/usr/src/uts/common/inet/ip/ip_if.c
+++ b/usr/src/uts/common/inet/ip/ip_if.c
@@ -3054,6 +3054,9 @@ ill_capability_direct_enable(ill_t *ill)
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
*/
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
diff --git a/usr/src/uts/common/sys/softmac_impl.h b/usr/src/uts/common/sys/softmac_impl.h
index 3e578fe38f..eb71063bc7 100644
--- a/usr/src/uts/common/sys/softmac_impl.h
+++ b/usr/src/uts/common/sys/softmac_impl.h
@@ -323,6 +323,12 @@ typedef struct softmac_upper_s {
* 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) { \