From ca20d287a3d0bc1ddb9ff611cca56ea84ca6d314 Mon Sep 17 00:00:00 2001 From: aestrin Date: Thu, 28 Dec 2006 22:54:11 +0000 Subject: [PATCH] [VNIC] fixed heartbeat algorithm. Other changes towards graceful handling of surprise IOCs removal, both local and remote. git-svn-id: svn://openib.tc.cornell.edu/gen1@569 ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86 --- trunk/ulp/inic/kernel/netvnic.inf | 10 +- trunk/ulp/inic/kernel/vnic_adapter.c | 24 +++-- trunk/ulp/inic/kernel/vnic_adapter.h | 4 +- trunk/ulp/inic/kernel/vnic_config.h | 14 +-- trunk/ulp/inic/kernel/vnic_control.c | 12 ++- trunk/ulp/inic/kernel/vnic_data.c | 109 ++++++++++++---------- trunk/ulp/inic/kernel/vnic_debug.h | 2 +- trunk/ulp/inic/kernel/vnic_driver.c | 47 +++++++--- trunk/ulp/inic/kernel/vnic_ib.c | 99 +++++++++----------- trunk/ulp/inic/kernel/vnic_netpath.c | 5 +- trunk/ulp/inic/kernel/vnic_viport.c | 134 ++++++++++++++++++++------- trunk/ulp/inic/kernel/vnic_viport.h | 1 + 12 files changed, 280 insertions(+), 181 deletions(-) diff --git a/trunk/ulp/inic/kernel/netvnic.inf b/trunk/ulp/inic/kernel/netvnic.inf index 45f3c472..dadfae6d 100644 --- a/trunk/ulp/inic/kernel/netvnic.inf +++ b/trunk/ulp/inic/kernel/netvnic.inf @@ -102,12 +102,12 @@ HKR,"Params\PnpInterface",%PNPBus%,%REG_DWORD%,1 HKR, Params, MinMtu,, "1500" HKR, Params, MaxMtu,, "9500" -HKR, Params, MinHostPoolSz,, "64" -HKR, Params, HostRecvPoolEntries,, "256" -HKR, Params, MinEiocPoolSz,, "64" -HKR, Params, MaxEiocPoolSz,, "256" +HKR, Params, MinHostPoolSz,, "256" +HKR, Params, HostRecvPoolEntries,, "512" +HKR, Params, MinEiocPoolSz,, "256" +HKR, Params, MaxEiocPoolSz,, "512" HKR, Params, MinHostKickTimeout,, "50" -HKR, Params, MaxHostKickTimeout,, "200" +HKR, Params, MaxHostKickTimeout,, "100" HKR, Params, MinHostKickEntries,, "1" HKR, Params, MaxHostKickEntries,, "64" HKR, Params, MinHostKickBytes,, "0" diff --git a/trunk/ulp/inic/kernel/vnic_adapter.c b/trunk/ulp/inic/kernel/vnic_adapter.c index 8dc77b79..afe25797 100644 --- a/trunk/ulp/inic/kernel/vnic_adapter.c +++ b/trunk/ulp/inic/kernel/vnic_adapter.c @@ -433,7 +433,7 @@ vnic_get_adapter_params( NdisReadConfiguration( &status, &p_reg_prm, h_config, &keyword, NdisParameterInteger ); if( status == NDIS_STATUS_SUCCESS ) - g_vnic_dbg_lvl = p_reg_prm->ParameterData.IntegerData; + g_vnic_dbg_lvl |= p_reg_prm->ParameterData.IntegerData; RtlInitUnicodeString( &keyword, L"MinMtu" ); NdisReadConfiguration( @@ -611,6 +611,7 @@ vnic_viport_allocate( data_construct( &p_viport->data, p_viport ); p_viport->ioc_num = _get_ioc_num_from_iocguid( &p_adapter->ifc_data.guid ); + p_adapter->ioc_num = p_viport->ioc_num; *pp_viport = p_viport; @@ -646,7 +647,7 @@ vnic_set_mcast( VNIC_ENTER( VNIC_DBG_MCAST ); - VNIC_TRACE( VNIC_DBG_INFO, + VNIC_TRACE( VNIC_DBG_INIT, ("MCAST COUNT to set = %d\n", mc_count)); /* Copy the MC address list into the adapter. */ if( mc_count ) @@ -852,10 +853,7 @@ __vnic_pnp_cb( VNIC_TRACE( VNIC_DBG_PNP, ("IB_PNP_IOC_REMOVE for %s.\n", p_adapter->ioc_info.profile.id_string) ); - NdisMIndicateStatus( p_adapter->h_handle, - NDIS_STATUS_MEDIA_DISCONNECT, NULL, 0 ); - NdisMIndicateStatusComplete( p_adapter->h_handle ); - vnic_viport_cleanup( p_adapter ); + viport_linkDown( p_adapter->p_viport ); break; case IB_PNP_IOC_PATH_ADD: @@ -902,7 +900,7 @@ __vnic_pnp_cb( if( ib_status != IB_SUCCESS ) { VNIC_TRACE( VNIC_DBG_ERROR, - ("Control connect return s%\n", p_adapter->ifc.get_err_str( ib_status )) ); + ("Control connect return %s\n", p_adapter->ifc.get_err_str( ib_status )) ); vnic_viport_cleanup( p_adapter ); break; } @@ -1004,6 +1002,14 @@ vnic_viport_cleanup( if ( p_adapter->p_viport ) { + if( ( InterlockedExchange( (volatile LONG *)&p_adapter->state, + INIC_DEREGISTERING )) == INIC_DEREGISTERING ) + { + VNIC_TRACE(VNIC_DBG_INIT, + ("vnic viport cleanup - already destroying\n" )); + return; + } + viport_timerStop( p_adapter->p_viport ); InterlockedExchange( (volatile LONG *)&p_adapter->p_viport->disconnect, TRUE ); viport_cleanup(p_adapter->p_viport ); } @@ -1013,7 +1019,7 @@ vnic_viport_cleanup( } void -__vnic_pnp_dereg( +__vnic_pnp_dereg_cb( IN void* context ) { vnic_adapter_t* p_adapter; @@ -1092,7 +1098,7 @@ vnic_reset_adapter( { h_pnp = p_adapter->h_pnp; p_adapter->h_pnp = NULL; - status = p_adapter->ifc.dereg_pnp( h_pnp, __vnic_pnp_dereg ); + status = p_adapter->ifc.dereg_pnp( h_pnp, __vnic_pnp_dereg_cb ); if( status == IB_SUCCESS ) status = IB_NOT_DONE; } diff --git a/trunk/ulp/inic/kernel/vnic_adapter.h b/trunk/ulp/inic/kernel/vnic_adapter.h index 09068dd2..5cd9f284 100644 --- a/trunk/ulp/inic/kernel/vnic_adapter.h +++ b/trunk/ulp/inic/kernel/vnic_adapter.h @@ -131,6 +131,8 @@ typedef struct _vnic_adapter { mac_addr_t mcast_array[MAX_MCAST]; LONG xmitStarted; LONG carrier; + uint32_t ioc_num; + uint32_t link_speed; uint32_t packet_filter; int hung; BOOLEAN reset; @@ -215,7 +217,7 @@ ibregion_physInit( IN uint64_t len ); void -__vnic_pnp_dereg( +__vnic_pnp_dereg_cb( IN void* context ); ib_api_status_t diff --git a/trunk/ulp/inic/kernel/vnic_config.h b/trunk/ulp/inic/kernel/vnic_config.h index 4a91679b..3dccc7ed 100644 --- a/trunk/ulp/inic/kernel/vnic_config.h +++ b/trunk/ulp/inic/kernel/vnic_config.h @@ -19,16 +19,16 @@ #define MAX_MTU 9500 /* max Jumbo frame payload size */ #define ETH_VLAN_HLEN 18 /* ethernet header with VLAN tag */ -#define HOST_RECV_POOL_ENTRIES 128 /* TBD: Abritrary */ -#define MIN_HOST_POOL_SZ 64 /* TBD: Abritrary */ -#define MIN_EIOC_POOL_SZ 64 /* TBD: Abritrary */ -#define MAX_EIOC_POOL_SZ 128 /* TBD: Abritrary */ +#define HOST_RECV_POOL_ENTRIES 512 /* TBD: Abritrary */ +#define MIN_HOST_POOL_SZ 256 /* TBD: Abritrary */ +#define MIN_EIOC_POOL_SZ 256 /* TBD: Abritrary */ +#define MAX_EIOC_POOL_SZ 512 /* TBD: Abritrary */ #define MIN_HOST_KICK_TIMEOUT 100 /* TBD: Arbitrary */ #define MAX_HOST_KICK_TIMEOUT 200 /* In uSec */ #define MIN_HOST_KICK_ENTRIES 1 /* TBD: Arbitrary */ -#define MAX_HOST_KICK_ENTRIES 64 /* TBD: Arbitrary */ +#define MAX_HOST_KICK_ENTRIES 128 /* TBD: Arbitrary */ #define MIN_HOST_KICK_BYTES 0 #define MAX_HOST_KICK_BYTES 5000 @@ -77,9 +77,10 @@ get_time_stamp_ms( void ) #define MEM_REG_SIZE 0xFFFFFFFFFFFFFFFF /* link speed in 100 bits/sec units */ +#define LINK_SPEED_1MBIT_x100BPS 10000 #define LINK_SPEED_1GBIT_x100BPS 10000000 #define LINK_SPEED_10GBIT_x100BPS 100000000 - /* VEx does not report it's link speed, so set it 1Gb/s so far */ + /* if VEx does not report it's link speed, so set it 1Gb/s so far */ #define DEFAULT_LINK_SPEED_x100BPS LINK_SPEED_1GBIT_x100BPS #define DEFAULT_PARAM(x,y) if(x == MAXU32) { \ @@ -231,6 +232,7 @@ typedef struct InicConfig { typedef enum { INIC_UNINITIALIZED, + INIC_DEREGISTERING, INIC_REGISTERED, } InicState_t; diff --git a/trunk/ulp/inic/kernel/vnic_control.c b/trunk/ulp/inic/kernel/vnic_control.c index e6ed64f4..799c7a75 100644 --- a/trunk/ulp/inic/kernel/vnic_control.c +++ b/trunk/ulp/inic/kernel/vnic_control.c @@ -228,7 +228,6 @@ control_cleanup( control_timerStop( pControl ); ibqp_detach( &pControl->qp ); - ibqp_cleanup( &pControl->qp ); ibregion_cleanup( pControl->p_viport, &pControl->region ); if ( pControl->pLocalStorage ) @@ -270,7 +269,9 @@ control_processAsync( case INIC_STATUS_LINK_UP: VNIC_TRACE( VNIC_DBG_CTRL, ("IOC %d: Link Up\n", pControl->p_viport->ioc_num ) ); - + /* renew link speed info */ + pControl->p_viport->p_adapter->link_speed = + ntoh32( pPkt->cmd.reportStatus.statusInfo ); viport_linkUp( pControl->p_viport ); break; @@ -1247,8 +1248,9 @@ control_recvComplete( !p_viport->errored && !p_viport->disconnect ) { - status = FALSE; - viport_timer( p_viport, p_viport->port_config.hbInterval ); + InterlockedExchange( + (volatile LONG*)&p_viport->link_hb_state, + (LONG)LINK_HEARTBEATRSP ); } // Don't signal any waiting thread or start processing other updates. return; @@ -1331,7 +1333,7 @@ control_send( VNIC_ENTER ( VNIC_DBG_CTRL ); - ASSERT( !pControl->reqOutstanding ); + //ASSERT( !pControl->reqOutstanding ); if ( InterlockedCompareExchange( (volatile LONG*)&pControl->reqOutstanding, TRUE, FALSE ) == TRUE ) { diff --git a/trunk/ulp/inic/kernel/vnic_data.c b/trunk/ulp/inic/kernel/vnic_data.c index 3c9196cc..fc69fba0 100644 --- a/trunk/ulp/inic/kernel/vnic_data.c +++ b/trunk/ulp/inic/kernel/vnic_data.c @@ -39,10 +39,18 @@ static void _data_kickTimeoutHandler( void *context ); static BOOLEAN data_allocXmitBuffer(Data_t *pData, BufferPoolEntry_t **ppBpe, RdmaIo_t **ppRdmaIo, BOOLEAN *pLast); static void data_checkXmitBuffers(Data_t *pData); -static void data_rdmaPacket(Data_t *pData, BufferPoolEntry_t *pBpe, RdmaIo_t *pRdmaIo); -static NDIS_PACKET * -_data_recv_to_ndis_pkt( Data_t *pData, RdmaDest_t *pRdmaDest ); +static +ib_api_status_t +data_rdmaPacket( + Data_t *pData, + BufferPoolEntry_t *pBpe, + RdmaIo_t *pRdmaIo ); +static +NDIS_PACKET * +_data_recv_to_ndis_pkt( + Data_t *pData, + RdmaDest_t *pRdmaDest ); static void _data_allocBuffers( @@ -574,6 +582,10 @@ data_xmitPacket( } } } + /* hash operation seem quite expensive + * should figure out anther way to do this + * meanwhile let's embedded do it for us. + ******************************************** else if( p_eth_hdr->type == ETH_PROT_TYPE_IP && !( p_eth_hdr->dst.addr[0] & 0x01 ) ) { @@ -584,15 +596,19 @@ data_xmitPacket( if( ((ip_pkt_t*)p_buf)->hdr.prot == IP_PROT_UDP || ((ip_pkt_t*)p_buf)->hdr.prot == IP_PROT_TCP ) { - /* use socket src port + dest port to generate hash value - * for link aggregation distribution function. - */ - pRdmaIo->p_trailer->connectionHashAndValid = 0x40 | - ((uint8_t)((ip_pkt_t*)p_buf)->prot.tcp.src_port + - (uint8_t)((ip_pkt_t*)p_buf)->prot.tcp.dst_port ) & 0x3f; + // use socket src port + dest port to generate hash value + // for link aggregation distribution function. + // + pRdmaIo->p_trailer->connectionHashAndValid = CHV_VALID | + ((uint8_t)ntoh16(((ip_pkt_t*)p_buf)->prot.tcp.src_port ) + + (uint8_t)ntoh16(((ip_pkt_t*)p_buf)->prot.tcp.dst_port )) & CHV_HASH_MASH; + pRdmaIo->p_trailer->pktFlags |= PF_CHASH_VALID; } + else + pRdmaIo->p_trailer->pktFlags &= ~PF_CHASH_VALID; } } + **********************/ } pRdmaIo->p_trailer->txChksumFlags = _tx_chksum_flags( p_packet ); @@ -611,7 +627,12 @@ data_xmitPacket( pRdmaIo->io.wrq.num_ds =p_sgl->NumberOfElements + 1; - data_rdmaPacket( pData, pBpe, pRdmaIo ); + if( data_rdmaPacket( pData, pBpe, pRdmaIo ) != IB_SUCCESS ) + { + VNIC_TRACE( VNIC_DBG_ERROR, + ("RDMA WRITE Failed\n")); + return FALSE; + } if( p_xmitPool->sendKicks ) { @@ -749,6 +770,13 @@ _data_receivedKick( pData->p_viport->stats.ifInOk += num_pkts; } + if( pData->p_viport->data.connected == TRUE && + !pData->p_viport->errored ) + { + _data_allocBuffers( pData, FALSE ); + _data_sendFreeRecvBuffers( pData ); + } + VNIC_EXIT( VNIC_DBG_DATA ); return; } @@ -762,7 +790,6 @@ _data_xmitComplete( XmitPool_t *p_xmitPool = &pData->xmitPool; NDIS_PACKET *p_packet; NDIS_STATUS ndis_status; - LIST_ENTRY *p_list_item; VNIC_ENTER( VNIC_DBG_DATA ); @@ -792,22 +819,10 @@ _data_xmitComplete( } } - if( !pIo->pViport->p_netpath->carrier ) + if( !pData->p_viport->errored ) { - while( ( p_list_item = NdisInterlockedRemoveHeadList( - &pIo->pViport->send_pending_list, - &pIo->pViport->pending_list_lock ) ) != NULL ) - { - p_packet = VNIC_PACKET_FROM_LIST_ITEM( p_list_item ); - NDIS_SET_PACKET_STATUS( p_packet, NDIS_STATUS_FAILURE ); - NdisMSendComplete( &pIo->pViport->p_adapter->h_handle, - p_packet, NDIS_STATUS_FAILURE ); - pIo->pViport->stats.ifOutErrors++; - } + data_checkXmitBuffers( pData ); } - - data_checkXmitBuffers( pData ); - VNIC_EXIT( VNIC_DBG_DATA ); return; } @@ -947,7 +962,8 @@ data_checkXmitBuffers( return; } -static void +static +ib_api_status_t data_rdmaPacket( IN Data_t *pData, IN BufferPoolEntry_t *pBpe, @@ -990,14 +1006,14 @@ data_rdmaPacket( { VNIC_TRACE(VNIC_DBG_ERROR, ("Failed sending data to EIOC\n") ); - viport_failure( pData->p_viport ); - return; + return IB_ERROR; } #ifdef VNIC_STATISTIC pData->statistics.xmitNum++; #endif /* VNIC_STATISTIC */ VNIC_EXIT( VNIC_DBG_DATA ); + return IB_SUCCESS; } static NDIS_PACKET * @@ -1188,7 +1204,8 @@ _data_incomingRecv( p_recvPool->kickOnFree = TRUE; } /* we do not want to indicate packet if no filter is set */ - if( pData->p_viport->p_adapter->packet_filter ) + if( pData->p_viport->p_adapter->packet_filter && + p_recvPool->numPostedBufs > 0 ) { p_packet = _data_recv_to_ndis_pkt( pData, pRdmaDest ); if ( p_packet != NULL ) @@ -1233,12 +1250,6 @@ vnic_return_packet( InsertTailList( &p_viport->data.recvPool.availRecvBufs, &p_rdma_dest->listPtrs ); - if( p_viport->data.connected == TRUE && - !p_viport->errored ) - { - _data_allocBuffers( &p_viport->data, FALSE ); - _data_sendFreeRecvBuffers( &p_viport->data ); - } } static void _data_return_recv( @@ -1268,13 +1279,14 @@ _data_sendFreeRecvBuffers( VNIC_ENTER( VNIC_DBG_DATA ); - for ( numToSend = p_recvPool->szFreeBundle; + for ( numToSend = MIN_EIOC_UPDATE_SZ; numToSend <= p_recvPool->numFreeBufs; - numToSend += p_recvPool->szFreeBundle ) + numToSend += MIN_EIOC_UPDATE_SZ ) { + /* Handle multiple bundles as one when possible. */ - nextIncrement = numToSend + p_recvPool->szFreeBundle; - if ( ( nextIncrement <= p_recvPool->numFreeBufs ) + nextIncrement = numToSend + MIN_EIOC_UPDATE_SZ; + if (( nextIncrement <= p_recvPool->numFreeBufs ) && ( p_recvPool->nextFreeBuf + nextIncrement <= p_recvPool->eiocPoolSz ) ) { continue; @@ -1316,7 +1328,7 @@ _data_sendFreeRecvBuffers( ("IOC %d: Unable to allocate receive buffers\n", pData->p_viport->ioc_num ) ); - viport_failure( pData->p_viport ); + //viport_failure( pData->p_viport ); } VNIC_EXIT( VNIC_DBG_DATA ); } @@ -1328,6 +1340,15 @@ data_cleanup( { VNIC_ENTER( VNIC_DBG_DATA ); + VNIC_TRACE(VNIC_DBG_INIT, + ("IOC[%d]data cleanup\n", pData->p_viport->ioc_num )); + + if( pData->p_recv_bufs ) + { + NdisFreeMemory( pData->p_recv_bufs, pData->recv_bufs_sz, 0 ); + pData->p_recv_bufs = NULL; + } + if( pData->recvPool.recv_pkt_array ) { cl_free( pData->recvPool.recv_pkt_array ); @@ -1349,20 +1370,14 @@ data_cleanup( if ( pData->h_recv_pkt_pool ) { - while( NdisPacketPoolUsage(pData->h_recv_pkt_pool) != 0) + if( NdisPacketPoolUsage(pData->h_recv_pkt_pool) != 0) { VNIC_TRACE( VNIC_DBG_WARN, ("Recv packet pool is not empty!!!\n") ); - NdisMSleep(100); } NdisFreePacketPool( pData->h_recv_pkt_pool ); pData->h_recv_pkt_pool = NULL; } - if( pData->p_recv_bufs ) - { - NdisFreeMemory( pData->p_recv_bufs, pData->recv_bufs_sz, 0 ); - pData->p_recv_bufs = NULL; - } // clear Qp struct for reuse cl_memclr( &pData->qp, sizeof( IbQp_t) ); diff --git a/trunk/ulp/inic/kernel/vnic_debug.h b/trunk/ulp/inic/kernel/vnic_debug.h index 37b22526..9a69dd47 100644 --- a/trunk/ulp/inic/kernel/vnic_debug.h +++ b/trunk/ulp/inic/kernel/vnic_debug.h @@ -66,7 +66,7 @@ extern uint32_t g_vnic_dbg_lvl; #define VNIC_DBG_ERROR CL_DBG_ERROR #define VNIC_DBG_ALL CL_DBG_ALL -#define VNIC_DEBUG_FLAGS ( VNIC_DBG_ERROR | VNIC_DBG_WARN ) +#define VNIC_DEBUG_FLAGS ( VNIC_DBG_ERROR | VNIC_DBG_WARN | VNIC_DBG_INFO | VNIC_DBG_PNP | VNIC_DBG_INIT ) /* Enter and exit macros automatically add VNIC_DBG_FUNC bit */ #define VNIC_ENTER( lvl ) \ CL_ENTER( (lvl | VNIC_DBG_FUNC), g_vnic_dbg_lvl ) diff --git a/trunk/ulp/inic/kernel/vnic_driver.c b/trunk/ulp/inic/kernel/vnic_driver.c index 6b29df49..cba109e2 100644 --- a/trunk/ulp/inic/kernel/vnic_driver.c +++ b/trunk/ulp/inic/kernel/vnic_driver.c @@ -128,7 +128,7 @@ DriverEntry( characteristics.MajorNdisVersion = MAJOR_NDIS_VERSION; characteristics.MinorNdisVersion = MINOR_NDIS_VERSION; - characteristics.CheckForHangHandler = vnic_check_for_hang; + //characteristics.CheckForHangHandler = vnic_check_for_hang; characteristics.HaltHandler = vnic_halt; characteristics.InitializeHandler = vnic_initialize; characteristics.QueryInformationHandler = vnic_oid_query_info; @@ -456,7 +456,10 @@ vnic_oid_query_info( if( p_adapter->p_currentPath->carrier ) { - info32 = DEFAULT_LINK_SPEED_x100BPS; /* x 100bps units */ + /* if we get link speed value - it is in Mbps units - have to convert to 100bps*/ + info32 = ( p_adapter->link_speed )? + ( p_adapter->link_speed * LINK_SPEED_1MBIT_x100BPS ): + DEFAULT_LINK_SPEED_x100BPS; } else { @@ -878,7 +881,7 @@ vnic_oid_query_info( break; case OID_802_3_MULTICAST_LIST: - VNIC_TRACE( VNIC_DBG_INFO, + VNIC_TRACE( VNIC_DBG_OID, (" received query for OID_802_3_MULTICAST_LIST\n" ) ); if (!p_adapter->p_currentPath->carrier || @@ -887,7 +890,7 @@ vnic_oid_query_info( p_adapter->pending_query = TRUE; p_adapter->query_oid = oid_info; - VNIC_TRACE( VNIC_DBG_INFO, + VNIC_TRACE( VNIC_DBG_OID, ("returning NDIS_STATUS_PENDING\n") ); status = NDIS_STATUS_PENDING; } @@ -903,7 +906,7 @@ vnic_oid_query_info( break; case OID_802_3_MAXIMUM_LIST_SIZE: - VNIC_TRACE( VNIC_DBG_INFO, + VNIC_TRACE( VNIC_DBG_OID, (" received query for OID_802_3_MAXIMUM_LIST_SIZE\n" ) ); if ( !p_adapter->macSet ) { @@ -1310,7 +1313,7 @@ vnic_oid_set_info( { /* Required General */ case OID_GEN_CURRENT_PACKET_FILTER: - VNIC_TRACE( VNIC_DBG_INFO, + VNIC_TRACE( VNIC_DBG_OID, (" IOC %d received set for OID_GEN_CURRENT_PACKET_FILTER, %#x\n", p_adapter->p_currentPath->pViport->ioc_num, *(uint32_t*)info_buf )); @@ -1367,19 +1370,19 @@ vnic_oid_set_info( status = NDIS_STATUS_NOT_ACCEPTED; break; } - VNIC_TRACE( VNIC_DBG_INFO, + VNIC_TRACE( VNIC_DBG_OID, (" IOC %d received set for OID_802_3_MULTICAST_LIST\n", p_adapter->p_currentPath->pViport->ioc_num ) ); if( info_buf_len > MAX_MCAST * sizeof(mac_addr_t) ) { - VNIC_TRACE( VNIC_DBG_INFO, + VNIC_TRACE( VNIC_DBG_OID, (" OID_802_3_MULTICAST_LIST - Multicast list full.\n" ) ); status = NDIS_STATUS_MULTICAST_FULL; *p_bytes_needed = MAX_MCAST * sizeof(mac_addr_t); } else if( info_buf_len % sizeof(mac_addr_t) ) { - VNIC_TRACE( VNIC_DBG_INFO, + VNIC_TRACE( VNIC_DBG_OID, (" OID_802_3_MULTICAST_LIST - Invalid input buffer length.\n" ) ); status = NDIS_STATUS_INVALID_DATA; } @@ -1495,7 +1498,6 @@ vnic_send_packets( netpath_xmitPacket( p_adapter->p_currentPath, packet_array[packet_num] ); } - VNIC_EXIT( VNIC_DBG_SEND ); } @@ -1515,7 +1517,7 @@ vnic_pnp_notify( p_adapter = (vnic_adapter_t*)adapter_context; - VNIC_TRACE( VNIC_DBG_PNP, ("Event %d\n", pnp_event) ); + VNIC_TRACE( VNIC_DBG_PNP, ("Event %d IOC[%d]\n", pnp_event, p_adapter->ioc_num ) ); if( pnp_event != NdisDevicePnPEventPowerProfileChanged ) { InterlockedExchange( (volatile LONG *)&p_adapter->pnp_state, IB_PNP_IOC_REMOVE ); @@ -1530,9 +1532,24 @@ void vnic_shutdown( IN PVOID adapter_context ) { + vnic_adapter_t *p_adapter; VNIC_ENTER( VNIC_DBG_INIT ); + p_adapter = (vnic_adapter_t *)adapter_context; + + if( p_adapter ) + { + VNIC_TRACE( VNIC_DBG_INIT, + ("IOC[%d]Shutdown -early retierement\n", p_adapter->ioc_num )); - UNUSED_PARAM( adapter_context ); + if( p_adapter->p_currentPath && + p_adapter->p_currentPath->pViport ) + { + viport_stopXmit( p_adapter->p_currentPath->pViport ); + viport_linkDown( p_adapter->p_currentPath->pViport ); + InterlockedExchange( &p_adapter->p_currentPath->carrier, (LONG)FALSE ); + } + vnic_destroy_adapter( p_adapter ); + } VNIC_EXIT( VNIC_DBG_INIT ); } @@ -1579,7 +1596,7 @@ vnic_resume_set_oids( switch( set_oid.oid ) { case OID_GEN_CURRENT_PACKET_FILTER: - VNIC_TRACE( VNIC_DBG_INFO, + VNIC_TRACE( VNIC_DBG_OID, (" IOC %d resume PACKET_FILTER set \n", p_adapter->p_currentPath->pViport->ioc_num ) ); /* Validation already performed in the SetInformation path. */ @@ -1593,7 +1610,7 @@ vnic_resume_set_oids( break; case OID_802_3_MULTICAST_LIST: - VNIC_TRACE( VNIC_DBG_INFO, + VNIC_TRACE( VNIC_DBG_OID, (" IOC %d resume MULTICAST_LIST\n", p_adapter->p_currentPath->pViport->ioc_num ) ); @@ -1893,7 +1910,7 @@ _vnic_process_packet_filter( ++p_adapter->pending_set; status = _viport_process_query( p_adapter->p_viport, FALSE ); - VNIC_TRACE( VNIC_DBG_INFO, + VNIC_TRACE( VNIC_DBG_OID, ("LINK CONFIG status %x\n", status )); if( status != NDIS_STATUS_PENDING ) { diff --git a/trunk/ulp/inic/kernel/vnic_ib.c b/trunk/ulp/inic/kernel/vnic_ib.c index 940d4655..020e8218 100644 --- a/trunk/ulp/inic/kernel/vnic_ib.c +++ b/trunk/ulp/inic/kernel/vnic_ib.c @@ -180,21 +180,20 @@ ibregion_cleanup( IN viport_t *p_viport, IN IbRegion_t *pRegion ) { - void *mr_handle; ib_api_status_t ib_status; VNIC_ENTER( VNIC_DBG_IB ); - if( ( mr_handle = InterlockedExchangePointer( (void *)&pRegion->h_mr, NULL )) != NULL ) + if( pRegion->h_mr != NULL ) { - ib_status = p_viport->p_adapter->ifc.dereg_mr( (ib_mr_handle_t)mr_handle ); + ib_status = p_viport->p_adapter->ifc.dereg_mr( pRegion->h_mr ); if ( ib_status != IB_SUCCESS ) { VNIC_TRACE_EXIT( VNIC_DBG_ERROR, - ("Dereg MR failed status %s(%d)\n", - p_viport->p_adapter->ifc.get_err_str(ib_status), ib_status ) ); + ("Dereg MR failed status (%d)\n", ib_status )); return; } + InterlockedExchangePointer( (void *)&pRegion->h_mr, NULL ); } VNIC_EXIT( VNIC_DBG_IB ); @@ -497,11 +496,10 @@ ibqp_detach( VNIC_ENTER( VNIC_DBG_IB ); - NdisAcquireSpinLock( &pQp->qpLock ); - - if( pQp->qpState == IB_ATTACHED ) + if( InterlockedCompareExchange( &pQp->qpState, + IB_DETACHING, IB_ATTACHED ) == IB_ATTACHED ) { - InterlockedExchange ( &pQp->qpState, IB_DETACHING ); + NdisAcquireSpinLock( &pQp->qpLock ); cm_dreq.h_qp = pQp->qp; cm_dreq.qp_type = IB_QPT_RELIABLE_CONN; @@ -515,9 +513,17 @@ ibqp_detach( (" cm_dreq failed status %s\n", pQp->pViport->p_adapter->ifc.get_err_str( ib_status ))); } + + NdisReleaseSpinLock( &pQp->qpLock ); + ib_status = pQp->pViport->p_adapter->ifc.destroy_qp( pQp->qp, NULL ); + if ( ib_status != IB_SUCCESS ) + { + VNIC_TRACE( VNIC_DBG_ERROR, + (" QP destroy failed status %s\n", + pQp->pViport->p_adapter->ifc.get_err_str( ib_status ))); + } } - NdisReleaseSpinLock( &pQp->qpLock ); VNIC_EXIT( VNIC_DBG_IB ); return; @@ -730,7 +736,7 @@ err: } -#define WC_LIST_SIZE_TO_POLL 4 +#define WC_LIST_SIZE_TO_POLL 32 static void _ib_qpCompletion( IN IbQp_t *pQp ) @@ -780,50 +786,33 @@ _ib_qpCompletion( { pIo = (Io_t *)(uintn_t)p_done_wc->wr_id; - if (pIo) + /* keep completion status for proper ndis packet return status */ + pIo->wc_status = p_done_wc->status; + + if( p_done_wc->status != IB_WCS_SUCCESS ) { - /* keep completion status for proper ndis packet return status */ - pIo->wc_status = p_done_wc->status; -#ifdef VNIC_STATISTIC - if (pIo->type == RECV) - { - pIo->time = compTime; - } - else if (pIo->type == RDMA) - { - pQp->statistics.rdmaCompTime += compTime - pIo->time; - pQp->statistics.rdmaCompIos++; - } - else if (pIo->type == SEND) - { - pQp->statistics.sendCompTime += compTime - pIo->time; - pQp->statistics.sendCompIos++; - } - pQp->statistics.numIos++; - if ( ++compNum > pQp->statistics.maxIos) - { - pQp->statistics.maxIos = compNum; - } -#endif /* VNIC_STATISTIC */ VNIC_TRACE( VNIC_DBG_IB, - ("ib_workCompletion: WcType = %d, Status = %d, Length = %d\n", - p_done_wc->wc_type, - p_done_wc->status, - ( p_done_wc->wc_type == IB_WC_RECV )? p_done_wc->length : 0 ) ); + ("Failed Completion: WcType = %d, Status = %d, Length = %d\n", + p_done_wc->wc_type, + p_done_wc->status, + ( p_done_wc->wc_type == IB_WC_RECV )? p_done_wc->length : 0 ) ); - if( pIo->pRoutine ) + if( pIo && pIo->type == RDMA ) { + VNIC_TRACE( VNIC_DBG_ERROR, + ("Failed RDMA Op, WC type = %d, WC status = %d IO type %d\n", + p_done_wc->wc_type, p_done_wc->status, pIo->type )); + + /* we must complete send packets */ (*pIo->pRoutine)( pIo ); } } - - if (p_done_wc->status != IB_WCS_SUCCESS ) + else if(pIo) { - VNIC_TRACE( VNIC_DBG_IB, - ("Failed completion, type = %d, status = %d (%s)\n", - p_done_wc->wc_type, - p_done_wc->status, - pQp->pViport->p_adapter->ifc.get_wc_status_str (p_done_wc->status) ) ); + if( pIo->pRoutine ) + { + (*pIo->pRoutine)( pIo ); + } } p_done_wc = p_done_wc->p_next; @@ -836,6 +825,7 @@ _ib_qpCompletion( VNIC_TRACE( VNIC_DBG_ERROR, ("Rearm CQ failed status %d(%s)\n", ib_status, pQp->pViport->p_adapter->ifc.get_err_str( ib_status )) ); + viport_failure( pQp->pViport ); } return; } @@ -861,28 +851,27 @@ void ib_asyncEvent( IN ib_async_event_rec_t *pEventRecord ) { - IbQp_t *pQp; + vnic_adapter_t *p_adapter; VNIC_ENTER ( VNIC_DBG_IB ); if ( pEventRecord ) { + p_adapter = (vnic_adapter_t * __ptr64 )pEventRecord->context; + switch ( pEventRecord->code ) { case IB_AE_QP_COMM: case IB_AE_QP_FATAL: - - pQp = (IbQp_t * __ptr64 )pEventRecord->context; - if (pQp) - { VNIC_TRACE( VNIC_DBG_ERROR, - ("Async Event %d QP State %#x\n", - pEventRecord->code, pQp->qpState )); - } + ("Async Event %d\n", pEventRecord->code )); break; + case IB_AE_PORT_DOWN: default: VNIC_TRACE( VNIC_DBG_ERROR, ("Async Event %d received\n", pEventRecord->code) ); + if( p_adapter && p_adapter->p_viport ) + viport_stopXmit( p_adapter->p_viport ); break; } } diff --git a/trunk/ulp/inic/kernel/vnic_netpath.c b/trunk/ulp/inic/kernel/vnic_netpath.c index 65926a7e..9d2af3b1 100644 --- a/trunk/ulp/inic/kernel/vnic_netpath.c +++ b/trunk/ulp/inic/kernel/vnic_netpath.c @@ -119,7 +119,10 @@ void netpath_restartXmit( if (pNetpath == pNetpath->p_adapter->p_currentPath ) { - InterlockedCompareExchange( &pNetpath->p_adapter->xmitStarted, 1, 0 ); + if( !pNetpath->pViport->errored ) + { + InterlockedCompareExchange( &pNetpath->p_adapter->xmitStarted, 1, 0 ); + } } #ifdef INIC_STATISTICS if (pNetpath->p_adapter->statistics.xmitRef != 0) diff --git a/trunk/ulp/inic/kernel/vnic_viport.c b/trunk/ulp/inic/kernel/vnic_viport.c index d6e823dd..e8238f45 100644 --- a/trunk/ulp/inic/kernel/vnic_viport.c +++ b/trunk/ulp/inic/kernel/vnic_viport.c @@ -217,10 +217,11 @@ viport_cleanup( if( p_viport ) { + VNIC_TRACE(VNIC_DBG_INIT, + ("IOC[%d]viport cleanup\n", p_viport->ioc_num )); InterlockedExchange( &p_viport->p_adapter->carrier, FALSE ); InterlockedExchange( &p_viport->p_netpath->carrier, FALSE ); viport_timerStop( p_viport ); - data_disconnect( &p_viport->data ); control_cleanup( &p_viport->control ); @@ -235,6 +236,9 @@ viport_cleanup( cl_timer_destroy( &p_viport->timer ); + InterlockedExchange( (volatile LONG *)&p_viport->p_adapter->state, + INIC_UNINITIALIZED ); + NdisFreeMemory ( p_viport, sizeof(viport_t), 0 ); } VNIC_EXIT( VNIC_DBG_VIPORT ); @@ -253,7 +257,7 @@ viport_setPath( VNIC_ENTER( VNIC_DBG_FUNC ); - VNIC_TRACE( VNIC_DBG_INFO, + VNIC_TRACE( VNIC_DBG_PNP, ("Using SLID=%d DLID=%d Target:%s\n", cl_ntoh16( p_path->slid ), cl_ntoh16( p_path->dlid ), @@ -527,9 +531,10 @@ viport_xmitPacket( IN viport_t* const p_viport, IN NDIS_PACKET* const p_packet ) { - BOOLEAN status = FALSE; + BOOLEAN status = TRUE; KIRQL flags; LIST_ENTRY *p_list_item; + NDIS_PACKET *p_packet_from_list; VNIC_ENTER( VNIC_DBG_VIPORT ); @@ -540,21 +545,59 @@ viport_xmitPacket( VNIC_LIST_ITEM_FROM_PACKET( p_packet ), &p_viport->pending_list_lock ); } - else + else { + KeAcquireSpinLock( &p_viport->lock, &flags ); + while( ( p_list_item = NdisInterlockedRemoveHeadList( - &p_viport->send_pending_list, - &p_viport->pending_list_lock ) ) != NULL ) + &p_viport->send_pending_list, + &p_viport->pending_list_lock ) ) != NULL ) { - KeAcquireSpinLock( &p_viport->lock, &flags ); - status = data_xmitPacket( &p_viport->data, - VNIC_PACKET_FROM_LIST_ITEM( p_list_item )); + p_packet_from_list = VNIC_PACKET_FROM_LIST_ITEM( p_list_item ); + + status = data_xmitPacket( &p_viport->data, p_packet_from_list ); + if( !status ) + { + VNIC_TRACE( VNIC_DBG_ERROR, + ("IOC[%d] Xmit Pending Packet failed\n", p_viport->ioc_num )); + /* put it back on pending list - will complete it on cleanup */ + NdisInterlockedInsertTailList( + &p_viport->send_pending_list, + VNIC_LIST_ITEM_FROM_PACKET( p_packet_from_list ), + &p_viport->pending_list_lock ); + viport_stopXmit( p_viport ); + break; + } + } + + if( !status ) + { /*do not try to send, just exit */ + NdisInterlockedInsertTailList( + &p_viport->send_pending_list, + VNIC_LIST_ITEM_FROM_PACKET( p_packet ), + &p_viport->pending_list_lock ); + viport_stopXmit( p_viport ); + KeReleaseSpinLock( &p_viport->lock, flags ); + VNIC_EXIT( VNIC_DBG_VIPORT ); + return status; } /* just send a packet */ - KeAcquireSpinLock( &p_viport->lock, &flags ); status = data_xmitPacket( &p_viport->data, p_packet ); + + if( !status ) + { + VNIC_TRACE( VNIC_DBG_ERROR, + ("IOC[%d] XmitPacket failed\n", p_viport->ioc_num )); + /* put it on pending list - will complete it on cleanup */ + NdisInterlockedInsertTailList( + &p_viport->send_pending_list, + VNIC_LIST_ITEM_FROM_PACKET( p_packet ), + &p_viport->pending_list_lock ); + viport_stopXmit( p_viport ); + } + KeReleaseSpinLock( &p_viport->lock, flags ); } @@ -630,6 +673,7 @@ viport_failure( if( InterlockedExchange( (volatile LONG*)&p_viport->errored, TRUE ) == FALSE ) { + viport_stopXmit( p_viport ); viport_linkDown( p_viport ); } @@ -645,20 +689,19 @@ viport_timeout( CL_ASSERT( p_viport ); InterlockedExchange( &p_viport->timerActive, FALSE ); + // did we get response from previous query ? + if( p_viport->link_hb_state != LINK_HEARTBEATRSP ) + { + VNIC_TRACE( VNIC_DBG_ERROR, + ("IOC[%d] NO HEARTBEAT RESPONSE\n", p_viport->ioc_num )); + viport_failure( p_viport ); + return; + } if( p_viport && p_viport->data.connected && !p_viport->errored ) { - // TODO: What about send failure? - if( !p_viport->control.reqOutstanding ) - { - control_heartbeatReq( &p_viport->control, - p_viport->port_config.hbTimeout ); - } - else - { /* send WQE is taken, send heartbeat later */ - viport_timer( p_viport, p_viport->port_config.hbInterval ); - } + viport_timer( p_viport, p_viport->port_config.hbInterval ); } } @@ -668,11 +711,29 @@ viport_timer( IN viport_t *p_viport, IN int timeout ) { + ib_api_status_t ib_status; + VNIC_ENTER( VNIC_DBG_VIPORT ); - InterlockedExchange( &p_viport->timerActive, TRUE ); - cl_timer_start( &p_viport->timer, (uint32_t)timeout ); + if( !p_viport->control.reqOutstanding ) + { + InterlockedExchange( &p_viport->timerActive, TRUE ); + p_viport->link_hb_state = LINK_HEARTBEATREQ; + + cl_timer_start( &p_viport->timer, (uint32_t)timeout ); + ib_status = control_heartbeatReq( &p_viport->control, + p_viport->port_config.hbTimeout ); + + if( ib_status != IB_SUCCESS ) + { + viport_timerStop( p_viport ); + VNIC_TRACE( VNIC_DBG_ERROR, + ("IOC[%d] HEARTBEAT send failed\n", p_viport->ioc_num )); + viport_failure( p_viport ); + return; + } + } VNIC_EXIT( VNIC_DBG_VIPORT ); } @@ -759,9 +820,10 @@ viport_control_connect( ib_status = ibqp_connect( &p_viport->control.qp ); if( ib_status != IB_SUCCESS ) { - VNIC_TRACE( VNIC_DBG_INFO, + VNIC_TRACE_EXIT( VNIC_DBG_ERROR, ("control QP connect failed\n")); - goto err1; + control_cleanup( &p_viport->control ); + return ib_status; } InterlockedExchange( (volatile LONG*)&p_viport->linkState, @@ -770,18 +832,21 @@ viport_control_connect( ib_status = control_initInicReq( &p_viport->control ); if( ib_status != IB_SUCCESS ) { - VNIC_TRACE( VNIC_DBG_INFO, ("CMD_INIT_INIC REQ failed\n") ); - goto err2; + VNIC_TRACE_EXIT( VNIC_DBG_ERROR, + ("CMD_INIT_INIC REQ failed\n") ); + control_cleanup( &p_viport->control ); + return ib_status; } cl_event_wait_on( &p_viport->conn_event, (p_viport->control.p_conf->rspTimeout << 11), TRUE ); if( p_viport->linkState != LINK_INITINICRSP ) { - VNIC_TRACE( VNIC_DBG_INFO, + VNIC_TRACE_EXIT( VNIC_DBG_ERROR, ("CMD_INIT_INIC RSP failed\n")); ib_status = IB_INSUFFICIENT_RESOURCES; - goto err2; + control_cleanup( &p_viport->control ); + return ib_status; } vnic_resume_oids( p_viport->p_adapter ); @@ -789,11 +854,8 @@ viport_control_connect( ib_status = viport_initMacAddresses( p_viport ); if( ib_status != IB_SUCCESS ) { - VNIC_TRACE( VNIC_DBG_INFO, + VNIC_TRACE( VNIC_DBG_ERROR, ("Init MAC Addresses failed\n")); -err2: - control_resetReq( &p_viport->control ); -err1: control_cleanup( &p_viport->control ); } @@ -917,7 +979,7 @@ _viport_process_query( if ( p_viport->state != VIPORT_CONNECTED || p_viport->errored != 0 ) { - VNIC_TRACE_EXIT( VNIC_DBG_WARN, ("Invalid state or error.\n") ); + VNIC_TRACE_EXIT( VNIC_DBG_INFO, ("Invalid state or error.\n") ); return NDIS_STATUS_NOT_ACCEPTED; } @@ -950,7 +1012,7 @@ _viport_process_query( // Handle update bits one at a time. if( p_viport->updates & NEED_ADDRESS_CONFIG ) { - VNIC_TRACE( VNIC_DBG_INFO, + VNIC_TRACE( VNIC_DBG_OID, ("QUERY NEED_ADDRESS_CONFIG\n")); KeAcquireSpinLock(&p_viport->lock, &irql ); p_viport->linkState = LINK_CONFIGADDRSREQ; @@ -968,7 +1030,7 @@ _viport_process_query( } else if( p_viport->updates & NEED_LINK_CONFIG ) { - VNIC_TRACE( VNIC_DBG_INFO, + VNIC_TRACE( VNIC_DBG_OID, ("QUERY NEED_LINK_CONFIG\n")); KeAcquireSpinLock(&p_viport->lock, &irql ); @@ -1001,7 +1063,7 @@ _viport_process_query( else if( p_viport->updates & NEED_STATS ) { // TODO: This is dead code. - VNIC_TRACE( VNIC_DBG_INFO, + VNIC_TRACE( VNIC_DBG_OID, ("QUERY NEED_STATS\n")); KeAcquireSpinLock( &p_viport->lock, &irql ); diff --git a/trunk/ulp/inic/kernel/vnic_viport.h b/trunk/ulp/inic/kernel/vnic_viport.h index 6023e3f1..f4da6432 100644 --- a/trunk/ulp/inic/kernel/vnic_viport.h +++ b/trunk/ulp/inic/kernel/vnic_viport.h @@ -168,6 +168,7 @@ typedef struct _viport { // State machine state? LinkState_t linkState; + LinkState_t link_hb_state; Inic_CmdReportStatisticsRsp_t stats; uint64_t lastStatsTime; -- 2.41.0