您的位置:首页 > 其它

模块API之module_put/__module_get

2017-11-01 14:55 369 查看
module_put和__module_get 是一对函数,用于减少或者增加模块的引用计数.
具体使用的例子如下:
void nfs4_schedule_state_manager(struct nfs_client *clp)
{
struct task_struct *task;
char buf[INET6_ADDRSTRLEN + sizeof("-manager") + 1];

if (test_and_set_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) != 0)
return;
__module_get(THIS_MODULE);
atomic_inc(&clp->cl_count);

task = kthread_run(nfs4_run_state_manager, clp, "%s", buf);
if (IS_ERR(task)) {
printk(KERN_ERR "%s: kthread_run: %ld\n",
__func__, PTR_ERR(task));
nfs4_clear_state_manager_bit(clp);
nfs_put_client(clp);
module_put(THIS_MODULE);
}
}
其源码如下:
void module_put(struct module *module)
{
int ret;

if (module) {
preempt_disable();
ret = atomic_dec_if_positive(&module->refcnt);
WARN_ON(ret < 0);	/* Failed to put refcount */
trace_module_put(module, _RET_IP_);
preempt_enable();
}
}
EXPORT_SYMBOL(module_put);
void __module_get(struct module *module)
{
if (module) {
preempt_disable();
atomic_inc(&module->refcnt);
trace_module_get(module, _RET_IP_);
preempt_enable();
}
}
EXPORT_SYMBOL(__module_get);
可见在使用module_put和__module_get的时候,要通过preempt_disable()/preempt_enable() 来禁止/使能内核的抢占
module->refcnt是以原子的方式增加或者减小的,因此不用加锁
在module_put 中通过atomic_dec_if_positive 来使module->refcnt 减一时,要先判断减一后是否小于零,也就是当前的module->refcnt == 0.这种情况下就
不能在减一了,从这里也可以知道module->refcnt的最小值是零.
static inline int atomic_dec_if_positive(atomic_t *v)
{
int c, old, dec;
c = atomic_read(v);
for (;;) {
dec = c - 1;
if (unlikely(dec < 0))
break;
old = atomic_cmpxchg((v), c, dec);
if (likely(old == c))
break;
c = old;
}
return dec;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: