2015-09-11 4 views
5

Скажите, что я зарегистрировал общий сетевой интерфейс с использованием genl_register_family_with_ops с несколькими обратными вызовами.Linux Kernel Generic Netlink - Параллельно ли это?

Я не вижу никаких предупреждений об этом, и я предполагаю, что обратные вызовы вызываются последовательно, но нет информации о том, как вызываемые вызовы не вызываются.

Возможно ли, что несколько обратных вызовов вызываются одновременно на одном и том же общем сетевом интерфейсе, который я зарегистрировал? Нужна ли какая-либо синхронизация между обратными вызовами?

Для того, чтобы вопрос проще:

Может ли один NetLink обратного вызова будет вытеснен или одновременно работать в двух ядрах?

+0

Обратные вызовы вызываются при возникновении события. Если произойдет еще одно событие до завершения обратного вызова, он получит перекрывающий вызов. – stark

+0

@stark Я более конкретно спрашиваю, могу ли я получить два события в одной и той же семейной регистрации сети, которая может перекрывать обратные вызовы. Существует только одна регистрация с несколькими обратными вызовами. Обратные вызовы Netlink будут изменять одни и те же структуры, и структуры будут только модифицироваться/получаться путем обратных вызовов netlink. – Etherealone

+1

@Etherealone Я подозреваю, что ответ заключается в том, что он настраивается, но отключен по умолчанию. В моей копии источников ядра 3.11, 'struct genl_family' содержит' bool parallel_ops'. В 'linux-3.11.10-21/net/netlink/genetlink.c: 674' или nearabouts в' genl_rcv_msg() ', если этот флаг не установлен, то глобальный мьютекс заблокирован, запрос обрабатывается и глобальный мьютекс разблокирован. Если он установлен, эта блокировка не выполняется. –

ответ

2

Ответ предполагает, что версия ядра Linux версии 3.11 или 4.2, вероятно, действительна для многих других. Ответ по состоянию на сентябрь 2015 года

ли обратные вызовы могут быть одновременно или не является настраиваемым свойством struct genl_family во время регистрации, но если явно не указано, является вероятно дефолт от. Это связано с 1) Наличие bool parallel_ops члена в struct genl_family, и 2) Неинициализированные члены статической продолжительности-struct будучи по умолчанию для 0 в C.

На приеме 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() вызывается (защищенным или незащищенным от мьютекса), фактические обратный вызов here.