私はカーネル モジュールに取り組んでおり、2 つのバッファーを比較して、それらが同等かどうかを確認する必要があります。そのために、Linux カーネルで定義されている memcmp 関数を使用しています。私の最初のバッファは次のようなものです:
cache_buffer = (unsigned char *)vmalloc(4097);
cache_buffer[4096] = '/0';
2 番目のバッファーは、page_address() 関数を使用したページからのものです。
page = bio_page(bio);
kmap(page);
write_buffer = (char *)page_address(page);
kunmap(page);
両方のバッファの内容を事前に印刷しましたが、正しく印刷されるだけでなく、同じ内容も含まれています。次に、次のようにします。
result = memcmp(write_buffer, cache_buffer, 2048); // only comparing up to 2048 positions
これにより、カーネルがフリーズし、その理由がわかりません。memcmp の実装を確認しましたが、フリーズを引き起こすものは何もありませんでした。誰でも原因を提案できますか?
memcmp の実装は次のとおりです。
int memcmp(const void *cs, const void *ct, size_t count)
{
const unsigned char *su1, *su2;
int res = 0;
for (su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--)
if ((res = *su1 - *su2) != 0)
break;
return res;
}
編集: フリーズを引き起こす関数は memcmp です。コメントアウトすると、すべてが機能しました。また、私がしたときは次のように memcmp しました
memcmp(write_buffer, write_buffer, 2048); //comparing two write_buffers
すべてが同様に機能しました。cache_buffer をミックスに投入したときだけ、エラーが発生します。また、上記は私の実際のコードを簡略化したものです。関数全体は次のとおりです。
static int compare_data(sector_t location, struct bio * bio, struct cache_c * dmc)
{
struct dm_io_region where;
unsigned long bits;
int segno;
struct bio_vec * bvec;
struct page * page;
unsigned char * cache_data;
char * temp_data;
char * write_data;
int result, length, i;
cache_data = (unsigned char *)vmalloc((dmc->block_size * 512) + 1);
where.bdev = dmc->cache_dev->bdev;
where.count = dmc->block_size;
where.sector = location << dmc->block_shift;
printk(KERN_DEBUG "place: %llu\n", where.sector);
dm_io_sync_vm(1, &where, READ, cache_data, &bits, dmc);
length = 0;
bio_for_each_segment(bvec, bio, segno)
{
if(segno == 0)
{
page = bio_page(bio);
kmap(page);
write_data = (char *)page_address(page);
//kunmap(page);
length += bvec->bv_len;
}
else
{
page = bio_page(bio);
kmap(page);
temp_data = strcat(write_data, (char *)page_address(page));
//kunmap(page);
write_data = temp_data;
length += bvec->bv_len;
}
}
printk(KERN_INFO "length: %u\n", length);
cache_data[dmc->block_size * 512] = '\0';
for(i = 0; i < 2048; i++)
{
printk("%c", write_data[i]);
}
printk("\n");
for(i = 0; i < 2048; i++)
{
printk("%c", cache_data[i]);
}
printk("\n");
result = memcmp(write_data, cache_data, length);
return result;
}
編集#2:申し訳ありません。問題は memcmp ではありませんでした。memcmpの結果でした。正または負の数値が返されるたびに、私の関数を呼び出した関数がいくつかのポインターを操作し、そのうちの 1 つが初期化されていませんでした。なんで今まで気づかなかったのかわからない。でも助けてくれてありがとう!