Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Wait on individual buffers than the whole channel in v9fs_intr_complete
In case of multiple concurrent vt9p_request() calls, there exists a situation where one of the call dequeues all the posted responses before virtqueue_intr_filter() was called. In such case virtqueue_intr() will never be called and results in the other vt9p_requests() call returning EIO. This can be demonstrated by the following sequence: .... Thread A (on vCPU0) Thread B (on vCPU1) ------------------------------------------------------------------- mtx_lock(chan->mtx) { acquired; } mtx_lock(chan->mtx) { virtqueue_enqueue(vq0, reqA) virtqueue_notify(vq0) virtqueue_dequeue(vq0)): null msleep() { mtx_unlock(chan->mtx); acquired; }; virtqueue_enqueue(vq0, reqB) virtqueue_notify(vq0) virtqueue_dequeue(vq0): reqA; reqA->rc->tag = reqA->tc->tag reqB->rc->tag == P9_NOTAG virtqueue_dequeue(vq0): reqB; reqB->rc->tag = reqB->tc->tag reqB->rc->tag != P9_NOTAG mtx_unlock(chan->mtx) return virtqueue_intr_filter(): FILTER_STRAY!!! mtx_lock(chan->mtx) { acquired; }; } mtx_unlock(chan->mtx) return EIO .... This change moves the dequeue of responses to VirtIO-9P interrupt handler, and wakes up the p9_req_t initiated by each vt9p_request() calls. Tests were done on ACX5448 with the following case: .... i=0 while [ $i -lt 3 ] ; do dd if=/dev/zero of=/hostvar/testdir/testfile.$i bs=1048576 count=128 status=progress & i=$((i+1)) done wait .... PR: 1727581 Change-Id: I189e88a623b6408aac9993c8ac43b1e57adc916e
- Loading branch information