首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >互斥锁解锁和request_module()行为

问互斥锁解锁和request_module()行为
EN

Stack Overflow用户
提问于 2017-03-13 23:23:54
回答 1查看 116关注 0票数 2

我在Linux内核中观察到了以下代码模式,例如net/sched/act_api.c或许多其他地方:

代码语言:javascript
复制
rtnl_lock();
rtnetlink_rcv_msg(skb, ...);
  replay:
  ret = process_msg(skb);
    ...
    /* try to obtain symbol which is in module. */
    /* if fail, try to load the module, otherwise use the symbol */
    a = get_symbol();
    if (a == NULL) {
       rtnl_unlock();
       request_module();
       rtnl_lock();
       /* now verify that we can obtain symbols from requested module and return EAGAIN.*/
       a = get_symbol();
       module_put();
       return -EAGAIN;
    }
  ...
  if (ret == -EAGAIN)
     goto replay;
  ...
rtnl_unlock();

在request_module成功之后,我们感兴趣的符号在内核内存空间中变得可用,我们可以使用它。然而,我不明白为什么返回EAGAIN并重新读取符号,为什么不直接在request_module()之后继续

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-03-14 00:20:14

如果你看一下Linux内核中的current implementation,在第二次调用之后有一个注释,它相当于上面代码中的get_symbol() (它是tc_lookup_action_n()),它确切地解释了为什么:

代码语言:javascript
复制
rtnl_unlock();
request_module("act_%s", act_name);
rtnl_lock();

a_o = tc_lookup_action_n(act_name);

/* We dropped the RTNL semaphore in order to
 * perform the module load.  So, even if we
 * succeeded in loading the module we have to
 * tell the caller to replay the request.  We
 * indicate this using -EAGAIN.
 */
if (a_o != NULL) {
    err = -EAGAIN;
    goto err_mod;
}

即使可以请求和加载模块,因为为了加载模块而丢弃了信号量,这是一个可以休眠的操作(并且不是执行该函数的“标准方式”,该函数返回EAGAIN来通知它。

编辑以澄清:

如果我们查看添加新操作时的调用序列(这可能导致加载所需的模块),我们会得到这样的序列:tc_ctl_action() -> tcf_action_add() -> tcf_action_init() -> tcf_action_init_1()。现在,如果将EAGAIN错误“移回”到case RTM_NEWACTION:中的tc_ctl_action(),我们可以看到,使用EAGAIN ret值,会重复调用tcf_action_add。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42767329

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档