Возможно ли защитить ___ nf_conntrack_find () возвращаемое значение с помощью RCU? - PullRequest
1 голос
/ 09 июля 2019

Интересно nf_conntrack_find_get(), которые действительно защищают указатель ct с помощью RCU в ядре Linux.

Read-Copy-Update (RCU) может защитить доступ (чтение) критической секции rcu_read_side узла при обновлении узла.Но это не означает защищенный узел.

nf_conntrack_find_get() вызов ___nf_conntrack_find.__nf_conntrack_find возвращено h (rcu potioner).

Но другой процесс может получить доступ к тому же h и free(h).

В настоящее время я думаю, что ct не защищен.

h используется для вычисления смещения и получения указателя ct.

Можем ли мы думать, что h или ct безопасны?

Ниже приведен код ..

/ net / netfilter / nf_conntrack_core.c :

__nf_conntrack_find_get() {

    rcu_read_lock();

    h = ____nf_conntrack_find(net, zone, tuple, hash);
    if (h) {
        // RCU can't protect free h. only ensures to read old copy.
        // If another processor free same h, h is freed.
        // is really h available next line?

        ct = nf_ct_tuplehash_to_ctrack(h);

        ....
    } 
}
rcu_read_unlock();

Я думаю, что если вы хотите защитить узел (h), придется использовать call_rcu() вместо прямого освобожденияв destroy_conntrack().

1 Ответ

0 голосов
/ 12 июля 2019

Мой вопрос в том, что h может быть освобожден другой процесс тогда «Является ли h безопасным?», «Если h безопасен, как это работает?»

вот ответы.

Обратите внимание, что h во всех контекстах означает то же самое значение ct (ct просто вычисляется как h).

Q. H безопасно?

Во-первых, нужно определить, что означает "безопасен ли он?"

Как правило, «указатель безопасен» означает, что адрес, на который указывает указатель, доступен и не освобожден. Так что, если использовать указатель или указатель членов, можно получить к ним доступ без нарушений.

смотреть в этом контексте код,

Ответ: «Ч может быть освобожден, но не произошло нарушений!» (вау: O).

Если использовать call_rcu () в destroy_conntrack (), h не сможет освободить использование периода отсрочки. но CT освобождается непосредственно в destroy_conntrack ().

как защитить ct без call_rcu (). (Даже не произошло нарушение).

Хитрость в использовании hlist_nulls (SLAB_TYPESAFE_BY_RCU).

узлы ct расположены SLAB_TYPESAFE_BY_RCU. эта ячейка памяти свободна для повторного использования в любое время.

Итак, узлы постоянно имеют одинаковое смещение. мы можем получить к ним доступ, даже освободившись.

Конечно, необходимо защищать несколько ограничений (барьеры памяти, атомарные операции, использовать счетчик ссылок, проверять повторно используемые узлы ...)

Более подробную информацию и ограничения вы читаете по ссылке ниже

https://github.com/westerndigitalcorporation/RISC-V-Linux/blob/master/linux/Documentation/RCU/rculist_nulls.txt

...