基本知識:
在核心
編程中,可能經常會有一些資料結構需要反覆使用和釋放,按照通常的思路,可能是使用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