Linux 内核通用 Netlink - 它是并发的吗?

Linux Kernel Generic Netlink - Is it concurrent?

说我已经使用 genl_register_family_with_ops 和多个回调注册了一个通用的 netlink 接口。

我没有看到任何关于它的警告,我假设回调是连续调用的,但没有关于回调如何调用的信息。

是否可以在我注册的同一个通用网络链接接口上同时调用多个回调?我需要在回调之间进行任何同步吗?

为了让问题更简单:

单个 netlink 回调是否可以在两个核心中抢占或并发 运行?

答案假定 Linux 内核版本 3.11 或 4.2,可能对许多其他版本有效。截至 2015 年 9 月的当前答案。

回调是否可以并发是注册时 struct genl_family 的可配置 属性,但如果未明确指定,则 可能 默认关闭。这是由于 1) struct genl_family 中存在 bool parallel_ops 成员,以及 2) C 中静态持续时间 struct 的未初始化成员默认为 0

接收到 Netlink 消息后,最终调用函数 genl_rcv_msg(),它确定消息的 GeNetlink 族和 parallel_ops 上的条件,以决定是否锁定全局 genl_mutex.

static int genl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
{
        struct genl_family *family;
        int err;

        family = genl_family_find_byid(nlh->nlmsg_type);
        if (family == NULL)
                return -ENOENT;

        if (!family->parallel_ops)
                genl_lock();

        err = genl_family_rcv_msg(family, skb, nlh);

        if (!family->parallel_ops)
                genl_unlock();

        return err;
}

一次genl_family_rcv_msg() is invoked (protected or unprotected by the mutex), the actual callback is invoked here.