2007-05-26

Linux TCP/IP协议栈的通用编码模式解析

来源: 本站收集整理 作者:佚名 评论 0 条
 

和其他内核功能一样,每个网络功能都是内核成员中的一个。因此,它必须合理且公平的使用内存, CPU和其他共享资源。绝大多数功能并非内核中一段独立的程序,而是根据该功能而或多或少的与内核中其他部分相互影响。因此它们总是试图,尽可能的,使用类似的体系结构来实现类似的功能。

对许多内核组件来说有些需求是通用的,比如为同一数据结构分配好几个实例,或者跟踪一个数据结构的参考以避免不安全的内存重分配,等等。下面我们来看linux解决这些需求的一些通用的方法。我们也会谈到在查看内核编码时可能碰到的通用的编码技巧。

1.缓存

内核使用kmalloc和kfree来分配和释放内存。这两个函数的使用方法和用户空间的函数 malloc 和free的使用方法类似.

一个内核组件通常需要分配一个数据结构的多个实例。假如分配和释放频繁发生,相关内核组件的初始化函数(比如路由子系统中的fib_hash_init函数)通常会分配一个非凡的内存缓存以加速内存分配。当一个内存块释放时,它会被返回给与分配时相同的内存缓存。

以下是一些需要内核来维护内存缓存的网络数据结构:

Socket buffer descriptors

这个缓存,由net/core/sk_buff.c中的skb_init分配,它用于分配sk_buff结构。sk_buff结构可能是网络子系统中分配和释放频率最高的数据结构。

Neighboring protocol mappings

邻居协议使用内存缓存来分配neighbour结构,这个结构保存L3到L2的地址映射关系。

Routing tables

路由代码使用两个内存缓存来分配两种数据结构,这两种数据结构定义了路由表。

以下是使用内存缓存时会用到的一些函数:

kmem_cache_create

kmem_cache_destroy

建立或销毁缓存 .

kmem_cache_alloc

kmem_cache_free

从内存缓存中分配或释放一个对象。它们通常会在一个包装函数中被调用,这个包装函数在更高的层次上处理分配和释放的请求。比如:kfree_skb函数处理释放sk_buff的请求,但是只有在所有对此结构的引用释放之后并且相关的子系统(比如,防火墙)已执行了清除操作之后,才调用kmem_cache_free释放这个sk_buff。

从一个给定的内存缓存中能够分配多少个实例的数量限制通常在kmem_cache_alloc的包装函数中指定,但是有时也可以通过/proc文件系统中的参数来调整。

2. 缓存和哈希表

使用缓存来提升性能的技巧很常见。在网络代码中,有L3到L2映射的缓存(比如IPV4中的ARP缓存),路由表缓存,等等。

缓存的查找函数通常都有一个输入值来说明在缓存查找没有命中的情况下,是否需要分配一个新的元素并把它加入到缓存中。而其他类型的查找函数都只会把没有命中的元素添加进去。
共2页: 上一页 1 [2] 下一页

(本文仅表明作者个人观点,不代表本站及其管理员立场.) 推荐 收藏 投稿 打印 返回 关闭
上一篇:Linux 下采用软件实现RAID  
下一篇:Proxy源代码分析 谈Linux网络编程技术
    评论加载中…
 推荐文章
     

网站首页  -  网站地图 -   站长论坛  -  网站投稿  -    -  网站管理
Copyright © 2008 芜湖站长站 All Rights Reserved 皖ICP备07500611号