私はkmem_cache_createとkmem_cache_allocを使ってカーネル空間にスタックを作成するモジュールを作成しています。たぶん私はポインタで何か悪いことをやったことがある、または私はスラブの割り当ての全体の概念をundestandしないでください。私はクラスメートと私の研究室リーダーにコードを示しました、悲しげに誰も私を助けることができませんでした。
はここスラブキャッシュは、あらかじめ定義された関数を持たない構造体のスタックを割り当てます。
#include<linux/module.h>
#include<linux/slab.h>
#include<linux/string.h>
static struct example_struct {
unsigned int id;
char example_string[10];
struct example_struct *next;
} *example_struct_pointer;
static struct example_struct *top = NULL;
static struct kmem_cache *example_cachep;
static void example_constructor(void *argument)
{
static unsigned int id;
static char test_string[] = "Stack";
struct example_struct *example = (struct example_struct *)argument;
example->id = id;
strcpy(example->example_string,test_string);
example->next = top;
top = example;
id++;
}
void print_example_struct(struct example_struct *example)
{
pr_notice("Struct id: %u\n",example->id);
pr_notice("String field content: %s\n",example->example_string);
}
static int __init slabmod_init(void)
{
example_cachep = kmem_cache_create("example cache", sizeof(struct example_struct),0, SLAB_HWCACHE_ALIGN|SLAB_POISON|SLAB_RED_ZONE, example_constructor);
if(IS_ERR(example_cachep)) {
pr_alert("Error creating cache: %ld\n",PTR_ERR(example_cachep));
return -ENOMEM;
}
for(i=1 ; i<6 ; i++)
{
printk(KERN_ALERT "i: %d\n",i);
example_struct_pointer = (struct example_struct *) kmem_cache_alloc(example_cachep,GFP_KERNEL);
if(IS_ERR(example_struct_pointer)) {
pr_alert("Error allocating from cache: %ld\n", PTR_ERR(example_struct_pointer));
kmem_cache_destroy(example_cachep);
return -ENOMEM;
}
}
return 0;
}
static void __exit slabmod_exit(void)
{
struct example_struct *tmp = example_struct_pointer;
if(example_cachep) {
while(example_struct_pointer != NULL) {
print_example_struct(example_struct_pointer);
tmp = example_struct_pointer;
example_struct_pointer = tmp->next;
kmem_cache_free(example_cachep,tmp);
}
kmem_cache_destroy(example_cachep);
}
}
module_init(slabmod_init);
module_exit(slabmod_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("kostek888888");
MODULE_DESCRIPTION("A module demonstrating use of the slab allocator.");
MODULE_VERSION("1.0");
私もこのコードのデバッグバージョンを持っている「スタック」に5つの構造を割り当てる私のコードです:私は範囲0〜12個の要素を取得していた出力で
#include<linux/module.h>
#include<linux/slab.h>
#include<linux/string.h>
static struct example_struct {
unsigned int id;
char example_string[10];
struct example_struct *next;
} *example_struct_pointer;
static struct example_struct *top = NULL;
static struct kmem_cache *example_cachep;
static unsigned int i;
static void example_constructor(void *argument)
{
static unsigned int id;
static char test_string[] = "Stack";
struct example_struct *example = (struct example_struct *)argument;
example->id = id;
strcpy(example->example_string,test_string);
example->next = top;
top = example;
id++;
}
void print_example_struct(struct example_struct *example)
{
pr_notice("Struct id: %u\n",example->id);
//pr_notice("String field content: %s\n",example->example_string);
printk(KERN_ALERT "example_struct_pointer: %p\n",example_struct_pointer);
//printk(KERN_ALERT "top: %p\n",top);
printk(KERN_ALERT "i: %d\n",i);
i++;
}
static int __init slabmod_init(void)
{
example_cachep = kmem_cache_create("example cache", sizeof(struct example_struct),0, SLAB_HWCACHE_ALIGN|SLAB_POISON|SLAB_RED_ZONE, example_constructor);
if(IS_ERR(example_cachep)) {
pr_alert("Error creating cache: %ld\n",PTR_ERR(example_cachep));
return -ENOMEM;
}
for(i=1 ; i<6 ; i++)
{
printk(KERN_ALERT "i: %d\n",i);
example_struct_pointer = (struct example_struct *) kmem_cache_alloc(example_cachep,GFP_KERNEL);
if(IS_ERR(example_struct_pointer)) {
pr_alert("Error allocating from cache: %ld\n", PTR_ERR(example_struct_pointer));
kmem_cache_destroy(example_cachep);
return -ENOMEM;
}
}
return 0;
}
static void __exit slabmod_exit(void)
{
struct example_struct *tmp = example_struct_pointer;
i = 1;
if(example_cachep) {
while(example_struct_pointer != NULL) {
print_example_struct(example_struct_pointer);
printk(KERN_ALERT "tmp: %p\n",tmp);
printk(KERN_ALERT "next: %p/%p\n\n",top->next,*(top->next));
tmp = example_struct_pointer;
example_struct_pointer = tmp->next;
kmem_cache_free(example_cachep,tmp);
}
printk(KERN_ALERT "tmp: %p\n",tmp);
printk(KERN_ALERT "next: %p\n\n",top->next);
printk(KERN_ALERT "example_struct_pointer: %p\n",example_struct_pointer);
kmem_cache_destroy(example_cachep);
}
}
module_init(slabmod_init);
module_exit(slabmod_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("kostek888888");
MODULE_DESCRIPTION("A module demonstrating use of the slab allocator.");
MODULE_VERSION("1.0");
11私はkmem_cache_allocを範囲1〜5で5回だけ実行し、 "スラブキャッシュにはまだオブジェクトがあります"というメッセージも表示します。
Here is screenshot demonstrating words above
その後、メモリのあるものが間違っているようにコールトレースメッセージが表示されます。仮想マシン全体を停止させることがあります。
私は__exitの中でポインタを交換していますが、 "トップ"ポインタは何を表示するかを確認するために使用しました - 122個の要素と同じメッセージがあったので、おそらく全体がスラブです。ポインタ "next"は常にDECの同じ値122を持ちます - 構造は122バイト幅ですか? Sizeof構造体は%dで1,000,000を超える大きな値を得ました。一つだけの構造を割り当て、魔法のように動作
オリジナルコード:
#include<linux/module.h>
#include<linux/slab.h>
#include<linux/string.h>
static struct example_struct {
unsigned int id;
char example_string[10];
} *example_struct_pointer;
static struct kmem_cache *example_cachep;
static void example_constructor(void *argument)
{
static unsigned int id;
static char test_string[] = "Test";
struct example_struct *example = (struct example_struct *)argument;
example->id = id;
strcpy(example->example_string,test_string);
id++;
}
void print_example_struct(struct example_struct *example)
{
pr_notice("Example struct id: %u\n",example->id);
pr_notice("Example string field content: %s\n",example->example_string);
}
static int __init slabmod_init(void)
{
example_cachep = kmem_cache_create("example cache", sizeof(struct example_struct),0, SLAB_HWCACHE_ALIGN|SLAB_POISON|SLAB_RED_ZONE, example_constructor);
if(IS_ERR(example_cachep)) {
pr_alert("Error creating cache: %ld\n",PTR_ERR(example_cachep));
return -ENOMEM;
}
example_struct_pointer = (struct example_struct *) kmem_cache_alloc(example_cachep,GFP_KERNEL);
if(IS_ERR(example_struct_pointer)) {
pr_alert("Error allocating form cache: %ld\n", PTR_ERR(example_struct_pointer));
kmem_cache_destroy(example_cachep);
return -ENOMEM;
}
return 0;
}
static void __exit slabmod_exit(void)
{
if(example_cachep) {
if(example_struct_pointer) {
print_example_struct(example_struct_pointer);
kmem_cache_free(example_cachep,example_struct_pointer);
}
kmem_cache_destroy(example_cachep);
}
}
module_init(slabmod_init);
module_exit(slabmod_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Arkadiusz Chrobot <***>");
MODULE_DESCRIPTION("A module demonstrating useing of the slab allocator.");
MODULE_VERSION("1.0");
私は、Linuxのデバイスドライバと似たような本をチェックしました - どこでも1つの要素の例と単なる関数です。
私はカーネル3.16.0-4-686-paeを使用していますが、カーネル4.9では状況は同じです。
は、私はあなたが間違ってがctor()
(kmem_cache_create()
への最後の引数が)毎回あなたがkmem_cache_create()
を呼び出すと呼ばれていることを前提としていすべての応答:)