1

ドライバーに AIO のサポートを追加し (カーネルランドでは .aio_read 、 .aio_write 呼び出し、ユーザーランドでは libaio )、さまざまなソースを調べましたが、 aio_read 、 .aio_write 呼び出しで iovector 引数へのポインターを格納するだけでよいかどうかを確認できます。 (このメモリは、たとえば aio_complete が呼び出されるまで手付かずのままであると仮定して)、または iovector データ構造をディープ コピーする必要があると仮定します。

static ssize_t aio_read( struct kiocb *iocb, const struct iovec *iovec, unsigned long nr_segs, loff_t pos );
static ssize_t aio_write( struct kiocb *iocb, const struct iovec *iovec, unsigned long nr_segs, loff_t pos );

例として \drivers\usb\gadget\inode.c の実装を見ると、ep_aio_rwtail 関数のポインターをコピーするだけのようです。

priv->iv = iv;

しかし、似たようなことをしようとすると、処理するまでにiovectorのデータが「破損」することが非常に定期的に発生します。

たとえば、ログに記録する aio_read/write 呼び出しで

iovector located at addr:0xbf1ebf04
segment 0: base: 0x76dbb468        len:512

しかし、カーネルスレッドで実際の作業を行うと(ユーザースペースmmにアタッチした後)、次のログが記録されました。

iovector located at addr:0xbf1ebf04
segment 0: base: 0x804e00c8        len:-1088503900

これは、ユーザー アプリケーションで 1 つの非同期コマンドのみを送信する非常に単純なテスト ケースです。

さらに興味深いことに、私は 3.13 カーネルで約 80% の確率で破損しています。

しかし、これまで 3.9 カーネルで見たことはありませんでした (ただし、3.13 にアップグレードする前に少しだけ使用しただけで、今では正気に戻り、何十回も試してみました)。( 3.9 カーネルで実行した例では、

iovector located at addr:0xbf9ee054
segment 0: base: 0x76e28468        len:512)

これは鐘を鳴らしますか?

(もちろん、これらのアドレス/長さを自分で破損している可能性もありますが、3.9 でこれがなかったのは奇妙です)

編集: Linux aio の 3.13 コード (動作していた 3.9 から大幅に変更された) を確認した後、自分の質問に答えるには、fs\aio.c に次のように記述します。

static ssize_t aio_run_iocb(struct kiocb *req, unsigned opcode, char __user *buf, bool compat) { ... struct iovec inline_vec, *iovec = &inline_vec; ... ret = rw_op(req, iovec, nr_segs, req->ki_pos); ... }

したがって、この iovec 構造体はスタック上にあり、aio_read/write 関数が終了するとすぐに失われます。

また、ガジェット フレームワークには、\drivers\usb\gadget\inode.c... に (少なくとも 3.13 の) バグが含まれています。

4

1 に答える 1

0

aio_readのマニュアルページから;

注意 使用前に制御ブロックをゼロにすることをお勧めします。読み取り操作の進行中は、制御ブロックを変更してはなりません。読み込み中のバッファ領域は、操​​作中にアクセスしてはなりません。アクセスすると、未定義の結果が発生する可能性があります。関連するメモリ領域は有効なままでなければなりません。

同じ aiocb 構造体を指定する同時入出力操作は、未定義の結果を生成します。

これは、操作中にドライバーがユーザーのデータ構造に依存できることを示しています。操作中にこれらの構造が変更されたことを検出した場合は、操作を中止して非同期エラーを返すことをお勧めします。

于 2014-03-06T15:14:45.913 に答える