您的位置:首页 > 编程语言

内核IPSec代码中xfrm_input.c中关于kmem_cache_alloc的使用分析

2010-03-07 10:31 501 查看
基本知识:

在内核
编程中,可能经常会有一些数据结构需要反复使用和释放,按照通常的思路,可能是使用kmalloc和kfree来实现。

但是这种方式效率不高,Linux为我们提供了更加高效的方法——Slab高速缓存管理器。

动态创建固定大小的内存对象,虽然kmalloc的时间复杂度并不大,但是联系到空间复杂度,还是采用kmem_cache_alloc的好;而非固定大小的内存申请,只能经由kmalloc来解决。

xfrm_input.c中关于kmem_cache_alloc的代码:(按文件中代码的顺序)

先是声明了一个struct kmem_cache类型的结构体:

static struct kmem_cache *secpath_cachep __read_mostly;

接下来是释放操作函数:

void __secpath_destroy(struct sec_path *sp)

{

int i;

for (i = 0; i < sp->len; i++)

xfrm_state_put(sp->xvec[i]);

kmem_cache_free(secpath_cachep, sp);

}

EXPORT_SYMBOL(__secpath_destroy);

使用kmem_cache_alloc为一个struct sec_path结构体分配空间:

struct sec_path *secpath_dup(struct sec_path *src)

{

struct sec_path *sp;

sp = kmem_cache_alloc(secpath_cachep, GFP_ATOMIC);

if (!sp)

return NULL;

sp->len = 0;

if (src) {

int i;

memcpy(sp, src, sizeof(*sp));

for (i = 0; i < sp->len; i++)

xfrm_state_hold(sp->xvec[i]);

}

atomic_set(&sp->refcnt, 1);

return sp;

}

EXPORT_SYMBOL(secpath_dup);

调用secpath_dup()指针函数获得指向分配好的struct sec_path结构体指针:

int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)

{

。。。。。。

/* Allocate new secpath or COW existing one. */

if (!skb->sp || atomic_read(&skb->sp->refcnt) != 1) {

struct sec_path *sp;

sp = secpath_dup(skb->sp);

if (!sp) {

XFRM_INC_STATS(LINUX_MIB_XFRMINERROR);

goto drop;

}

if (skb->sp)

secpath_put(skb->sp);

skb->sp = sp;

}

。。。。。。

}

初始化函数,获得指向高速缓存struct kmem_cache结构体指针secpath_cachep,这个函数也在~/include/net/xfrm.h

中进行了声明,另外~/net/xfrm/xfrm_policy.c的初始化函数xfrm_init()在调用 xfrm_state_init();和 xfrm_policy_init();

函数时,也调用了xfrm_input_init()函数;

void __init xfrm_input_init(void)

{

secpath_cachep = kmem_cache_create("secpath_cache",

sizeof(struct sec_path),

0, SLAB_HWCACHE_ALIGN|SLAB_PANIC,

NULL);

}

实际代码执行顺序是这样的:

static struct kmem_cache *secpath_cachep __read_mostly;

xfrm_input_init()--> secpath_cachep = kmem_cache_create("secpath_cache",

sizeof(struct sec_path),

0, SLAB_HWCACHE_ALIGN|SLAB_PANIC,

NULL);

到这里我们获得了一个可用的secpath_cachep头指针

接下来

xfrm_input()-->secpath_dup()-->struct sec_path *sp; sp = kmem_cache_alloc(secpath_cachep, GFP_ATOMIC);

这样我们就可以使用sp指针来存储struct sec_path结构体的内容了。

顺便说一下struct sec_path

{

atomic_t refcnt;

int len;

struct xfrm_state *xvec[XFRM_MAX_DEPTH];

};

这个结构体也是struct sk_buff的成员之一,它包含了指向SA的指针数组struct xfrm_state *xvec[XFRM_MAX_DEPTH],

记录了在IPsec进入处理过程中,依次应用于信报处理的SA及其相关信息。

参考:
http://linux.chinaunix.net/bbs/viewthread.php?tid=913690 http://blog.chinaunix.net/u/5251/showart_402033.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: