内存管理
内核分别使用kmalloc和kfree函数分配和释放一个内存块。这两个函数的用法,类似于另外两个来自于libc用户空间库的姊妹函数malloc和free的调用。
内核组建为同一种数据结构类型分配几个实例(instance)是很常见的事。当分配和回收经常发生时,相关联内核组件初始化函数(例如,路由表的fib_hash_init)通常会分配一块特殊的内存缓存,以作分配之用。当一个内存块被释放时,实际上是返回到当初被分配的同一个缓冲区中。
内核维护的其专属内存缓存的一些网络数据结构的例子包括:
套接字缓冲区描述符
这个缓存是由net/core/sk_buff.c的skb_init分配的,用于分配sk_buff缓冲区描述符。sk_buff结构可能是网络子系统中分配和回收注册次数最高的。
邻居协议映射
每个邻居协议都使用一个缓冲区,以分配存储L3层(网络层,例如:IP)到L2层(链路层,例如:Ethernet)地址映射的数据结构。
路由表
路由代码使用两块缓存,用于定义路径的两个数据结构。
以下是用于处理内存缓存的关键内核函数:
kmem_cache_create
kmem_cache_destroy
创建和销毁一个缓存
kmem_cache_alloc
kmem_cache_free
为缓存分配及回收一个缓冲。通常有调用包裹函数(wrapper)实现分配和回收一个缓存缓冲区,包裹函数在较高层中管理用于处理分配和回收的请求。例如,用kfree_skb要求释放一个sk_buff缓冲区的一个实例时,只有当所有对该缓冲区的引用都已释放,而且相关的子系统(例如防火墙)也把所有必要的清理工作都做完后,才会去调用kmem_cache_free.
给定缓冲区(存在时)所能分配的实例数目的限制,通常由内容kmem_cache_alloc的包裹函数决定,但是有些时候可以通过/proc里的参数进行配置.