5

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?

4
  • Call backs are called when an event occurs,. If another event happens before the callback ends, then it will get an overlapping call. Commented Sep 11, 2015 at 14:13
  • @stark I'm more specifically asking if I can get two events on the same netlink family registration which can make the callbacks overlap. There is only one registration with multiple callbacks. Netlink callbacks will be modifying the same structures and the structures will only be modified/accessed by netlink callbacks. Commented Sep 11, 2015 at 14:48
  • 1
    @Etherealone I suspect the answer is that this is configurable, but off by default. In my copy of kernel 3.11's sources, the struct genl_family contains a bool parallel_ops. In linux-3.11.10-21/net/netlink/genetlink.c:674 or nearabouts, in genl_rcv_msg(), if that flag is not set, then a global mutex is locked, the request is processed, and the global mutex unlocked. If it is set then this locking doesn't happen. Commented Sep 11, 2015 at 15:39
  • @IwillnotexistIdonotexist I think you are right. I missed it but it actually refers to synchronization on operation callbacks in 4.2 genetlink.h, too. That should cover both multiple callbacks and single callback concurrency. Implementation you are referring seems to be proving that. You should make that an answer. Commented Sep 11, 2015 at 16:10

1 Answer 1

2

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.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.