销毁SLAB高速缓存kmem_cache_destroy()
作者:李万鹏 于北京 borqs
调用kmem_cache_destroy()释放cache。这个函数一般是在模块卸载的时候调用,在调用这个函数之前,cache应该是empty的。调用者必须保证在执行kmem_cache_destroy()的时候,不会对这个cache有任何内存分配。这里将share local slab中的指针释放回slab,然后对slabs_free上所有的slab进行释放。
int kmem_cache_destroy (kmem_cache_t * cachep)
{
int i;
/*指针不能为空,也不能在中断上下文*/
if (!cachep || in_interrupt())
BUG();
/* Don't let CPUs to come and go */
lock_cpu_hotplug();
/* Find the cache in the chain of caches. */
down(&cache_chain_sem);
/*将cache从cache_chain链表上删掉*/
list_del(&cachep->next);
up(&cache_chain_sem);
/*将slab中的对象都释放掉,如果slabs_partial或slabs_full链表不为空,则无法释放左右对象,再把cache加回以cache_chain为链表头的链表*/
if (__cache_shrink(cachep)) {
slab_error(cachep, "Can't free all objects");
down(&cache_chain_sem);
list_add(&cachep->next,&cache_chain);
up(&cache_chain_sem);
unlock_cpu_hotplug();
return 1;
}
if (unlikely(cachep->flags & SLAB_DESTROY_BY_RCU))
synchronize_kernel();
/* no cpu_online check required here since we clear the percpu
* array on cpu offline and set this to NULL.
*/
/*释放cpu local slab 数组*/
for (i = 0; i < NR_CPUS; i++)
kfree(cachep->array[i]);
/* NUMA: free the list3 structures */
/*释放共享local cpu slab*/
kfree(cachep->lists.shared);
cachep->lists.shared = NULL;
/*释放cache的描述符*/
kmem_cache_free(&cache_cache, cachep);
unlock_cpu_hotplug();
return 0;
}
static int __cache_shrink(kmem_cache_t *cachep)
{
struct slab *slabp;
int ret;
/*将共享local slab上的对象全部释放回slab*/
drain_cpu_caches(cachep);
check_irq_on();
spin_lock_irq(&cachep->spinlock);
/*释放slabs_free上的所有对象,然后释放slab块*/
for(;;) {
struct list_head *p;
p = cachep->lists.slabs_free.prev;
if (p == &cachep->lists.slabs_free)
break;
slabp = list_entry(cachep->lists.slabs_free.prev, struct slab, list);
#if DEBUG
if (slabp->inuse)
BUG();
#endif
list_del(&slabp->list);
cachep->lists.free_objects -= cachep->num;
spin_unlock_irq(&cachep->spinlock);
slab_destroy(cachep, slabp);
spin_lock_irq(&cachep->spinlock);
}
ret = !list_empty(&cachep->lists.slabs_full) ||
!list_empty(&cachep->lists.slabs_partial);
spin_unlock_irq(&cachep->spinlock);
return ret;
}
static void drain_cpu_caches(kmem_cache_t *cachep)
{
smp_call_function_all_cpus(do_drain, cachep);
check_irq_on();
spin_lock_irq(&cachep->spinlock);
/*如果存在共享 local slab,将其释放回slab*/
if (cachep->lists.shared)
drain_array_locked(cachep, cachep->lists.shared, 1);
spin_unlock_irq(&cachep->spinlock);
}
static void drain_array_locked(kmem_cache_t *cachep,
struct array_cache *ac, int force)
{
int tofree;
check_spinlock_acquired(cachep);
if (ac->touched && !force) {
ac->touched = 0;
} else if (ac->avail) {
/*如果存在对象*/
tofree = force ? ac->avail : (ac->limit+4)/5;
if (tofree > ac->avail) {
tofree = (ac->avail+1)/2;
}
/*将对象归还给slab*/
free_block(cachep, ac_entry(ac), tofree);
ac->avail -= tofree;
memmove(&ac_entry(ac)[0], &ac_entry(ac)[tofree],
sizeof(void*)*ac->avail);
}
}
static void free_block(kmem_cache_t *cachep, void **objpp, int nr_objects)
{
int i;
check_spinlock_acquired(cachep);
/* NUMA: move add into loop */
/*要释放多少个对象,cache空闲对象的数目就增加多少*/
cachep->lists.free_objects += nr_objects;
for (i = 0; i < nr_objects; i++) {
void *objp = objpp[i];
struct slab *slabp;
unsigned int objnr;
/**获得对象坐在slab的地址/
slabp = GET_PAGE_SLAB(virt_to_page(objp));
/*把slab从它所在的链表上删除*/
list_del(&slabp->list);
/*计算对象的number*/
objnr = (objp - slabp->s_mem) / cachep->objsize;
check_slabp(cachep, slabp);
#if DEBUG
if (slab_bufctl(slabp)[objnr] != BUFCTL_FREE) {
printk(KERN_ERR "slab: double free detected in cache '%s', objp %p.\n",
cachep->name, objp);
BUG();
}
#endif
/*kmem_bufctl_t数组指向下一个空闲的对象*/
slab_bufctl(slabp)[objnr] = slabp->free;
slabp->free = objnr;
STATS_DEC_ACTIVE(cachep);
/*slab中对象的使用计数减一*/
slabp->inuse--;
check_slabp(cachep, slabp);
/*如果slab中没有正在使用的了*/
if (slabp->inuse == 0) {
/*如果cache的空闲对象大于cache空闲对象的上限*/
if (cachep->lists.free_objects > cachep->free_limit) {
/*从cache空闲对象的数目中减去这个slab中空闲对象的数目*/
cachep->lists.free_objects -= cachep->num;
/*撤销这个slab块*/
slab_destroy(cachep, slabp);
} else {
/*否则把这个slab添加到slabs_free链表上*/
list_add(&slabp->list,
&list3_data_ptr(cachep, objp)->slabs_free);
}
} else {
/* Unconditionally move a slab to the end of the
* partial list on free - maximum time for the
* other objects to be freed, too.
*/
/*如果还有正在使用的则把slab添加到slabs_partial链表上*/
list_add_tail(&slabp->list,
&list3_data_ptr(cachep, objp)->slabs_partial);
}
}
}
分享到:
相关推荐
Linux常见驱动源码分析(kernel hacker修炼之道)--李万鹏 李万鹏 IBM Linux Technology Center kernel team 驱动资料清单内容如下: Linux设备模型(中)之上层容器.pdf Linux设备模型(上)之底层模型.pdf Linux...
这本书是“Linux kernel hacker修炼之道”的一部分,通过深入剖析各种常见的驱动源码,帮助读者提升在Linux系统中的驱动开发能力。 在Linux操作系统中,驱动程序是连接硬件与内核的桥梁,它们负责管理和控制硬件...
《常见驱动源码分析(kernel hacker修炼之道)》这本书或课程很可能深入探讨了如何理解和编写这些驱动,旨在帮助开发者提升对Linux内核和驱动编程的理解。在这个过程中,我们将会涉及到几个关键的知识点: 1. **Linux...
如果刚刚对linux的kernel有兴趣,想了解点什么的话,请先看看此书吧,她风趣幽默的介绍了linux的发展趣事,让你开心快乐之余慢慢领会linux的魅力,让你了解学习掌握kernel的方法。其中的很多建议经过我的实践和摸索...
CMake是一款跨平台的构建工具,它用于管理软件构建过程,尤其适合大型项目或包含多个子项目的工程。CMake不依赖于任何特定的构建系统,而是生成本地构建文件(如Unix Makefiles、Visual Studio项目等),然后使用...
【网鼎杯-第三场-杂项-track_hacker】是一个典型的网络安全竞赛中的挑战,涉及到的是CTF(Capture The Flag)比赛中的杂项类别。在CTF比赛中,参赛者需要运用各种安全技能解决难题,获取“旗标”(代表分数或解题...
内存管理是Linux内核的重要组成部分,它包括了与体系结构无关的部分和依赖于特定体系结构的部分。内存管理负责分配、回收内存资源,管理虚拟内存和物理内存的映射关系,并实现内存保护机制。 Linux内核支持多种文件...
【标题解析】:“BotnetWebSocket-master_chancexvw_hacker_websocket_botnet_sangerp”这个标题中的关键词“BotnetWebSocket-master”暗示了一个与僵尸网络(Botnet)相关的项目,特别是利用WebSocket协议的。...
这份标题为"HackerRank_2019-2018_Developer-Skills-Report.pdf"的报告,即HackerRank发布的2019-2018开发者技能报告,详细地探讨了开发者社区中的技术趋势和技能发展情况。根据描述,报告提出了React、物联网(IOT)...
《HackerRank面试准备套装详解》 HackerRank是一家知名的技术人才招聘平台,它提供了丰富的编程挑战和面试准备资源,帮助求职者提升技术能力并熟悉面试流程。"HackerRank-Interview-Preparation-Kit-master"是这个...
资源 Hacker 是一款强大的Windows应用程序资源编辑工具,主要用于查看、修改、添加、删除以及替换应用程序中的资源,如图标、对话框、菜单、字符串表等。在本文中,我们将深入探讨Resource Hacker的功能、使用方法...
这需要深入理解JVM的工作原理和内存管理机制。同时,他还提到了`/proc/thread-self/`,这是一个学习线程信息的途径,对于理解系统级的调试和分析会有帮助。 4. **动手实践** 作者鼓励读者亲自尝试,通过动手实践来...
骇客V1.0 描述 一个令人兴奋的游戏,将您带到了热门的位置,试图使MI6总部免遭破坏。 使用您的技能来克服这种情况。 记得保持冷静。 请下载并对其评分,以免错过。 即将推出进一步的升级! 更多信息 ...
HackerRank平台上的"The Linux Shell"挑战旨在帮助开发者熟悉和精通Shell脚本编写,提高他们在终端环境中解决问题的能力。在这个项目中,我们将深入探讨Shell编程的各个方面,并提供一系列解决方案来解决这些问题。 ...
有关hacker 的文章和资料分享给大家
super hacker tools pour tester beta
ProcessHacker是一款强大的系统信息工具,它提供了进程管理、服务管理、硬件监控、内存查看等多种功能,深受系统管理员和高级用户的喜爱。这个"processhacker-2.39-bin"压缩包很可能包含了ProcessHacker的二进制版本...
Process Hacker是一款开源、免费且功能强大的系统信息工具,它允许用户查看并管理正在运行的进程、服务、线程以及内存等系统资源。 【描述】"Process Hacker 1.1 PH1" 提示我们这是Process Hacker的早期版本,版本...
processhacker-2.39 最新版高速下载