On Wed, Dec 14, 2011 at 5:16 PM, Jesse Gross <je...@nicira.com> wrote: > On Wed, Dec 14, 2011 at 4:48 PM, Pravin Shelar <pshe...@nicira.com> wrote: >> On Wed, Dec 14, 2011 at 4:37 PM, Jesse Gross <je...@nicira.com> wrote: >>> On Wed, Dec 14, 2011 at 3:47 PM, Pravin Shelar <pshe...@nicira.com> wrote: >>>> On Wed, Dec 14, 2011 at 3:34 PM, Jesse Gross <je...@nicira.com> wrote: >>>>> On Wed, Dec 14, 2011 at 3:07 PM, Pravin Shelar <pshe...@nicira.com> wrote: >>>>>> On Wed, Dec 14, 2011 at 2:47 PM, Ansis Atteka <aatt...@nicira.com> wrote: >>>>>>> On Wed, Dec 14, 2011 at 2:08 PM, Pravin B Shelar <pshe...@nicira.com> >>>>>>> wrote: >>>>>>>> +int genl_exec(genl_exec_func_t func, void *data) >>>>>>>> +{ >>>>>>>> + struct sk_buff *skb; >>>>>>>> + >>>>>>>> + skb = genlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); >>>>>>>> + if (!skb) >>>>>>>> + return -ENOMEM; >>>>>>>> + >>>>>>>> + genlmsg_put(skb, 0, 0, &genl_exec_family, NLM_F_REQUEST, >>>>>>>> GENL_EXEC_RUN); >>>>>>>> + >>>>>>>> + mutex_lock(&genl_exec_lock); >>>>>>>> + genl_exec_function = func; >>>>>>>> + genl_exec_data = data; >>>>>>>> + init_completion(&done); >>>>>>>> + genlmsg_unicast(&init_net, skb, 0); >>>>>>>> + wait_for_completion(&done); >>>>>>>> + genl_exec_function = NULL; >>>>>>> >>>>>>> Shouldn't you prepare here a copy of genl_exec_function_ret before >>>>>>> actually >>>>>>> returning it? I sense a small-probability of a race condition here. >>>>>>>> >>>>>> right, I need to do it inside lock. Even with lock it is not >>>>>> completely safe as callback is not taking any lock. But I think that >>>>>> is not issue for now. >>>>> >>>>> Isn't all of this executing synchronously anyways, so the callback >>>>> actually is protected by genl_exec_lock and the completion stuff isn't >>>>> necessary? >>>> Its not same across kernel that we care. >>>> callbacks are executed synchronously from 2.6.24 onward. >>> >>> Are you sure? I think it just takes a slightly more convoluted path >>> to get there. If doesn't execute in this context, what context does >>> it execute in? >>> >>> On 2.6.18, for example, I think this is the call stack: >>> - genl_exec >>> - genlmsg_unicast >>> - nlmsg_unicast >>> - netlink_unicast >>> - netlink_sendskb (skb gets enqueued to socket buffer) >>> - netlink_data_ready AKA sk->sk_data_ready >>> - genl_rcv AKA nlk->data_ready >>> - netlink_run_queue (skb gets dequeued from socket buffer) >>> - netlink_rcv_skb >>> - genl_rcv_mesg >>> - genl_exec_cmd AKA doit >>> >>> So there's a lot of useless enqueueing, dequeueing, waking up >>> processes, etc. that are really only needed when sending data to >>> userspace. That was shortcut in later kernels but it doesn't really >>> change anything. >> >> right, but there is genl_trylock() called in genl_rcv(). > > Hmm, I guess you're right. Getting back to Ansis's original question, > assuming that you move retrieving the return value into the lock which > part were you saying isn't completely safe?
GENL_EXEC_RUN msg can be send from other function without taking genl_exec_lock. But we can always enforce locking, so it is not real issue. Never mind. It is just weird that sender is taking lock for rcv function. _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev