Say that i have registered a generic netlink interface using genl_register_family_with_ops
with multiple callbacks.
I don't see any warnings about it and I assume the callbacks are serially called but there is no information about how the callbacks are called neither.
Is it possible that multiple callbacks are called concurrently on the same generic netlink interface I have registered? Do I need any synchronization between the callbacks?
To make the question simpler:
Can a single netlink callback be preempted or concurrently run in two cores?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With