Ядро Linux - Красные / Черные Деревья - PullRequest
3 голосов
/ 20 апреля 2010

Я пытаюсь реализовать красное / черное дерево в Linux для task_struct, используя код из linux/rbtree.h. Я могу получить красное / черное дерево, вставленное должным образом в отдельное пространство в ядре, например, в модуль, но когда я пытаюсь заставить работать тот же код с rb_root, объявленным либо в task_struct, либо task_struct->files_struct, я получаю SEGFAULT каждый раз, когда я пытаюсь вставить.

Вот код:

В task_struct я создаю структуру rb_root для своего дерева (не указатель). В init_task.h, макрос INIT_TASK(tsk), я установил это равным RB_ROOT. Чтобы сделать вставку, я использую этот код:

rb_insert(&(current->fd_tree), &rbnode);

Здесь возникает проблема.

Моя команда вставки является стандартной вставкой, которая описана во всей документации RBTree для ядра:

  int my_insert(struct rb_root *root, struct mytype *data)
  {
    struct rb_node **new = &(root->rb_node), *parent = NULL;

    /* Figure out where to put new node */
    while (*new) {
        struct mytype *this = container_of(*new, struct mytype, node);
        int result = strcmp(data->keystring, this->keystring);

        parent = *new;
        if (result < 0)
            new = &((*new)->rb_left);
        else if (result > 0)
            new = &((*new)->rb_right);
        else
            return FALSE;
    }

    /* Add new node and rebalance tree. */
    rb_link_node(&data->node, parent, new);
    rb_insert_color(&data->node, root);

    return TRUE;
  }

Я что-то упускаю?

По какой причине это будет работать нормально, если я сделаю корень дерева за пределами task_struct? Если я сделаю rb_root внутри модуля, эта вставка работает нормально. Но как только я помещаю фактический корень дерева в task_struct или даже в task_struct->files_struct, я получаю SEGFAULT. Разве корневой узел не может быть добавлен в эти структуры?

Любые советы приветствуются. Я перепробовал почти все, что мог придумать.


Edit:

Я получаю SEGFAULT в следующей строке при попытке печати и любую строку, которая обращается к дереву. С этой строкой вы должны понять, как я справляюсь с указателями. rb_entry и rb_first - это методы, уже доступные в ядре. current - это указатель на структуру задачи (текущий рабочий процесс), а дерево - это мой корневой узел (не указатель), который является членом структуры задачи (я добавил). rb_first необходимо передать указатель *rb_root. Я делаю это неправильно.

printk(KERN_CRIT "node=%d\n", rb_entry(rb_first(&(current->tree)), struct rb_tree_struct, node)->fd_key);

1 Ответ

0 голосов
/ 20 апреля 2010

Может быть, значения указателя корня и / или данных не соответствуют вашим ожиданиям? Может быть полезно добавить

printk("%s: root=%p data=%p\n", __func__, root, data);

перед циклом while().

...