From: sleybo Date: Wed, 7 Feb 2007 13:32:45 +0000 (+0000) Subject: git-svn-id: svn://openib.tc.cornell.edu/gen1@588 ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86 X-Git-Url: https://openfabrics.org/gitweb/?a=commitdiff_plain;h=e7970bb1df5067dc9959c2ceaf83fd8e6c243704;p=~shefty%2Frdma-win.git git-svn-id: svn://openib.tc.cornell.edu/gen1@588 ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86 --- diff --git a/trunk/core/al/kernel/al_smi.c b/trunk/core/al/kernel/al_smi.c index ca4adb82..a2fc5f37 100644 --- a/trunk/core/al/kernel/al_smi.c +++ b/trunk/core/al/kernel/al_smi.c @@ -121,7 +121,7 @@ loopback_mad( IN al_mad_wr_t* const p_mad_wr ); static ib_api_status_t -process_subn_mad( +__process_subn_mad( IN spl_qp_svc_t* p_spl_qp_svc, IN al_mad_wr_t* const p_mad_wr ); @@ -552,7 +552,8 @@ create_spl_qp_svc( /* Initialize the send and receive queues. */ cl_qlist_init( &p_spl_qp_svc->send_queue ); cl_qlist_init( &p_spl_qp_svc->recv_queue ); - + cl_spinlock_init(&p_spl_qp_svc->cache_lock); + #if defined( CL_USE_MUTEX ) /* Initialize async callbacks and flags for send/receive processing. */ p_spl_qp_svc->send_async_queued = FALSE; @@ -1388,8 +1389,8 @@ local_mad_send( case IB_MCLASS_SUBN_DIR: case IB_MCLASS_SUBN_LID: //DO not use the cache in order to force Mkey check - //status = process_subn_mad( p_spl_qp_svc, p_mad_wr ); - status = IB_NOT_DONE; + status = __process_subn_mad( p_spl_qp_svc, p_mad_wr ); + //status = IB_NOT_DONE; break; default: @@ -1540,8 +1541,129 @@ loopback_mad( } +static void +__update_guid_info( + IN spl_qp_cache_t* const p_cache, + IN const ib_smp_t* const p_mad ) +{ + uint32_t idx; + + /* Get the table selector from the attribute */ + idx = cl_ntoh32( p_mad->attr_mod ); + + /* + * We only get successful MADs here, so invalid settings + * shouldn't happen. + */ + CL_ASSERT( idx <= 31 ); + + cl_memcpy( &p_cache->guid_block[idx].tbl, + ib_smp_get_payload_ptr( p_mad ), + sizeof(ib_guid_info_t) ); + p_cache->guid_block[idx].valid = TRUE; +} + + +static void +__update_pkey_table( + IN spl_qp_cache_t* const p_cache, + IN const ib_smp_t* const p_mad ) +{ + uint16_t idx; + + /* Get the table selector from the attribute */ + idx = ((uint16_t)cl_ntoh32( p_mad->attr_mod )); + + CL_ASSERT( idx <= 2047 ); + + cl_memcpy( &p_cache->pkey_tbl[idx].tbl, + ib_smp_get_payload_ptr( p_mad ), + sizeof(ib_pkey_table_info_t) ); + p_cache->pkey_tbl[idx].valid = TRUE; +} + + +static void +__update_sl_vl_table( + IN spl_qp_cache_t* const p_cache, + IN const ib_smp_t* const p_mad ) +{ + cl_memcpy( &p_cache->sl_vl.tbl, + ib_smp_get_payload_ptr( p_mad ), + sizeof(ib_slvl_table_t) ); + p_cache->sl_vl.valid = TRUE; +} + + +static void +__update_vl_arb_table( + IN spl_qp_cache_t* const p_cache, + IN const ib_smp_t* const p_mad ) +{ + uint16_t idx; + + /* Get the table selector from the attribute */ + idx = ((uint16_t)(cl_ntoh32( p_mad->attr_mod ) >> 16)) - 1; + + CL_ASSERT( idx <= 3 ); + + cl_memcpy( &p_cache->vl_arb[idx].tbl, + ib_smp_get_payload_ptr( p_mad ), + sizeof(ib_vl_arb_table_t) ); + p_cache->vl_arb[idx].valid = TRUE; +} + + + +void +spl_qp_svc_update_cache( + IN spl_qp_svc_t *p_spl_qp_svc, + IN ib_smp_t *p_mad ) +{ + + + + CL_ASSERT( p_spl_qp_svc ); + CL_ASSERT( p_mad ); + CL_ASSERT( p_mad->mgmt_class == IB_MCLASS_SUBN_DIR || + p_mad->mgmt_class == IB_MCLASS_SUBN_LID); + CL_ASSERT(!p_mad->status); + + cl_spinlock_acquire(&p_spl_qp_svc->cache_lock); + + switch( p_mad->attr_id ) + { + case IB_MAD_ATTR_GUID_INFO: + __update_guid_info( + &p_spl_qp_svc->cache, p_mad ); + break; + + case IB_MAD_ATTR_P_KEY_TABLE: + __update_pkey_table( + &p_spl_qp_svc->cache, p_mad ); + break; + + case IB_MAD_ATTR_SLVL_TABLE: + __update_sl_vl_table( + &p_spl_qp_svc->cache, p_mad ); + break; + + case IB_MAD_ATTR_VL_ARBITRATION: + __update_vl_arb_table( + &p_spl_qp_svc->cache, p_mad ); + break; + + default: + break; + } + + cl_spinlock_release(&p_spl_qp_svc->cache_lock); +} + + + static ib_api_status_t -process_node_info( +__process_node_info( IN spl_qp_svc_t* p_spl_qp_svc, IN al_mad_wr_t* const p_mad_wr ) { @@ -1596,8 +1718,7 @@ process_node_info( p_node_info->class_version = 1; p_node_info->node_type = IB_NODE_TYPE_CA; p_node_info->num_ports = p_ca_attr->num_ports; - /* TODO: Get some unique identifier for the system */ - p_node_info->sys_guid = p_ca_attr->ca_guid; + p_node_info->sys_guid = p_ca_attr->system_image_guid; p_node_info->node_guid = p_ca_attr->ca_guid; p_node_info->port_guid = p_port_attr->port_guid; p_node_info->partition_cap = cl_hton16( p_port_attr->num_pkeys ); @@ -1616,7 +1737,7 @@ process_node_info( static ib_api_status_t -process_node_desc( +__process_node_desc( IN spl_qp_svc_t* p_spl_qp_svc, IN al_mad_wr_t* const p_mad_wr ) { @@ -1662,12 +1783,341 @@ process_node_desc( return status; } +static ib_api_status_t +__process_guid_info( + IN spl_qp_svc_t* p_spl_qp_svc, + IN al_mad_wr_t* const p_mad_wr ) +{ + + ib_mad_t *p_mad; + ib_mad_element_t *p_mad_resp; + ib_smp_t *p_smp; + ib_guid_info_t *p_guid_info; + uint16_t idx; + ib_api_status_t status; + + + /* Initialize a pointers to the MAD work request and outbound MAD. */ + p_mad = get_mad_hdr_from_wr( p_mad_wr ); + + /* Get the table selector from the attribute */ + idx = ((uint16_t)cl_ntoh32( p_mad->attr_mod )); + + /* + * TODO : Setup the response to fail the MAD instead of sending + * it down to the HCA. + */ + if( idx > 31 ) + { + AL_EXIT( AL_DBG_SMI ); + return IB_NOT_DONE; + } + if( !p_spl_qp_svc->cache.guid_block[idx].valid ) + { + AL_EXIT( AL_DBG_SMI ); + return IB_NOT_DONE; + } + + /* + * If a SET, see if the set is identical to the cache, + * in which case it's a no-op. + */ + if( p_mad->method == IB_MAD_METHOD_SET ) + { + if( cl_memcmp( ib_smp_get_payload_ptr( (ib_smp_t*)p_mad ), + &p_spl_qp_svc->cache.guid_block[idx].tbl, sizeof(ib_pkey_table_info_t) ) ) + { + /* The set is requesting a change. */ + return IB_NOT_DONE; + } + } + + /* Get a MAD element from the pool for the response. */ + status = get_resp_mad( p_spl_qp_svc, p_mad_wr, &p_mad_resp ); + if( status == IB_SUCCESS ) + { + p_smp = (ib_smp_t*)p_mad_resp->p_mad_buf; + + /* Setup the response mad. */ + cl_memcpy( p_smp, p_mad, MAD_BLOCK_SIZE ); + p_smp->method = (IB_MAD_METHOD_RESP_MASK | IB_MAD_METHOD_GET); + if( p_smp->mgmt_class == IB_MCLASS_SUBN_DIR ) + p_smp->status = IB_SMP_DIRECTION; + else + p_smp->status = 0; + + p_guid_info = (ib_guid_info_t*)ib_smp_get_payload_ptr( p_smp ); + + // TODO: do we need lock on the cache ????? + + + /* Copy the cached data. */ + cl_memcpy( p_guid_info, + &p_spl_qp_svc->cache.guid_block[idx].tbl, sizeof(ib_guid_info_t) ); + + status = complete_local_mad( p_spl_qp_svc, p_mad_wr, p_mad_resp ); + } + + AL_EXIT( AL_DBG_SMI ); + return status; +} + + +static ib_api_status_t +__process_pkey_table( + IN spl_qp_svc_t* p_spl_qp_svc, + IN al_mad_wr_t* const p_mad_wr ) +{ + + ib_mad_t *p_mad; + ib_mad_element_t *p_mad_resp; + ib_smp_t *p_smp; + ib_pkey_table_info_t *p_pkey_table_info; + uint16_t idx; + ib_api_status_t status; + + AL_ENTER( AL_DBG_SMI ); + + CL_ASSERT( p_spl_qp_svc ); + CL_ASSERT( p_mad_wr ); + + /* Initialize a pointers to the MAD work request and outbound MAD. */ + p_mad = get_mad_hdr_from_wr( p_mad_wr ); + + /* Get the table selector from the attribute */ + idx = ((uint16_t)cl_ntoh32( p_mad->attr_mod )); + + /* + * TODO : Setup the response to fail the MAD instead of sending + * it down to the HCA. + */ + if( idx > 2047 ) + { + AL_EXIT( AL_DBG_SMI ); + return IB_NOT_DONE; + } + + + if( !p_spl_qp_svc->cache.pkey_tbl[idx].valid ) + { + AL_EXIT( AL_DBG_SMI ); + return IB_NOT_DONE; + } + + /* + * If a SET, see if the set is identical to the cache, + * in which case it's a no-op. + */ + if( p_mad->method == IB_MAD_METHOD_SET ) + { + if( cl_memcmp( ib_smp_get_payload_ptr( (ib_smp_t*)p_mad ), + &p_spl_qp_svc->cache.pkey_tbl[idx].tbl, sizeof(ib_pkey_table_info_t) ) ) + { + /* The set is requesting a change. */ + AL_EXIT( AL_DBG_SMI ); + return IB_NOT_DONE; + } + } + + /* Get a MAD element from the pool for the response. */ + status = get_resp_mad( p_spl_qp_svc, p_mad_wr, &p_mad_resp ); + if( status == IB_SUCCESS ) + { + p_smp = (ib_smp_t*)p_mad_resp->p_mad_buf; + + /* Setup the response mad. */ + cl_memcpy( p_smp, p_mad, MAD_BLOCK_SIZE ); + p_smp->method = (IB_MAD_METHOD_RESP_MASK | IB_MAD_METHOD_GET); + if( p_smp->mgmt_class == IB_MCLASS_SUBN_DIR ) + p_smp->status = IB_SMP_DIRECTION; + else + p_smp->status = 0; + + p_pkey_table_info = (ib_pkey_table_info_t*)ib_smp_get_payload_ptr( p_smp ); + + // TODO: do we need lock on the cache ????? + + + /* Copy the cached data. */ + cl_memcpy( p_pkey_table_info, + &p_spl_qp_svc->cache.pkey_tbl[idx].tbl, sizeof(ib_pkey_table_info_t) ); + + status = complete_local_mad( p_spl_qp_svc, p_mad_wr, p_mad_resp ); + } + + AL_EXIT( AL_DBG_SMI ); + return status; +} + + +static ib_api_status_t +__process_slvl_table( + IN spl_qp_svc_t* p_spl_qp_svc, + IN al_mad_wr_t* const p_mad_wr ) +{ + + + ib_mad_t *p_mad; + ib_mad_element_t *p_mad_resp; + ib_smp_t *p_smp; + ib_slvl_table_t *p_slvl_table; + ib_api_status_t status; + + AL_ENTER( AL_DBG_SMI ); + + CL_ASSERT( p_spl_qp_svc ); + CL_ASSERT( p_mad_wr ); + + /* Initialize a pointers to the MAD work request and outbound MAD. */ + p_mad = get_mad_hdr_from_wr( p_mad_wr ); + + if( !p_spl_qp_svc->cache.sl_vl.valid ) + { + AL_EXIT( AL_DBG_SMI ); + return IB_NOT_DONE; + } + + /* + * If a SET, see if the set is identical to the cache, + * in which case it's a no-op. + */ + if( p_mad->method == IB_MAD_METHOD_SET ) + { + if( cl_memcmp( ib_smp_get_payload_ptr( (ib_smp_t*)p_mad ), + &p_spl_qp_svc->cache.sl_vl.tbl, sizeof(ib_slvl_table_t) ) ) + { + /* The set is requesting a change. */ + AL_EXIT( AL_DBG_SMI ); + return IB_NOT_DONE; + } + } + + /* Get a MAD element from the pool for the response. */ + status = get_resp_mad( p_spl_qp_svc, p_mad_wr, &p_mad_resp ); + if( status == IB_SUCCESS ) + { + p_smp = (ib_smp_t*)p_mad_resp->p_mad_buf; + + /* Setup the response mad. */ + cl_memcpy( p_smp, p_mad, MAD_BLOCK_SIZE ); + p_smp->method = (IB_MAD_METHOD_RESP_MASK | IB_MAD_METHOD_GET); + if( p_smp->mgmt_class == IB_MCLASS_SUBN_DIR ) + p_smp->status = IB_SMP_DIRECTION; + else + p_smp->status = 0; + + p_slvl_table = (ib_slvl_table_t*)ib_smp_get_payload_ptr( p_smp ); + + // TODO: do we need lock on the cache ????? + + + /* Copy the cached data. */ + cl_memcpy( p_slvl_table, + &p_spl_qp_svc->cache.sl_vl.tbl, sizeof(ib_slvl_table_t) ); + + status = complete_local_mad( p_spl_qp_svc, p_mad_wr, p_mad_resp ); + } + + AL_EXIT( AL_DBG_SMI ); + return status; +} + + + +static ib_api_status_t +__process_vl_arb_table( + IN spl_qp_svc_t* p_spl_qp_svc, + IN al_mad_wr_t* const p_mad_wr ) +{ + + ib_mad_t *p_mad; + ib_mad_element_t *p_mad_resp; + ib_smp_t *p_smp; + ib_vl_arb_table_t *p_vl_arb_table; + uint16_t idx; + ib_api_status_t status; + + AL_ENTER( AL_DBG_SMI ); + + CL_ASSERT( p_spl_qp_svc ); + CL_ASSERT( p_mad_wr ); + + /* Initialize a pointers to the MAD work request and outbound MAD. */ + p_mad = get_mad_hdr_from_wr( p_mad_wr ); + + /* Get the table selector from the attribute */ + idx = ((uint16_t)(cl_ntoh32( p_mad->attr_mod ) >> 16)) - 1; + + /* + * TODO : Setup the response to fail the MAD instead of sending + * it down to the HCA. + */ + if( idx > 3 ) + { + AL_EXIT( AL_DBG_SMI ); + return IB_NOT_DONE; + } + + + if( !p_spl_qp_svc->cache.vl_arb[idx].valid ) + { + AL_EXIT( AL_DBG_SMI ); + return IB_NOT_DONE; + } + + /* + * If a SET, see if the set is identical to the cache, + * in which case it's a no-op. + */ + if( p_mad->method == IB_MAD_METHOD_SET ) + { + if( cl_memcmp( ib_smp_get_payload_ptr( (ib_smp_t*)p_mad ), + &p_spl_qp_svc->cache.vl_arb[idx].tbl, sizeof(ib_vl_arb_table_t) ) ) + { + /* The set is requesting a change. */ + AL_EXIT( AL_DBG_SMI ); + return IB_NOT_DONE; + } + } + + /* Get a MAD element from the pool for the response. */ + status = get_resp_mad( p_spl_qp_svc, p_mad_wr, &p_mad_resp ); + if( status == IB_SUCCESS ) + { + p_smp = (ib_smp_t*)p_mad_resp->p_mad_buf; + + /* Setup the response mad. */ + cl_memcpy( p_smp, p_mad, MAD_BLOCK_SIZE ); + p_smp->method = (IB_MAD_METHOD_RESP_MASK | IB_MAD_METHOD_GET); + if( p_smp->mgmt_class == IB_MCLASS_SUBN_DIR ) + p_smp->status = IB_SMP_DIRECTION; + else + p_smp->status = 0; + + p_vl_arb_table = (ib_vl_arb_table_t*)ib_smp_get_payload_ptr( p_smp ); + + // TODO: do we need lock on the cache ????? + + + /* Copy the cached data. */ + cl_memcpy( p_vl_arb_table, + &p_spl_qp_svc->cache.pkey_tbl[idx].tbl, sizeof(ib_vl_arb_table_t) ); + + status = complete_local_mad( p_spl_qp_svc, p_mad_wr, p_mad_resp ); + } + + AL_EXIT( AL_DBG_SMI ); + return status; +} + + + /* * Process subnet administration MADs using cached data if possible. */ static ib_api_status_t -process_subn_mad( +__process_subn_mad( IN spl_qp_svc_t* p_spl_qp_svc, IN al_mad_wr_t* const p_mad_wr ) { @@ -1684,21 +2134,63 @@ process_subn_mad( CL_ASSERT( p_smp->mgmt_class == IB_MCLASS_SUBN_DIR || p_smp->mgmt_class == IB_MCLASS_SUBN_LID ); + /* simple m-key check */ + if( p_spl_qp_svc->m_key && p_smp->m_key == p_spl_qp_svc->m_key ) + { + if(!p_spl_qp_svc->cache_en ) + { + p_spl_qp_svc->cache_en = TRUE; + AL_EXIT( AL_DBG_SMI ); + return IB_NOT_DONE; + } + } + else + { + AL_PRINT(TRACE_LEVEL_WARNING, AL_DBG_SMI, ("Mkey check failed \n")); + AL_PRINT(TRACE_LEVEL_ERROR, AL_DBG_ERROR, ("Mkey check SMP= 0x%x:%x SVC = 0x%x:%x \n", + ((uint32_t*)&p_smp->m_key)[0],((uint32_t*)&p_smp->m_key)[1], + ((uint32_t*)&p_spl_qp_svc->m_key)[0],((uint32_t*)&p_spl_qp_svc->m_key)[1])); + + p_spl_qp_svc->cache_en = FALSE; + AL_EXIT( AL_DBG_SMI ); + return IB_NOT_DONE; + } + + cl_spinlock_acquire(&p_spl_qp_svc->cache_lock); + switch( p_smp->attr_id ) { case IB_MAD_ATTR_NODE_INFO: - status = process_node_info( p_spl_qp_svc, p_mad_wr ); + status = __process_node_info( p_spl_qp_svc, p_mad_wr ); break; case IB_MAD_ATTR_NODE_DESC: - status = process_node_desc( p_spl_qp_svc, p_mad_wr ); + status = __process_node_desc( p_spl_qp_svc, p_mad_wr ); + break; + + case IB_MAD_ATTR_GUID_INFO: + status = __process_guid_info( p_spl_qp_svc, p_mad_wr ); break; + case IB_MAD_ATTR_P_KEY_TABLE: + status = __process_pkey_table( p_spl_qp_svc, p_mad_wr ); + break; + + case IB_MAD_ATTR_SLVL_TABLE: + status = __process_slvl_table( p_spl_qp_svc, p_mad_wr ); + break; + + case IB_MAD_ATTR_VL_ARBITRATION: + status = __process_vl_arb_table( p_spl_qp_svc, p_mad_wr ); + break; + default: status = IB_NOT_DONE; break; } + cl_spinlock_release(&p_spl_qp_svc->cache_lock); + AL_EXIT( AL_DBG_SMI ); return status; } @@ -1707,7 +2199,7 @@ process_subn_mad( /* * Process a local MAD send work request. */ -ib_api_status_t +static ib_api_status_t fwd_local_mad( IN spl_qp_svc_t* p_spl_qp_svc, IN al_mad_wr_t* const p_mad_wr ) @@ -1814,25 +2306,25 @@ fwd_local_mad( */ if( smp_is_set ) { - ib_port_info_t* p_port_info = NULL; + ib_smp_t* p_smp_response = NULL; switch( p_mad_response_buf->mgmt_class ) { case IB_MCLASS_SUBN_DIR: - if( ( p_smp->attr_id == IB_MAD_ATTR_PORT_INFO ) && - ( ib_smp_get_status( p_smp ) == IB_SA_MAD_STATUS_SUCCESS ) ) + if( ib_smp_get_status( p_smp ) == IB_SA_MAD_STATUS_SUCCESS ) { - p_port_info = - (ib_port_info_t*)ib_smp_get_payload_ptr( p_smp ); + p_smp_response = p_smp; + //p_port_info = + // (ib_port_info_t*)ib_smp_get_payload_ptr( p_smp ); } break; case IB_MCLASS_SUBN_LID: - if( ( p_mad_response_buf->attr_id == IB_MAD_ATTR_PORT_INFO ) && - ( p_mad_response_buf->status == IB_SA_MAD_STATUS_SUCCESS ) ) + if( p_mad_response_buf->status == IB_SA_MAD_STATUS_SUCCESS ) { - p_port_info = - (ib_port_info_t*)ib_smp_get_payload_ptr((ib_smp_t*)p_mad_response_buf); + p_smp_response = (ib_smp_t*)p_mad_response_buf; + //p_port_info = + // (ib_port_info_t*)ib_smp_get_payload_ptr((ib_smp_t*)p_mad_response_buf); } break; @@ -1840,21 +2332,39 @@ fwd_local_mad( break; } - if( p_port_info ) - { - p_spl_qp_svc->base_lid = p_port_info->base_lid; - p_spl_qp_svc->lmc = ib_port_info_get_lmc( p_port_info ); - p_spl_qp_svc->sm_lid = p_port_info->master_sm_base_lid; - p_spl_qp_svc->sm_sl = ib_port_info_get_sm_sl( p_port_info ); - - if (p_port_info->subnet_timeout & 0x80) + if( p_smp_response ) + { + switch( p_smp_response->attr_id ) { - AL_PRINT( TRACE_LEVEL_INFORMATION, AL_DBG_PNP, - ("Client reregister event, setting sm_lid to 0.\n")); - ci_ca_lock_attr(p_spl_qp_svc->obj.p_ci_ca); - p_spl_qp_svc->obj.p_ci_ca->p_pnp_attr-> - p_port_attr->sm_lid= 0; - ci_ca_unlock_attr(p_spl_qp_svc->obj.p_ci_ca); + case IB_MAD_ATTR_PORT_INFO: + { + ib_port_info_t *p_port_info = + (ib_port_info_t*)ib_smp_get_payload_ptr(p_smp_response); + p_spl_qp_svc->base_lid = p_port_info->base_lid; + p_spl_qp_svc->lmc = ib_port_info_get_lmc( p_port_info ); + p_spl_qp_svc->sm_lid = p_port_info->master_sm_base_lid; + p_spl_qp_svc->sm_sl = ib_port_info_get_sm_sl( p_port_info ); + if(p_port_info->m_key) + p_spl_qp_svc->m_key = p_port_info->m_key; + if (p_port_info->subnet_timeout & 0x80) + { + AL_PRINT( TRACE_LEVEL_INFORMATION, AL_DBG_PNP, + ("Client reregister event, setting sm_lid to 0.\n")); + ci_ca_lock_attr(p_spl_qp_svc->obj.p_ci_ca); + p_spl_qp_svc->obj.p_ci_ca->p_pnp_attr-> + p_port_attr->sm_lid= 0; + ci_ca_unlock_attr(p_spl_qp_svc->obj.p_ci_ca); + } + } + break; + case IB_MAD_ATTR_P_KEY_TABLE: + case IB_MAD_ATTR_GUID_INFO: + case IB_MAD_ATTR_SLVL_TABLE: + case IB_MAD_ATTR_VL_ARBITRATION: + spl_qp_svc_update_cache( p_spl_qp_svc, p_smp_response); + break; + default : + break; } } } diff --git a/trunk/core/al/kernel/al_smi.h b/trunk/core/al/kernel/al_smi.h index e9f452d4..883d9708 100644 --- a/trunk/core/al/kernel/al_smi.h +++ b/trunk/core/al/kernel/al_smi.h @@ -66,23 +66,71 @@ typedef enum _spl_qp_svc_state } spl_qp_svc_state_t; +/* + * Attribute cache for port info saved to expedite local MAD processing. + * Note that the cache accounts for the worst case GID and PKEY table size + * but is allocated from paged pool, so it's nothing to worry about. + */ + +typedef struct _guid_block +{ + boolean_t valid; + ib_guid_info_t tbl; + +} guid_block_t; + + +typedef struct _pkey_block +{ + boolean_t valid; + ib_pkey_table_info_t tbl; + +} pkey_block_t; + +typedef struct _sl_vl_cache +{ + boolean_t valid; + ib_slvl_table_t tbl; + +} sl_vl_cache_t; + +typedef struct _vl_arb_block +{ + boolean_t valid; + ib_vl_arb_table_t tbl; + +} vl_arb_block_t; + +typedef struct _attr_cache +{ + guid_block_t guid_block[32]; + pkey_block_t pkey_tbl[2048]; + sl_vl_cache_t sl_vl; + vl_arb_block_t vl_arb[4]; + +} spl_qp_cache_t; /* Per port special QP service */ typedef struct _spl_qp_svc { - al_obj_t obj; /* Child of spl_qp_agent_t */ + al_obj_t obj; /* Child of spl_qp_agent_t */ cl_map_item_t map_item; /* Item on SMI/GSI list */ net64_t port_guid; uint8_t port_num; ib_net16_t base_lid; uint8_t lmc; - + ib_net16_t sm_lid; uint8_t sm_sl; + ib_net64_t m_key; - al_mad_disp_handle_t h_mad_disp; + spl_qp_cache_t cache; + cl_spinlock_t cache_lock; + boolean_t cache_en; + + al_mad_disp_handle_t h_mad_disp; ib_cq_handle_t h_send_cq; ib_cq_handle_t h_recv_cq; ib_qp_handle_t h_qp;