Answer assumes Linux kernel version 3.11 or 4.2, probably valid for many others. Answer current as of September 2015.
Whether callbacks may be concurrent or not is a configurable property of the struct genl_family
at registration time, but if not explicitly specified, is probably defaulted to off. This is due to 1) The presence of a bool parallel_ops
member in struct genl_family
, and 2) Uninitialized members of a static-duration struct
being defaulted to 0
in C.
On reception of a Netlink message, eventually the function genl_rcv_msg()
is called, which determines the message's GeNetlink family and conditions on parallel_ops
to decide whether or not to lock down the global 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;
}
Once genl_family_rcv_msg()
is invoked (protected or unprotected by the mutex), the actual callback is invoked here.