0

我正在修改 PKTGEN 以发送包含斐波那契数列序列的数据包。这是我第一次接触内核开发,所以我对内存分配的可用函数不是很熟悉。我也不是 C 大师 :)

我将算法的迭代步骤存储在一个数组中,如果有人要求一个很好的斐波那契 n 参数,我希望它是动态的。

Realloc 不可用。你知道动态扩大数组大小的方法吗?

谢谢

4

2 回答 2

2

请参阅 Dave Hansen 灵活阵列添加到 2.6.31-rc5

https://lwn.net/Articles/345273/

灵活数组的创建通过以下方式完成:

#include <linux/flex_array.h>

struct flex_array *flex_array_alloc(int element_size, int total, gfp_t flags);

单个对象的大小由 element_size 提供,而 total 是可以存储在数组中的最大对象数。flags 参数直接传递给内部内存分配调用。使用当前代码,使用标志请求高内存可能会导致明显不愉快的副作用。

将数据存储到一个灵活的数组是通过调用来完成的:

int flex_array_put(struct flex_array *array, int element_nr, void *src, gfp_t flags);

此调用会将数据从 src 复制到数组中,在 element_nr 指示的位置(必须小于创建数组时指定的最大值)。如果必须执行任何内存分配,将使用标志。成功时返回值为零,否则返回负错误代码。

在某种原子上下文中运行时,可能需要将数据存储到一个灵活的数组中;在这种情况下,睡在内存分配器中将是一件坏事。这可以通过使用 GFP_ATOMIC 作为标志值来避免,但通常有更好的方法。诀窍是确保在进入原子上下文之前完成任何需要的内存分配,使用:

int flex_array_prealloc(struct flex_array *array, int start, int end, gfp_t flags);

此函数将确保已为 start 和 end 定义的范围内索引的元素分配内存。此后,保证对该范围内的元素的 flex_array_put() 调用不会阻塞。

从数组中取回数据是通过以下方式完成的:

void *flex_array_get(struct flex_array *fa, int element_nr);

返回值是指向数据元素的指针,如果该特定元素从未被分配,则返回 NULL。

请注意,可以为从未存储在数组中的元素取回有效指针。数组元素的内存一次分配一页;单个分配可以为几个相邻元素提供内存。灵活数组代码不知道是否已写入特定元素;它只知道相关的内存是否存在。因此,对从未存储在数组中的元素调用 flex_array_get() 有可能返回指向随机数据的指针。如果调用者没有单独的方法来知道实际存储了哪些元素,那么至少将 GFP_ZERO 添加到 flags 参数以确保所有元素都归零可能是明智的。

无法从数组中删除单个元素。但是,可以通过以下调用删除所有元素:

void flex_array_free_parts(struct flex_array *array);

此调用释放所有元素,但将数组本身留在原处。释放整个数组是通过以下方式完成的:

void flex_array_free(struct flex_array *array);

在撰写本文时,主线内核中还没有灵活数组的用户。此处描述的功能也不会导出到模块;当有人提出需要时,这可能会得到解决。

于 2013-05-02T09:23:37.030 回答
1

这不是内核开发想要支持的那种东西。将其设为用户模式程序会更合适。

但是,这样做的方法是实现您自己的动态长度数组。跟踪阵列有多大。如果它需要增长,用新的大小调用kmalloc()(通常带有GFP_KERNEL参数),将旧数据复制到新数据,并处理旧数据(kfree())。查看内核头文件

如果阵列将大于大约 4K 或 8K,请考虑使用__get_free_pages()orvmalloc()代替。

kmalloc() 和 kfree() 在linux-2.X.XX.XX/include/linux/slob_def.h
__get_free_pages() 在linux-2.X.XX.XX/include/linux/gfp.h
vmalloc() 在linux-2.X.XX.XX/include/linux/vmalloc.h

于 2011-05-18T00:25:01.340 回答