Mercurial > illumos > illumos-gate
changeset 5022:7b32314731c6
6593961 Transmit performance doesn't scale with increasing number of TCP connections in guest domain
author | raghuram |
---|---|
date | Mon, 10 Sep 2007 15:47:44 -0700 |
parents | 86546f219f69 |
children | e0c678e511a7 |
files | usr/src/uts/sun4v/io/vnet_gen.c |
diffstat | 1 files changed, 28 insertions(+), 17 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/uts/sun4v/io/vnet_gen.c Mon Sep 10 14:31:41 2007 -0700 +++ b/usr/src/uts/sun4v/io/vnet_gen.c Mon Sep 10 15:47:44 2007 -0700 @@ -280,6 +280,8 @@ uint32_t vgen_ldcup_retries = 5; /* max # of ldc_up() retries */ uint32_t vgen_recv_delay = 1; /* delay when rx descr not ready */ uint32_t vgen_recv_retries = 10; /* retry when rx descr not ready */ +uint32_t vgen_tx_retries = 0x4; /* retry when tx descr not available */ +uint32_t vgen_tx_delay = 0x30; /* delay when tx descr not available */ int vgen_rcv_thread_enabled = 1; /* Enable Recieve thread */ @@ -529,11 +531,26 @@ static mblk_t * vgen_tx(void *arg, mblk_t *mp) { + int i; vgen_port_t *portp; - int status; + int status = VGEN_FAILURE; portp = (vgen_port_t *)arg; - status = vgen_portsend(portp, mp); + /* + * Retry so that we avoid reporting a failure + * to the upper layer. Returning a failure may cause the + * upper layer to go into single threaded mode there by + * causing performance degradation, especially for a large + * number of connections. + */ + for (i = 0; i < vgen_tx_retries; ) { + status = vgen_portsend(portp, mp); + if (status == VGEN_SUCCESS) { + break; + } + if (++i < vgen_tx_retries) + delay(drv_usectohz(vgen_tx_delay)); + } if (status != VGEN_SUCCESS) { /* failure */ return (mp); @@ -549,6 +566,7 @@ vgen_ldclist_t *ldclp; vgen_ldc_t *ldcp; int status; + int rv = VGEN_SUCCESS; ldclp = &portp->ldclist; READ_ENTER(&ldclp->rwlock); @@ -561,23 +579,14 @@ } ldcp = ldclp->headp; - if (ldcp->need_resched) { - /* out of tx resources, see vgen_ldcsend() for details. */ - mutex_enter(&ldcp->txlock); - ldcp->statsp->tx_no_desc++; - mutex_exit(&ldcp->txlock); - - RW_EXIT(&ldclp->rwlock); - return (VGEN_FAILURE); - } - status = vgen_ldcsend(ldcp, mp); + RW_EXIT(&ldclp->rwlock); - if (status != VGEN_TX_SUCCESS) - return (VGEN_FAILURE); - - return (VGEN_SUCCESS); + if (status != VGEN_TX_SUCCESS) { + rv = VGEN_FAILURE; + } + return (rv); } /* channel transmit function */ @@ -4858,6 +4867,7 @@ static void vgen_reclaim_dring(vgen_ldc_t *ldcp) { + int count = 0; vnet_public_desc_t *txdp; vgen_private_desc_t *tbufp; vio_dring_entry_hdr_t *hdrp; @@ -4881,6 +4891,7 @@ tbufp = NEXTTBUF(ldcp, tbufp); txdp = tbufp->descp; hdrp = &txdp->hdr; + count++; } ldcp->cur_tbufp = tbufp; @@ -4888,7 +4899,7 @@ /* * Check if mac layer should be notified to restart transmissions */ - if (ldcp->need_resched) { + if ((ldcp->need_resched) && (count > 0)) { ldcp->need_resched = B_FALSE; vnet_tx_update(vgenp->vnetp); }