Linux中的内存分配和释放之slab分配器分析(完)

本文详细介绍了Linux内核中的slab分配器如何进行内存分配和释放,包括kmem_getpages()和kmem_freepages()函数的工作原理。slab分配器通过管理内存页和对象,实现高效的对象分配和回收,确保内存的有效利用。
摘要由CSDN通过智能技术生成

        我们在上篇文章分析cache_grow()函数的时候涉及两个函数,我们没有细说。一个就是kmem_getpages()和kmem_freepages()函数,这两个函数有3个参数。kmem_cahce_t:主要是把申请到的对象加到这个高速缓存内

  flags:表示你申请时候的一些控制标志。nodeid:主要是要求在那个内存节点号申请内存。我们先来说下kmem_getpages()函数吧。

static void *kmem_getpages(kmem_cache_t *cachep, int flags, int nodeid)
{
       struct page *page;
       void *addr;
       int i;

       flags |= cachep->gfpflags;//设置flags,如果此高速缓存内存位于dma时,gfpflags就不为0.反而是在标志的某一位设置为1.
       if (likely(nodeid == -1)) {//如果nodeid为-1,说明没有指定在哪个节点号申请内存。
                 addr = (void*)__get_free_pages(flags, cachep->gfporder);//申请2的gfporder页的内存空间,函数返回是内存空间起始的线性地址。
                 if (!addr)
                    return NULL;
                page = virt_to_page(addr);//由线性地址找到对应的struct page结构体。
      } else {//如果指定了内存节点号。
        page = alloc_pages_node(nodeid, flags, cachep->gfporder);//在指定的内存节点号申请内存空间。
        if (!page)
           return NULL;
       addr = page_address(page);//把返回的struct page结构体转换为对应的线性地址。
     }

     i = (1 << cachep->gfporder);//这里是统计申请到的页数。
     if (cachep->flags & SLAB_RECLAIM_ACCOUNT)
        atomic_add(i, &slab_reclaim_pages);//如果设置了可跟踪slab回收标志,我们将slab_reclaim_pages加上i。这里主要表示我们有多少页可以被回收的。
     add_page_state(nr_slab, i);//将当前处理器的页状态的slab计数器加i。这里主要是统计内存页的状态,主要是为了表明我们的系统内有多少内存页已经交给了slab管理了。
     while (i--) {
               SetPageSlab(page);//将每页对应的struct page结构体的flags成员设置属于slab管理的标志位置1.
               page++;
     }
     return addr;
}
下面我们来说说它的相对函数kmem_freepages()函数。

static void kmem_freepages(kmem_cache_t *cachep, void *addr)
{
   unsigned long i = (1<<cachep->gfporder);
   struct page *page = virt_to_page(addr);
   const unsigned long nr_freed = i;

   while (i--) {
      if (!TestClearPageSlab(page))
         BUG();//由于这里是要释放申请用做slab管理的页,所以他们对应的struct page结构体的flags标志的PG_slab标志位必须被置1了,发现不为1时则系统就崩溃了。如果为1时,我们还要把这位清0.
     page++;
  }
  sub_page_state(nr_slab, nr_freed);//这里和上面相反,把当前处理器内存页状态的slab计数器减去nr_freed,表明系统现有的由slab管理的内存页数量。
  if (current->recl

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值