我需要在内核代码中实现一个链表(不确定是否太重要)。该代码应使用0到255之间的数字来标识每个链接列表。每个节点在列表和一些其他数据字段中还具有一个ID。我在使其无法正常工作时遇到一些麻烦,并且不确定出了什么问题我已经非常清楚地编写了它,但是似乎存在细分问题。我很高兴了解这里出了什么问题。
注意:我很确定问题不在于它正在使用内核函数。
#undef __KERNEL__
#define __KERNEL__
#undef MODULE
#define MODULE
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/string.h>
MODULE_LICENSE("GPL");
typedef struct Node {
long node_id;
char data[256];
int data_size;
struct Node next;
};
typedef struct List {
int list_id;
struct Node head;
};
/* array holds the Lists by their list_id number */
static struct List* lists = (List*) kmalloc(256 * sizeof(List), GFP_KERNEL);
static struct List* get_list(int list_id) {
return lists[list_id];
}
static struct Node* get_node(struct List* list, long node_id) {
struct Node* node = list->head;
while (node != NULL) {
if (node->node_id == node_id) {
return node;
}
node = node->next;
}
return NULL;
}
static void add_node(struct List* list, long node_id) {
struct Node* node;
node = kmalloc(sizeof(Node), GFP_KERNEL);
node->next = list->head;
list->head = node;
}
static void add_list(int list_id) {
struct List* list;
list = kmalloc(sizeof(List), GFP_KERNEL);
list->list_id = list_id;
lists[list->list_id] = list;
}
static void free_list(struct List* list) {
if (list == NULL) {
return;
}
while (list->head != NULL) {
struct Node* node = list->head;
list->head = node->next;
kfree(node);
}
kfree(list);
}
static void free_lists(void) {
int list_id;
for (list_id = 0 ; list_id < 256; list_id++) {
free_list(lists[list_id]);
}
}
答案 0 :(得分:1)
struct Node next;
您的struct Node
定义中的这一行特别创建了非终止递归,其中struct Node
需要另一个定义的struct Node
才能被正确定义,而后者又需要另一个struct Node
,等等:
我们使用指针是因为我们可以使用NULL终止链表,这意味着除其他外,不再有节点可以连接:
我假设您正在尝试以这种方式实现链接列表和节点,就像它们是函数中的指针一样,其中最著名的是get_list
。
关于kmalloc的另一件事值得一提:
kmalloc是为内核中小于页面大小的对象分配内存的常规方法。
Although I've read that kmalloc can allocate way more memory than this default page size in modern kernels,我不知道您使用的是哪个Linux版本或环境。进行以下假设,您可能需要重新考虑这些数据结构的整体实现,或者至少重新考虑kmalloc的使用:
static struct List* lists
分配的大小是List结构的256倍,舍入后最大为72kb,这比页面大小还要大。对于一个,我建议您有一个使用头节点的指针的列表,而不是让列表存储头本身。我还建议您将char data[256]
设为dynamic array,并且最大容量为256,这样也可以节省一些空间。我还建议您使用指向列表的指针数组(static struct List* lists[256]
,而不是static struct List* lists
或static struct List lists[256]
)。