[ofw][patch] mcast garbage collector

Fab Tillier ftillier at windows.microsoft.com
Mon Jun 30 09:42:19 PDT 2008


Hi Slava,

Any feedback on the comments I provided on the IGMPv2 patch?  I've heard nothing back.

I also heard nothing back on the comments I made to the first iteration of this patch (the one that was both the IGMPv2 changes and the garbage collector).

-Fab

> -----Original Message-----
> From: ofw-bounces at lists.openfabrics.org [mailto:ofw-
> bounces at lists.openfabrics.org] On Behalf Of Slava Strebkov
> Sent: Sunday, June 29, 2008 6:52 AM
> To: ofw at lists.openfabrics.org
> Subject: [ofw][patch] mcast garbage collector
>
> Hi,
> Please review mcast garbage collector, which removes old endpoints of
> ipoib port. Rescan time can be configured from device property page.
> Garbage collector may be disabled from the device property page, it's
> on
> by default. Garbage collector uses implementation of igmp v2 protocol.
>
>
>
> Index: ulp/ipoib/kernel/ipoib_adapter.h
> ===================================================================
> --- ulp/ipoib/kernel/ipoib_adapter.h    (revision 1302)
> +++ ulp/ipoib/kernel/ipoib_adapter.h    (working copy)
> @@ -74,7 +74,8 @@
>         uint32_t        payload_mtu;
>         uint32_t        xfer_block_size;
>         mac_addr_t      conf_mac;
> -
> +    boolean_t  mc_garbage_collector;
> +       uint32_t        mc_leave_rescan;
>  }      ipoib_params_t;
>  /*
>  * FIELDS
> Index: ulp/ipoib/kernel/ipoib_driver.c
> ===================================================================
> --- ulp/ipoib/kernel/ipoib_driver.c     (revision 1302)
> +++ ulp/ipoib/kernel/ipoib_driver.c     (working copy)
> @@ -526,6 +526,29 @@
>         }
>         p_adapter->params.recv_pool_ratio =
> p_param->ParameterData.IntegerData;
>
> +    /* Required: MC garbage collector. */
> +    RtlInitUnicodeString( &keyword, L"MCGarbageCollector" );
> +    NdisReadConfiguration(
> +        &status, &p_param, h_config, &keyword, NdisParameterInteger );
> +    if( status != NDIS_STATUS_SUCCESS )
> +    {
> +        IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,
> +            ("MC garbage collector parameter is missing.\n") );
> +        return status;
> +    }
> +    p_adapter->params.mc_garbage_collector =
> (p_param->ParameterData.IntegerData != 0);
> +       /* Optional: MC leave rescan (sec) for the MC garable collector
> thread. */
> +       RtlInitUnicodeString( &keyword, L"MCLeaveRescan" );
> +       NdisReadConfiguration(
> +               &status, &p_param, h_config, &keyword,
> NdisParameterInteger );
> +       if( status != NDIS_STATUS_SUCCESS )
> +       {
> +               p_adapter->params.mc_leave_rescan = 260;
> +       }
> +       else
> +       {
> +               p_adapter->params.mc_leave_rescan =
> p_param->ParameterData.IntegerData;
> +       }
>         /* required: MTU size. */
>         RtlInitUnicodeString( &keyword, L"PayloadMtu" );
>         NdisReadConfiguration(
> Index: ulp/ipoib/kernel/ipoib_endpoint.h
> ===================================================================
> --- ulp/ipoib/kernel/ipoib_endpoint.h   (revision 1302)
> +++ ulp/ipoib/kernel/ipoib_endpoint.h   (working copy)
> @@ -61,7 +61,9 @@
>  TO_LONG_PTR(   ib_av_handle_t ,                        h_av) ;
>         boolean_t                               expired;
>         ib_al_ifc_t                             *p_ifc;
> -
> +       boolean_t                       is_in_use;
> +    boolean_t                          is_gc_in_use;
> +       boolean_t                               is_mcast_listener;
>  }      ipoib_endpt_t;
>  /*
>  * FIELDS
> Index: ulp/ipoib/kernel/ipoib_port.c
> ===================================================================
> --- ulp/ipoib/kernel/ipoib_port.c       (revision 1302)
> +++ ulp/ipoib/kernel/ipoib_port.c       (working copy)
> @@ -66,7 +66,7 @@
>  ipoib_port_t   *gp_ipoib_port;
>  #endif
>
> -
> +static void __port_do_mcast_garbage(ipoib_port_t *p_port);
>
> /**********************************************************************
> *
> *******
>  *
>  * Declarations
> @@ -94,6 +94,8 @@
>  __port_free(
>         IN                              cl_obj_t* const
> p_obj );
>
> +static void CL_API __port_mcast_garbage_collector
> +       (IN                             void*
> context );
>
>
> /**********************************************************************
> *
> *******
>  *
> @@ -290,6 +292,14 @@
>         IN      OUT                     ipoib_send_desc_t* const
> p_desc );
>
>  static NDIS_STATUS
> +__send_mgr_filter_igmp_v2(
> +       IN                              ipoib_port_t* const
> p_port,
> +    IN         const   ip_hdr_t* const
> p_ip_hdr,
> +       IN                              size_t
> iph_options_size,
> +       IN                              NDIS_BUFFER*
> p_buf,
> +       IN                              size_t
> buf_len );
> +
> +static NDIS_STATUS
>  __send_mgr_filter_udp(
>         IN                              ipoib_port_t* const
> p_port,
>         IN              const   ip_hdr_t* const
> p_ip_hdr,
> @@ -489,6 +499,13 @@
>  #endif
>  }
>
> +/* function returns pointer to payload that is going after IP header.
> +*  asssuming that payload and IP header are in the same buffer
> +*/
> +static void* GetIpPayloadPtr(const     ip_hdr_t* const p_ip_hdr)
> +{
> +       return (void*)((uint8_t*)p_ip_hdr + 4*(p_ip_hdr->ver_hl &
> 0xf));
> +}
>
>
> /**********************************************************************
> *
> *******
>  *
> @@ -579,6 +596,11 @@
>         KeInitializeEvent( &p_port->sa_event, NotificationEvent, TRUE
> );
>         KeInitializeEvent( &p_port->leave_mcast_event,
> NotificationEvent, TRUE );
>
> +       p_port->mcast_event_init = FALSE;
> +       cl_event_construct(&p_port->mcast_event);
> +
> +       p_port->mcast_thread_init = FALSE;
> +       cl_thread_construct(&p_port->mcast_thread);
>         IPOIB_EXIT( IPOIB_DBG_INIT );
>  }
>
> @@ -653,6 +675,12 @@
>                 return status;
>         }
>
> +    if (p_port->p_adapter->params.mc_garbage_collector)
> +    {
> +        /* Initialize multicast garbage collector event */
> +               KeInitializeEvent( &p_port->mcast_event,
> NotificationEvent, FALSE );
> +        p_port->mcast_event_init = TRUE;
> +       }
>         /* We only ever destroy from the PnP callback thread. */
>         cl_status = cl_obj_init( &p_port->obj, CL_DESTROY_SYNC,
>                 __port_destroying, __port_cleanup, __port_free );
> @@ -746,7 +774,19 @@
>         CL_ASSERT( p_obj );
>
>         p_port = PARENT_STRUCT( p_obj, ipoib_port_t, obj );
> +    if (p_port->p_adapter->params.mc_garbage_collector)
> +    {
> +        /* Destroy multicast garbage collector thread */
>
> +        if(p_port->mcast_thread_init)
> +        {
> +            CL_ASSERT(p_port->mcast_event_init);
> +                       KeSetEvent( &p_port->mcast_event, 0, FALSE );
>
> +            cl_thread_destroy(&p_port->mcast_thread);
> +            p_port->mcast_thread_init = FALSE;
> +        }
> +    }
> +
>         __endpt_mgr_destroy( p_port );
>         __recv_mgr_destroy( p_port );
>         __send_mgr_destroy( p_port );
> @@ -2131,6 +2171,11 @@
>         p_eth->hdr.src = p_src->mac;
>         p_eth->hdr.dst = p_dst->mac;
>
> +    if ( p_dst->is_gc_in_use)
> +       {
> +               CL_ASSERT(p_dst->h_mcast != NULL);
> +        p_dst->is_in_use = TRUE;
> +       }
>         IPOIB_EXIT( IPOIB_DBG_RECV );
>         return IB_SUCCESS;
>  }
> @@ -3129,7 +3174,132 @@
>         return status;
>  }
>
> +static NDIS_STATUS
> +__send_mgr_filter_igmp_v2(
> +       IN                              ipoib_port_t* const
> p_port,
> +    IN         const   ip_hdr_t* const
> p_ip_hdr,
> +       IN                              size_t
> iph_options_size,
> +       IN                              NDIS_BUFFER*
> p_buf,
> +       IN                              size_t
> buf_len )
> +{
> +    igmp_v2_hdr_t              *p_igmp_v2_hdr = NULL;
> +       NDIS_STATUS                     endpt_status;
> +       ipoib_endpt_t*          p_endpt = NULL;
> +       mac_addr_t                      fake_mcast_mac;
>
> +       IPOIB_ENTER( IPOIB_DBG_SEND );
> +
> +    if( !buf_len )
> +       {
> +               // To get the IGMP packet we need to skip the ip
> options
> NDIS_BUFFER (if exists)
> +               while ( iph_options_size )
> +               {
> +                       NdisGetNextBuffer( p_buf, &p_buf );
> +                       if( !p_buf )
> +                       {
> +                               IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR,
> IPOIB_DBG_ERROR,
> +                                       ("Failed to get IGMPv2 header
> buffer.\n") );
> +                               return NDIS_STATUS_FAILURE;
> +                       }
> +                       NdisQueryBufferSafe( p_buf, &p_igmp_v2_hdr,
> &buf_len, NormalPagePriority );
> +                       if( !p_igmp_v2_hdr )
> +                       {
> +                               IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR,
> IPOIB_DBG_ERROR,
> +                                       ("Failed to query IGMPv2 header
> buffer.\n") );
> +                               return NDIS_STATUS_FAILURE;
> +                       }
> +
> +                       iph_options_size-=buf_len;
> +               }
> +
> +               NdisGetNextBuffer( p_buf, &p_buf );
> +               if( !p_buf )
> +               {
> +                       IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR,
> IPOIB_DBG_ERROR,
> +                               ("Failed to get IGMPv2 header
> buffer.\n") );
> +                       return NDIS_STATUS_FAILURE;
> +               }
> +               NdisQueryBufferSafe( p_buf, &p_igmp_v2_hdr, &buf_len,
> NormalPagePriority );
> +               if( !p_igmp_v2_hdr )
> +               {
> +                       IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR,
> IPOIB_DBG_ERROR,
> +                               ("Failed to query IGMPv2 header
> buffer.\n") );
> +                       return NDIS_STATUS_FAILURE;
> +               }
> +       }
> +       else
> +       {
> +               /* assuming ip header and options are in the same
> packet
> */
> +               p_igmp_v2_hdr = GetIpPayloadPtr(p_ip_hdr);
> +       }
> +       /* Get the IGMP header length. */
> +       if( buf_len < sizeof(igmp_v2_hdr_t) )
> +       {
> +               IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,
> +                       ("Buffer not large enough for IGMPv2
> packet.\n")
> );
> +               return NDIS_STATUS_BUFFER_TOO_SHORT;
> +       }
> +
> +       // build fake mac from igmp packet group address
> +       fake_mcast_mac.addr[0] = 1;
> +    fake_mcast_mac.addr[1] = ((unsigned
> char*)&p_igmp_v2_hdr->group_address)[0] & 0x0f;
> +    fake_mcast_mac.addr[2] = 0x5E;
> +       fake_mcast_mac.addr[3] = ((unsigned
> char*)&p_igmp_v2_hdr->group_address)[1];
> +       fake_mcast_mac.addr[4] = ((unsigned
> char*)&p_igmp_v2_hdr->group_address)[2];
> +       fake_mcast_mac.addr[5] = ((unsigned
> char*)&p_igmp_v2_hdr->group_address)[3];
> +
> +       switch ( p_igmp_v2_hdr->type )
> +       {
> +       case IGMP_V2_MEMBERSHIP_REPORT:
> +               /*
> +                       This mean that some body open listener on this
> group
> +                   Change type of mcast endpt to SEND_RECV endpt. So
> mcast garbage collector
> +                       will not delete this mcast endpt.
> +               */
> +        IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_MCAST,
> +                       ("Catched IGMP_V2_MEMBERSHIP_REPORT message\n")
> );
> +        endpt_status = __endpt_mgr_ref( p_port, fake_mcast_mac,
> &p_endpt );
> +               if ( p_endpt )
> +               {
> +                       cl_obj_lock( &p_port->obj );
> +                       p_endpt->is_mcast_listener = TRUE;
> +                       cl_obj_unlock( &p_port->obj );
> +            ipoib_endpt_deref( p_endpt );
> +               }
> +               break;
> +
> +       case IGMP_V2_LEAVE_GROUP:
> +        /*
> +                       This mean that somebody CLOSE listener on this
> group .
> +                   Change type of mcast endpt to SEND_ONLY endpt. So
> mcast
> +                       garbage collector will delete this mcast endpt
> next time.
> +               */
> +        IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_MCAST,
> +                            ("Catched IGMP_V2_LEAVE_GROUP message\n")
> );
> +        endpt_status = __endpt_mgr_ref( p_port, fake_mcast_mac,
> &p_endpt );
> +               if ( p_endpt )
> +               {
> +                       cl_obj_lock( &p_port->obj );
> +                       p_endpt->is_mcast_listener = FALSE;
> +                       p_endpt->is_in_use = FALSE;
> +                       cl_obj_unlock( &p_port->obj );
> +                       ipoib_endpt_deref( p_endpt );
> +               }
> +
> +               __port_do_mcast_garbage(p_port);
> +
> +               break;
> +
> +       default:
> +        IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_MCAST,
> +                            ("Send Unknown IGMP message: 0x%x \n",
> p_igmp_v2_hdr->type ) );
> +               break;
> +       }
> +
> +       IPOIB_EXIT( IPOIB_DBG_SEND );
> +       return NDIS_STATUS_SUCCESS;
> +}
> +
>  static NDIS_STATUS
>  __send_mgr_filter_udp(
>         IN                              ipoib_port_t* const
> p_port,
> @@ -3577,7 +3747,18 @@
>                         return NDIS_STATUS_PENDING;
>                 }
>         }
> +       else if ( p_port->p_adapter->params.mc_garbage_collector &&
> +                     status == NDIS_STATUS_SUCCESS &&
> +                         ETH_IS_MULTICAST( p_eth_hdr->dst.addr ) &&
> +                         !ETH_IS_BROADCAST( p_eth_hdr->dst.addr ) )
> +       {
> +               CL_ASSERT( (*pp_endpt) );
> +               CL_ASSERT((*pp_endpt)->h_mcast != NULL);
> +               CL_ASSERT((*pp_endpt)->is_gc_in_use);
>
> +               (*pp_endpt)->is_in_use = TRUE;
> +       }
> +
>         IPOIB_EXIT( IPOIB_DBG_SEND );
>         return status;
>  }
> @@ -4706,6 +4887,8 @@
>         ib_query_req_t                  query;
>         ib_user_query_t                 info;
>         ib_portinfo_record_t    port_rec;
> +    cl_status_t             cl_status;
> +    BOOLEAN                 success = TRUE;
>
>         IPOIB_ENTER( IPOIB_DBG_INIT );
>
> @@ -4744,15 +4927,41 @@
>                 p_port->p_adapter->h_al, &query, &p_port-
> >ib_mgr.h_query
> );
>         if( status != IB_SUCCESS )
>         {
> -               KeSetEvent( &p_port->sa_event, EVENT_INCREMENT, FALSE
> );
> -               ipoib_set_inactive( p_port->p_adapter );
> -               ipoib_port_deref( p_port, ref_port_up );
> +            success = FALSE;
>                 IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,
>                         ("ib_query returned %s\n",
>                         p_port->p_adapter->p_ifc->get_err_str( status
> ))
> );
> -               return;
> -       }
> +        goto port_up_end;
> +        }
>
> +       /* garbage collector is needed when link is active */
> +        if (p_port->p_adapter->params.mc_garbage_collector)
> +        {
> +            CL_ASSERT(p_port->mcast_event_init);
> +               KeClearEvent( &p_port->mcast_event );
> +
> +            cl_status = cl_thread_init(
> +                &p_port->mcast_thread,
> +                __port_mcast_garbage_collector,
> +                p_port,
> +                "mcast_garbage");
> +            if( cl_status != CL_SUCCESS )
> +            {
> +                success = FALSE;
> +                IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,
> +                    ("cl_thread_init returned %#x\n", cl_status) );
> +            goto port_up_end;
> +            }
> +            p_port->mcast_thread_init = TRUE;
> +    }
> +port_up_end:
> +        if (!success)
> +        {
> +            KeSetEvent( &p_port->sa_event, EVENT_INCREMENT, FALSE );
> +            ipoib_set_inactive( p_port->p_adapter );
> +            ipoib_port_deref( p_port, ref_port_up );
> +        }
> +
>         IPOIB_EXIT( IPOIB_DBG_INIT );
>  }
>
> @@ -5229,6 +5438,16 @@
>                 return;
>         }
>
> +    /* Destroy multicast garbage collector thread */
> +       /* garbage collector is not needed when link is down */
> +    if(p_port->p_adapter->params.mc_garbage_collector &&
> p_port->mcast_thread_init)
> +    {
> +        CL_ASSERT(p_port->mcast_event_init);
> +               KeSetEvent( &p_port->mcast_event, 0, FALSE );
> +
> +        cl_thread_destroy(&p_port->mcast_thread);
> +        p_port->mcast_thread_init = FALSE;
> +    }
>         KeResetEvent(&p_port->leave_mcast_event);
>
>         /* Reset all endpoints so we don't flush our ARP cache. */
> @@ -5656,6 +5875,17 @@
>                         &p_port->endpt_mgr.lid_endpts, p_endpt->dlid,
> &p_endpt->lid_item );
>                 CL_ASSERT( p_qitem == &p_endpt->lid_item );
>         }
> +    /* Add the endpoint to the multicast endpoints list */
> +       if ( p_port->p_adapter->params.mc_garbage_collector )
> +       {
> +               /* set flag that garbage collector is enabled */
> +               p_endpt->is_gc_in_use = TRUE;
> +               p_endpt->is_in_use = TRUE;
> +       }
> +       else
> +       {
> +               p_endpt->is_gc_in_use = FALSE;
> +       }
>         cl_obj_unlock( &p_port->obj );
>
>         /* Try to send all pending sends. */
> @@ -5712,6 +5942,93 @@
>         IPOIB_EXIT( IPOIB_DBG_MCAST );
>  }
>
> +static void __port_do_mcast_garbage(ipoib_port_t *p_port)
> +{
> +    const mac_addr_t DEFAULT_MCAST_GROUP = {0x01, 0x00, 0x5e, 0x00,
> 0x00, 0x01};
> +       /* Do garbage collecting... */
>
> +       cl_map_item_t   *p_item;
> +       ipoib_endpt_t   *p_endpt;
> +       cl_qlist_t              destroy_mc_list;
> +       uint8_t                 cnt;
> +       const static GC_MAX_LEAVE_NUM = 80;
>
> +       cl_qlist_init( &destroy_mc_list );
>
> +       cl_obj_lock( &p_port->obj );
> +       cnt = 0;
> +       p_item = cl_qmap_head( &p_port->endpt_mgr.mac_endpts );
> +       while( (p_item != cl_qmap_end( &p_port->endpt_mgr.mac_endpts ))
> && (cnt < GC_MAX_LEAVE_NUM))
> +       {
> +               p_endpt = PARENT_STRUCT( p_item, ipoib_endpt_t,
> mac_item
> );
> +               p_item = cl_qmap_next( p_item );
> +
> +               /* Check if the current endpoint is not a multicast
> listener */
> +
> +               if( p_endpt->h_mcast &&
> +                       p_endpt->is_gc_in_use &&
> +                       (!p_endpt->is_mcast_listener) &&
> +                       ( cl_memcmp( &p_endpt->mac,
> &DEFAULT_MCAST_GROUP, sizeof(mac_addr_t) ) &&
> +                        (!p_endpt->is_in_use) ))
> +               {
> +                       cl_qmap_remove_item(
> &p_port->endpt_mgr.mac_endpts,
> +                               &p_endpt->mac_item );
> +                       cl_fmap_remove_item(
> &p_port->endpt_mgr.gid_endpts,
> +                               &p_endpt->gid_item );
> +
> +                       if( p_endpt->dlid )
> +                       {
> +                               cl_qmap_remove_item(
> &p_port->endpt_mgr.lid_endpts,
> +                                       &p_endpt->lid_item );
> +                               p_endpt->dlid = 0;
> +                       }
> +
> +                       cl_qlist_insert_tail(
> +                               &destroy_mc_list,
> &p_endpt->mac_item.pool_item.list_item );
> +                       cnt++;
> +               }
> +               else
> +                       p_endpt->is_in_use = FALSE;
> +       }
> +       cl_obj_unlock( &p_port->obj );
> +
> +       /* Destroy all multicast endpoints now that we have released
> the
> lock. */
> +       while( cl_qlist_count( &destroy_mc_list ) )
> +       {
> +               p_endpt = PARENT_STRUCT( cl_qlist_head(
> &destroy_mc_list
> ),
> +
> ipoib_endpt_t, mac_item.pool_item.list_item );
> +               IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_ENDPT,
> +                       ("mcast garbage collector: destroying endpoint
> %02x:%02x:%02x:%02x:%02x:%02x \n",
> +                                p_endpt->mac.addr[0],
> +                                p_endpt->mac.addr[1],
> +                                p_endpt->mac.addr[2],
> +                                p_endpt->mac.addr[3],
> +                                p_endpt->mac.addr[4],
> +                                p_endpt->mac.addr[5]) );
> +
> +               cl_obj_destroy( &PARENT_STRUCT( cl_qlist_remove_head(
> &destroy_mc_list ),
> +                       ipoib_endpt_t, mac_item.pool_item.list_item
> )->obj );
> +       }
> +}
> +
> +static void CL_API __port_mcast_garbage_collector
> +       (IN                             void*
> context )
> +{
> +       cl_status_t status;
> +       LARGE_INTEGER   wait;
> +       ipoib_port_t *p_port = context;
> +    IPOIB_ENTER( IPOIB_DBG_ENDPT );
> +
> +    CL_ASSERT( p_port->p_adapter->params.mc_garbage_collector );
> +
> +       wait.QuadPart =
> -(int64_t)(((uint64_t)p_port->p_adapter->params.mc_leave_rescan *
> 1000000) * 10);
> +       status = KeWaitForSingleObject( &p_port->mcast_event,
> Executive,
> KernelMode,
> +               FALSE, &wait );
> +
> +       while((status = KeWaitForSingleObject( &p_port->mcast_event,
> Executive, KernelMode,
> +
> FALSE, &wait )) != STATUS_SUCCESS)
> +       {
> +               __port_do_mcast_garbage(p_port);
> +       }
> +    IPOIB_EXIT( IPOIB_DBG_ENDPT );
> +}
> Index: ulp/ipoib/kernel/ipoib_port.h
> ===================================================================
> --- ulp/ipoib/kernel/ipoib_port.h       (revision 1302)
> +++ ulp/ipoib/kernel/ipoib_port.h       (working copy)
> @@ -506,6 +506,11 @@
>         atomic32_t                              endpt_rdr;
>
>         atomic32_t                              hdr_idx;
> +       boolean_t                               mcast_event_init;
> +       KEVENT                              mcast_event;
> /* Multicast garabage collector thread terminate event */
> +
> +       boolean_t                               mcast_thread_init;
> +       cl_thread_t                             mcast_thread;
> /* Multicast garbage collector thread */
>         uint16_t                                pkey_index;
>         ipoib_hdr_t                             hdr[1]; /* Must be
> last!
> */
>
> Index: ulp/ipoib/kernel/netipoib.inf
> ===================================================================
> --- ulp/ipoib/kernel/netipoib.inf       (revision 1302)
> +++ ulp/ipoib/kernel/netipoib.inf       (working copy)
> @@ -126,6 +126,19 @@
>  HKR, Ndi\Params\PayloadMtu,            Min,            0, "60"
>  HKR, Ndi\Params\PayloadMtu,            Max,            0, "2044"
>
> +HKR, Ndi\Params\MCGarbageCollector,    ParamDesc,      0, "MC garbage
> collector"
> +HKR, Ndi\Params\MCGarbageCollector,    Type,           0, "enum"
> +HKR, Ndi\Params\MCGarbageCollector,    Default,        0, "1"
> +HKR, Ndi\Params\MCGarbageCollector,    Optional,       0, "0"
> +HKR, Ndi\Params\MCGarbageCollector\enum,"0",           0, "Disabled"
> +HKR, Ndi\Params\MCGarbageCollector\enum,"1",           0, "Enabled"
> +
> +HKR, Ndi\Params\MCLeaveRescan,         ParamDesc,      0, "MC leave
> rescan (sec)"
> +HKR, Ndi\Params\MCLeaveRescan,         Type,           0, "dword"
> +HKR, Ndi\Params\MCLeaveRescan,         Default,        0, "260"
> +HKR, Ndi\Params\MCLeaveRescan,         Optional,       0, "0"
> +HKR, Ndi\Params\MCLeaveRescan,         Min,            0, "1"
> +HKR, Ndi\Params\MCLeaveRescan,         Max,            0, "3600"
>  [IpoibService]
>  DisplayName     = %IpoibServiceDispName%
>  ServiceType     = 1 ;%SERVICE_KERNEL_DRIVER%
>




More information about the ofw mailing list