Эта функция принимает переменное количество параметров, по аналогии с функциями printf()
printk(). Как уже было сказано, на имя объекта указывает поле k_name структуры kobject. Если это имя достаточно короткое, то оно хранится в статически выделенном массиве name, поэтому есть смысл без необходимости не указывать длинные имена.После того как для объекта выделена память и объекту присвоено имя, нужно установить значение его поля kset
ktype. Последнее необходимо делать только в том случае, если множество kset не предоставляет типа ktype для данного объекта, в противном случае значение поля ktype, которое указано в структуре kset, имеет преимущество. Если интересно, почему объекты kobject имеют свое поле ktype, то добро пожаловать в клуб!Счетчики ссылок
Одно из главных свойств, которое реализуется с помощью объектов kobject
Увеличение значения счетчика ссылок выполняется с помощью функции kobject_get()
struct kobject* kobject_get(struct kobject *kobj);
Эта функция возвращает указатель на объект kobject
NULL в случае ошибки.Уменьшение значения счетчика ссылок выполняется с помощью функции kobject_put()
void kobject put(struct kobject *kobj);
Если значение счетчика ссылок объекта, который передается в качестве параметра, становится равным нулю, то вызывается функция, на которую указывает указатель release
ktype этого объекта.Структуры kref
Внутреннее представление счетчика ссылок выполнено с помощью структуры kref
следующим образом.struct kref {
atomic_t refcount;
};
Единственное поле этой структуры — атомарная переменная, в которой хранится значение счетчика ссылок. Структура используется просто для того, чтобы выполнять проверку типов. Чтобы воспользоваться структурой kref
kref_init().void kref_init(struct kref *kref) {
atomic_set(&kref->refcount, 1);
}
Как видно из определения, эта функция просто инициализирует атомарную переменную тина atomic_t
Следовательно, структура kref
kobject.Для того чтобы захватить ссылку на структуру kref
kref_get().void kref_get(struct kref *kref) {
WARN_ON(!atomic_read(&kref->refcount));
atomic_inc(&kref->refcount);
}
Эта функция увеличивает значение счетчика ссылок на единицу. Она не возвращает никаких значений. Чтобы освободить ссылку на структуру kref
kref_put().void kref_put(struct kref *kref, void (*release)(struct kref *kref)) {
WARN_ON(release == NULL);
WARN_ON(release == (void(*)(struct kref*))kfree);
if (atomic_dec_and_test(&kref->refcount))
release (kref);
}
Эта функция уменьшает значение счетчика ссылок на единицу и вызывает функцию release()
WARN_ON(), функция release() не может просто совпадать с функцией kfrее(), а должна быть специальной функцией, которая принимает указатель на структуру struct kref в качестве своего единственного параметра и не возвращает никаких значений.Вместо того чтобы разрабатывать свои функции управления счетчиками ссылок на основании типа данных atomic_t
kref и соответствующие функции, которые обеспечивают общий и правильно работающий механизм поддержки счетчиков ссылок в ядре.