1

PCIeブロックデバイスドライバーを使用してファイルを読み書きするときに、本当に理解できないエラーが発生します。swiotlb_unmap_sg_attrs()で問題が発生しているようです。これは、ポインターのNULL逆参照を行っているようsgですが、これがどこから来ているのかわかりません。scatterlist自分で使用しているのはデバイス情報の一部として割り当てられているためです。構造化され、ドライバーが実行する限り存続します。

問題に対応するためのスタックトレースがあります。正確な詳細は少し異なる傾向がありますが、常にでクラッシュしswiotlb_unmap_sq_attrs()ます。

IO関数の周りのロックを処理する方法がわからないため、ロックの問題が発生している可能性が高いと思います。関数が呼び出されたときにロックはすでに保持されていrequestます。完了するには(MSI)IRQが必要なため、IO関数自体が呼び出される前にロックを解放します。IRQハンドラーは、IO関数が待機している「ステータス」値を更新します。IO関数が戻ったら、ロックを元に戻し、キュー処理の要求に戻ります。

クラッシュは次の間に発生しblk_fetch_request()ます。

if (!__blk_end_request(req, res, bytes)){
    printk(KERN_ERR "%s next request\n", DRIVER_NAME);

    req = blk_fetch_request(q);
} else {
    printk(KERN_ERR "%s same request\n", DRIVER_NAME);
}

ここでbytes、要求ハンドラーによって、IOの全長(各スキャッター・ギャザー・セグメントの合計長)になるように更新されます。

4

1 に答える 1

0

requestこれは、関数の再入可能性によるものであることが判明しました。IRQ が入るのを許可するために途中でロックを解除していたので、request関数が再度呼び出され、(元の要求ハンドラーが IO を待っている間に) ロックを取得し、間違ったハンドラーが IRQ を取得し、すべてが南に行きました。失敗した IO のスタック。

私がこれを解決した方法は、リクエスト関数の開始時に「ビジー」フラグを設定し、最後にそれをクリアし、これが設定されている場合は関数の開始時にすぐに戻ることでした:

static void mydev_submit_req(struct request_queue *q){
    struct mydevice *dev = q->queuedata;

    // We are already processing a request
    // so reentrant calls can take a hike
    // They'll be back
    if (dev->has_request)
        return;

    // We own the IO now, new requests need to wait
    // Queue lock is held when this function is called
    // so no need for an atomic set
    dev->has_request = 1; 

    // Access request queue here, while queue lock is held

    spin_unlock_irq(q->queue_lock);

    // Perform IO here, with IRQs enabled
    // You can't access the queue or request here, make sure 
    // you got the info you need out before you release the lock

    spin_lock_irq(q->queue_lock);

    // you can end the requests as needed here, with the lock held

    // allow new requests to be processed after we return
    dev->has_request = 0;

    // lock is held when the function returns
}

ただし、一貫して からスタックトレースを取得した理由はまだわかりませんswiotlb_unmap_sq_attrs()

于 2012-12-13T10:58:50.973 に答える