一些内核模块函数(3)

//查看模块 mod 是否处于活跃状态
static inline int module_is_live(struct module *mod)
{
return mod->state != MODULE_STATE_GOING;
}


//模块引用计数减1,因为内核卸载某些模块时,要保证这个模块的引用计数为0,所以可以一次或反复
//调用这个函数,实现模块的引用计数清0,从而卸载
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();
}
}


//获得一个模块的引用计数,方便卸载时知道用多少次 module_put
/* MODULE_REF_BASE is the base reference count by kmodule loader. */
#define MODULE_REF_BASE 1
int module_refcount(struct module *mod)
{
return atomic_read(&mod->refcnt) - MODULE_REF_BASE;
}


//给一个内存地址addr,找到该地址所在的模块后,将模块的引用计数减1,内部调用了 module_put
void symbol_put_addr(void *addr)
{
struct module *modaddr;
unsigned long a = (unsigned long)dereference_function_descriptor(addr);


if (core_kernel_text(a))
return;


/* module_text_address is safe here: we're supposed to have reference
* to module from symbol_get, so it can't go away. */
modaddr = __module_text_address(a);
BUG_ON(!modaddr);
module_put(modaddr);
}


//给一个模块module,看是否处于活跃状态,然后将该模块module的引用计数加1
bool try_module_get(struct module *module)
{
bool ret = true;


if (module) {
preempt_disable();
/* Note: here, we can fail to get a reference */
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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值