bangh
驱动牛犊
驱动牛犊
  • 注册日期2003-03-26
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分57分
  • 威望75点
  • 贡献值0点
  • 好评度5点
  • 原创分0分
  • 专家分0分
阅读:1848回复:11

pcausa 例子的问题

楼主#
更多 发布于:2003-11-04 09:32
那位朋友看过 pcausa 的 passthru 呀.
在分配 packet的 pool 时候.

NDIS_STATUS
UTILAllocatePacketPool(
   PADAPTER Adapter                  
   )
{
   NDIS_STATUS Status;
   PNDIS_PACKET Packet;
   ULONG i;
   ULONG ProtoReservedSize;

   //
   // Determine Size Of Protocol Reserved Area
   //
   ProtoReservedSize = sizeof( IM_PACKET_CONTEXT );

   //
   // Call NDIS To Allocate The Packet Pool
   //
   NdisAllocatePacketPool(
      &Status,
      &Adapter->PacketPoolHandle,
      g_ConfigData.PacketPoolSize,
      ProtoReservedSize + 8   // For compatibility with Win95
      );

   //
   // Move Allocated Packets To Our Packet List
   // -----------------------------------------
   // The rationale for doing this is that the DDK documentation suggests
   // that re-using NDIS_PACKET structures is significantly faster and
   // more efficient then calling NdisAllocatePacket each time one is needed.
   //
   if( NT_SUCCESS( Status ) )
   {
      Adapter->ShutdownMask |= SHUTDOWN_DEALLOC_PACKET_POOL;

      for ( i = 0; i < g_ConfigData.PacketPoolSize; ++i )
      {
         //
         // Fetch The Packet From The NDIS Packet Pool
         //
         NdisAllocatePacket( &Status, &Packet, Adapter->PacketPoolHandle );

         if ( !NT_SUCCESS( Status ))
         {
            //
            // Log The Error
            //
            UTILWriteToAdapterErrorLog(
               Adapter,                            // Which Adapter
               IM_ERROR_PACKET,                    // Where ID
               NDIS_ERROR_CODE_OUT_OF_RESOURCES,   // Error Code
               0                                   // Extra ULONG
               );

            return Status;
         }

         IMSetTag( IM_PACKET_CONTEXT_FROM_PACKET( Packet ), PacketContext );

         //
         // Stash The Packet In Our Own SList
         //
         NdisInterlockedPushEntrySList(
            &Adapter->PacketSList,
            (PSINGLE_LIST_ENTRY)Packet->ProtocolReserved,
            &Adapter->PacketSListLock
            );
      }
   }
   else
   {
      //
      // Log The Error
      //
      UTILWriteToAdapterErrorLog(
         Adapter,                            // Which Adapter
         IM_ERROR_PACKET_POOL,               // Where ID
         NDIS_ERROR_CODE_OUT_OF_RESOURCES,   // Error Code
         0                                   // Extra ULONG
         );
   }
   return Status;
}  // UTILAllocatePacketPool


在 NdisInterlockedPushEntrySList 的时候, 为什么用的是
(PSINGLE_LIST_ENTRY)Packet->ProtocolReserved, 而不是
(PSINGLE_LIST_ENTRY)Packet, 那位大侠能够 说明一下吗 . ???
谢谢. 当然也给分拉.

bangh
驱动牛犊
驱动牛犊
  • 注册日期2003-03-26
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分57分
  • 威望75点
  • 贡献值0点
  • 好评度5点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2003-11-04 09:38
我觉得, pcausa 的例子中 , 对包的预分配, 可以提高了好多效率

如果结合 你本身的项目.真的挺有好处的.
SharpShooter
驱动小牛
驱动小牛
  • 注册日期2002-04-07
  • 最后登录2013-07-05
  • 粉丝0
  • 关注0
  • 积分5分
  • 威望40点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2003-11-04 10:03
 
在 NdisInterlockedPushEntrySList 的时候, 为什么用的是
(PSINGLE_LIST_ENTRY)Packet->ProtocolReserved, 而不是
(PSINGLE_LIST_ENTRY)Packet,  


在Push的时候,它把ProtocolReserved当作了List_Entry来使用,Pop出来后,再给ProtocolReserved域赋其它值.对于接收过程,它还要把这个Packet挂在一个双链表中,这时又把ProtocolReserved域作为了一个双链表的LIST_ENTRY使用:
NdisInterlockedInsertTailList(
         &Adapter->PendingReceiveList,        
        (PLIST_ENTRY)Packet->ProtocolReserved ,
         &Adapter->PendingReceiveListLock
         );

这时候使用(PSINGLE_LIST_ENTRY)Packet显然是不可以的,PacketReserved域是我们自己管理的,Pop/Push前后我们可以任意处理这个域,而Packet不是,如果改动了Packet中的其它域,Pop出来后则必须对其进行恢复,这样做也不是不行,不过麻烦也没有必要.

类似的情况在Pcause的这个例子里还有,好比对于接收处理,直接在预分配的内存中记录了相关的信息:
BufContext = (PIM_BUFFER_CONTEXT)SysBuffer;
        BufContext->NdisBuffer = NdisBuffer;
        ExInterlockedPushEntrySList(&Adapter->LookaheadSList,
                                      &BufContext->SListEntry,
                                      (ULONG*) &Adapter->LookaheadSListLock);

Pop出来之后,SysBuffer又填充了数据包内容,用完之后再当作PIM_BUFFER_CONTEXT处理.


[编辑 -  11/4/03 by  SharpShooter]
写驱动不如买足彩!!
bangh
驱动牛犊
驱动牛犊
  • 注册日期2003-03-26
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分57分
  • 威望75点
  • 贡献值0点
  • 好评度5点
  • 原创分0分
  • 专家分0分
地板#
发布于:2003-11-04 10:29
那有个 疑问.
为什么  不在  IM_PACKET_CONTEXT 中 直接 分配一个 PLIST_ENTRY 或 PSLIST_ENTRY 的字段 给 每个 包用呢 ???

谢谢 楼上的朋友能够继续帮忙.
SharpShooter
驱动小牛
驱动小牛
  • 注册日期2002-04-07
  • 最后登录2013-07-05
  • 粉丝0
  • 关注0
  • 积分5分
  • 威望40点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2003-11-04 10:43
那有个 疑问.
为什么  不在  IM_PACKET_CONTEXT 中 直接 分配一个 PLIST_ENTRY 或 PSLIST_ENTRY 的字段 给 每个 包用呢 ???

谢谢 楼上的朋友能够继续帮忙.  


对于Packet链,Packet本身包含了一个Reserved域可以存放这些信息,当然,Packet只是个描述符,除了Reserved域它也没有别的空间可用.

而对于处理接收的NdisBuffer链,NdisBuffer中并没有类似Packet的Reserved域可以用来记录List_Entry等信息,所以使用分配的内存空间记录这些信息确实是个好主意.

另一个办法是:自己定义一个结构,里面除了记录IM_PACKET_CONTEXT中的内容外,再提供一个预分配的Ndis_Buffer的指针,然后做一个这个结构的链.我觉得这样也没有问题,像这种分配,对效率/内存使用也不会有什么明显的影响,但显然不及Pcause的做法巧妙.
写驱动不如买足彩!!
SharpShooter
驱动小牛
驱动小牛
  • 注册日期2002-04-07
  • 最后登录2013-07-05
  • 粉丝0
  • 关注0
  • 积分5分
  • 威望40点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2003-11-04 10:46
p.s.
其实这个例子不是pcause的了,这是ND4.0 DDK中原附的例子,不过我不知道pcause和microsoft是什么关系,也没准这个例子就是pcause的人写的.
写驱动不如买足彩!!
bangh
驱动牛犊
驱动牛犊
  • 注册日期2003-03-26
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分57分
  • 威望75点
  • 贡献值0点
  • 好评度5点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2003-11-04 10:48
呵呵.
谢谢SharpShooter

我大致了解了 .

我只给你放了 20 分. 够了吗 ? 不够. 我另开帖子, 加给你. 呵呵.
bangh
驱动牛犊
驱动牛犊
  • 注册日期2003-03-26
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分57分
  • 威望75点
  • 贡献值0点
  • 好评度5点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2003-11-04 10:53
啊.
SharpShooter

我的 给分 那一项, 怎么没有了呀.

这几个星期, 老是登陆以后, 说我还没登陆.
好奇怪.

bangh
驱动牛犊
驱动牛犊
  • 注册日期2003-03-26
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分57分
  • 威望75点
  • 贡献值0点
  • 好评度5点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2003-11-04 10:59
p.s.
其实这个例子不是pcause的了,这是ND4.0 DDK中原附的例子,不过我不知道pcause和microsoft是什么关系,也没准这个例子就是pcause的人写的.



那你觉得, 在 2K 中 和 XP 中 passthtru 为什么不采用 那种
预先 分包 的办法呢 ??

是说明 那种方法不好, 还是说明 2K 中采用了 更好的方法呢.

SharpShooter
驱动小牛
驱动小牛
  • 注册日期2002-04-07
  • 最后登录2013-07-05
  • 粉丝0
  • 关注0
  • 积分5分
  • 威望40点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2003-11-04 11:11
[quote]p.s.
其实这个例子不是pcause的了,这是ND4.0 DDK中原附的例子,不过我不知道pcause和microsoft是什么关系,也没准这个例子就是pcause的人写的.



那你觉得, 在 2K 中 和 XP 中 passthtru 为什么不采用 那种
预先 分包 的办法呢 ??

是说明 那种方法不好, 还是说明 2K 中采用了 更好的方法呢.

 [/quote]
据说是这个例子的注释什么的写的不够漂亮,呵呵,道听途说.
有一点是肯定的,2K/XP的Passthru功能很是简化,这里很多帖子都在讨论Passthru接收方面的一些问题,我想主要就是因为2K/XP的Passthru接收没有怎么处理,至少它没有在PtReceive中拼装整个包,而nt40这个是拼装了的.

我觉得这个例子确实是做的不错,干脆给贴出来了,省得大伙儿到处找.
 [url] http://www.driverdevelop.com/forum/html_54311.html?1067915464[/url]
写驱动不如买足彩!!
bangh
驱动牛犊
驱动牛犊
  • 注册日期2003-03-26
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分57分
  • 威望75点
  • 贡献值0点
  • 好评度5点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2003-11-04 11:19
呵呵.你说的这个没错.

但, 我想说的是, 对 预分配包链表 及 buffer 链表.
在 2K 及 XP中 根本 没有这样处理.

我的问题是, 是不是 ,原来这样处理有缺点.
所以 XP 及 2K 没采用了 .
SharpShooter
驱动小牛
驱动小牛
  • 注册日期2002-04-07
  • 最后登录2013-07-05
  • 粉丝0
  • 关注0
  • 积分5分
  • 威望40点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2003-11-04 13:01
呵呵.你说的这个没错.

但, 我想说的是, 对 预分配包链表 及 buffer 链表.
在 2K 及 XP中 根本 没有这样处理.

我的问题是, 是不是 ,原来这样处理有缺点.
所以 XP 及 2K 没采用了 .
 

缺点不知道有没有,问题是没有,如果你不改动的话,我想肯定是没有问题的.

至于XP/2K DDK中为什么不收入这个例子,真的是不知道了.
写驱动不如买足彩!!
游客

返回顶部