模块API之try_module_get
2017-11-03 09:23
387 查看
try_module_get的作用是如果一个模块处于活动状态,则对其引用计数加1. 在kernel中使用的例程如下: struct file *anon_inode_getfile(const char *name, const struct file_operations *fops, void *priv, int flags) { struct qstr this; struct path path; struct file *file; if (IS_ERR(anon_inode_inode)) return ERR_PTR(-ENODEV); if (fops->owner && !try_module_get(fops->owner)) return ERR_PTR(-ENOENT); } 其源码如下: bool try_module_get(struct module *module) { bool ret = true; //首先这个模块不能为null if (module) { // 由于要增加模块的引用计数,因此需要通过preempt_disable()/preempt_enable()来禁止内核抢占 preempt_disable(); /* Note: here, we can fail to get a reference */ // 首先通过module_is_live 判读模块处于活动状态,这个函数其实就是判断模块的flag是否是MODULE_STATE_GOING。然后通过atomic_inc_not_zero来增加模块的引用计数 if (likely(module_is_live(module) && atomic_inc_not_zero(&module->refcnt) != 0)) trace_module_get(module, _RET_IP_); else ret = false; preempt_enable(); } return ret; } 我们来看看atomic_inc_not_zero的实现 #ifndef atomic_inc_not_zero #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) #endif 继续看atomic_add_unless static inline int atomic_add_unless(atomic_t *v, int a, int u) { return __atomic_add_unless(v, a, u) != u; } 替换一下等于调用 __atomic_add_unless(v, 1, 0) != 0; 其源码如下: #ifndef __atomic_add_unless static inline int __atomic_add_unless(atomic_t *v, int a, int u) { int c, old; //首先读取v这个地址里面的值,首先v这个地址里面的值不能是u,这里u等于0,因为前面已经判断过模块是活动的,因此这c肯定不等于0 // 然后调用atomic_cmpxchg c = atomic_read(v); while (c != u && (old = atomic_cmpxchg(v, c, c + a)) != c) c = old; return c; } #endif #define atomic_cmpxchg(v, old, new) (cmpxchg(&((v)->counter), (old), (new))) #ifndef cmpxchg64_local #define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n)) #endif #define cmpxchg(ptr, o, n) cmpxchg_local((ptr), (o), (n)) static inline u64 __cmpxchg64_local_generic(volatile void *ptr, u64 old, u64 new) { u64 prev; unsigned long flags; raw_local_irq_save(flags); prev = *(u64 *)ptr; if (prev == old) *(u64 *)ptr = new; raw_local_irq_restore(flags); return prev; } 原来__cmpxchg64_local_generic的作用首先读取ptr这个地址里面的值,如果这个值等于old,就给ptr 赋值为new,但是返回ptr之前的旧值old 回到__atomic_add_unless 中的atomic_cmpxchg,就是先读取v里面的值,如果值等于1的话,这时c就等于1,然后给v加1,这个时候v里面的值是2,返回c的值,也就是1 最后总结一下: static inline int atomic_add_unless(atomic_t *v, int a, int u) { return __atomic_add_unless(v, a, u) != u; } 可以简单的认为: @a to @v, so long as @v was not already @u.Returns non-zero if @v was not @u, and zero otherwise.也就是返回非零表示v已经加上a了.
相关文章推荐
- 模块API之module_get_kallsym
- linux-2.6内核模块引用计数的实现(try_module_get和module_put)
- linux-2.6内核模块引用计数的实现(try_module_get和module_put)
- linux-2.6内核模块引用计数的实现(try_module_get和module_put)
- 模块API之module_put/__module_get
- c#调用API(GetModuleFileName)获取程序路径返回乱码有关问题
- 2011-1-2----------mage:getModuleDir函数的分析!!--------得到模块的地址
- WinAPI: GetModuleHandle - 获取一个模块(exe 或 dll)的句柄
- 模块API之__module_text_address
- GetModuleHandle(NULL)获取当前DLL模块基址?
- try_module_get和module_put
- try_module_get和module_put
- 2014-04-30工作日志:提取文件的路径及使用createprocess时,要用getmodulename获取要执行的模块的路径及调用createprocess时要记得关闭新建的进程
- 模块API之__module_address
- 模块API之module_refcount
- try_module_get和module_put
- try_module_get和module_put
- 解决nginx上传模块nginx_upload_module传递GET参数
- MFC模块状态(二)AFX_MANAGE_STATE(AfxGetStaticModuleState())
- Springboot整合dubbo构建maven多模块项目(三) - 把server分为api(服务接口定义)和server(服务实现)两个子module