0

私は、フィボナッチシリーズのシーケンスを含むパケットを送信するためのPKTGENの変更に取り組んでいます。これはカーネル開発で初めてのことですので、メモリ割り当てに利用できる機能にはあまり慣れていません。私はC教祖でもありません:)Linuxカーネルモジュールの動的配列

アルゴリズムの反復ステップを配列に格納します。誰かが偉大なフィボナッチnパラメータを求めている場合は、動的にしたいと考えています。

Reallocは利用できません。動的に配列サイズを拡大する方法を知っていますか?

これはカーネルの開発をサポートするために意図されているものの一種ではありませんあなたに

答えて

2

で見るデーブ・ハンセン柔軟な配列は2.6.31-RC5に

を追加します

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

可撓性アレイの作成

を用いて行われます

個々のオブジェクトサイズはelement_sizeによって提供され、totalは配列に格納できるオブジェクトの最大数です。 flags引数は、内部メモリ割り当て呼び出しに直接渡されます。現在のコードでは、フラグを使用してメモリを要求すると、特に不愉快な副作用が発生する可能性があります。

が可撓性アレイにデータを格納するがへの呼び出しを用いて達成される:

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

この呼び出しは、最大値より小さくなければならないelement_nr(で示す位置に、配列にSRCからのデータをコピーします配列の作成時に指定)。メモリ割り当てを実行する必要がある場合は、フラグが使用されます。戻り値は成功した場合は0、それ以外の場合は負のエラーコードです。

ある種のアトミックなコンテキストで実行している間は、データを柔軟な配列に格納する必要があるかもしれません。この状況では、メモリアロケータでスリープ状態が悪いことになります。これは、フラグ値にGFP_ATOMICを使用することで回避できますが、多くの場合、より良い方法があります。トリックは、必要なメモリ割り当てを使用して、原子のコンテキストに入る前に行われることを保証することである。

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

この関数の開始と終了によって定義される範囲で索引付け要素のためのメモリが割り当てられていることを保証します。その後、その範囲内の要素に対するflex_array_put()呼び出しはブロックされないことが保証されます。その特定の要素が割り当てされていない場合

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

戻り値はデータ要素、またはNULLを指すポインタである:バックアレイのうち

取得データを用いて行われます。

配列に格納されていない要素の有効なポインタを取得することができます。配列要素のメモリは一度に1ページずつ割り当てられます。 1回の割り当てでいくつかの隣接要素のメモリを提供することができます。フレキシブル配列コードは、特定の要素が書き込まれているかどうかを知りません。関連するメモリが存在するかどうかしかわかりません。そのため、配列に格納されていない要素のflex_array_get()呼び出しは、ランダムなデータへのポインタを返す可能性があります。呼び出し元が実際にどの要素が格納されているかを知るための別個の方法がない場合は、少なくともGFP_ZEROをflags引数に追加して、すべての要素がゼロになるようにすることが賢明かもしれません。

アレイから1つの要素を削除する方法はありません。この呼び出しは、すべての要素を解放しますが、所定の位置に配列自体を残し

void flex_array_free_parts(struct flex_array *array); 

:それはへの呼び出しを持つすべての要素を削除するには、しかし、可能です。

void flex_array_free(struct flex_array *array); 

この記事の執筆時点では、メインラインカーネルにはフレキシブルアレイのユーザーがいませんでした。ここで説明する関数もモジュールにエクスポートされません。誰かがそれを必要とするときにおそらく修正されるでしょう。

+0

これらのフレックスアレイはどのように使用しますか?あなたは例を挙げていただけますか?ありがとう! –

1

ありがとうございます。これをユーザーモードプログラムにする方がはるかに適切です。

しかし、それを行う方法は、独自の動的長さの配列を実装することです。配列の大きさを追跡します。拡大する必要がある場合は、新しいサイズのkmalloc()(通常はGFP_KERNELパラメータ)を呼び出し、古いデータを新しいデータにコピーし、古いデータ(kfree())を廃棄します。カーネルヘッダーファイルを参照

アレイが約4Kまたは8Kより大きい場合は、代わりに__get_free_pages()またはvmalloc()を使用することを検討してください。

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

関連する問題