模块API之module_put/__module_get

本文介绍了Linux内核中模块管理函数module_put和__module_get的使用方法及其源码实现。这些函数通过原子操作来调整模块的引用计数,并在特定条件下禁用内核抢占以确保操作的一致性和安全性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值