virtiofs: Set FR_SENT flag only after request has been sent

FR_SENT flag should be set when request has been sent successfully sent
over virtqueue. This is used by interrupt logic to figure out if interrupt
request should be sent or not.

Also add it to fqp->processing list after sending it successfully.

Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
This commit is contained in:
Vivek Goyal 2019-10-15 13:46:24 -04:00 committed by Miklos Szeredi
parent 7ee1e2e631
commit 5dbe190f34
1 changed files with 10 additions and 13 deletions

View File

@ -857,6 +857,7 @@ static int virtio_fs_enqueue_req(struct virtio_fs_vq *fsvq,
unsigned int i; unsigned int i;
int ret; int ret;
bool notify; bool notify;
struct fuse_pqueue *fpq;
/* Does the sglist fit on the stack? */ /* Does the sglist fit on the stack? */
total_sgs = sg_count_fuse_req(req); total_sgs = sg_count_fuse_req(req);
@ -911,6 +912,15 @@ static int virtio_fs_enqueue_req(struct virtio_fs_vq *fsvq,
goto out; goto out;
} }
/* Request successfully sent. */
fpq = &fsvq->fud->pq;
spin_lock(&fpq->lock);
list_add_tail(&req->list, fpq->processing);
spin_unlock(&fpq->lock);
set_bit(FR_SENT, &req->flags);
/* matches barrier in request_wait_answer() */
smp_mb__after_atomic();
fsvq->in_flight++; fsvq->in_flight++;
notify = virtqueue_kick_prepare(vq); notify = virtqueue_kick_prepare(vq);
@ -939,7 +949,6 @@ __releases(fiq->lock)
struct virtio_fs *fs; struct virtio_fs *fs;
struct fuse_conn *fc; struct fuse_conn *fc;
struct fuse_req *req; struct fuse_req *req;
struct fuse_pqueue *fpq;
struct virtio_fs_vq *fsvq; struct virtio_fs_vq *fsvq;
int ret; int ret;
@ -958,14 +967,6 @@ __releases(fiq->lock)
req->in.h.nodeid, req->in.h.len, req->in.h.nodeid, req->in.h.len,
fuse_len_args(req->args->out_numargs, req->args->out_args)); fuse_len_args(req->args->out_numargs, req->args->out_args));
fpq = &fs->vqs[queue_id].fud->pq;
spin_lock(&fpq->lock);
list_add_tail(&req->list, fpq->processing);
spin_unlock(&fpq->lock);
set_bit(FR_SENT, &req->flags);
/* matches barrier in request_wait_answer() */
smp_mb__after_atomic();
retry: retry:
fsvq = &fs->vqs[queue_id]; fsvq = &fs->vqs[queue_id];
ret = virtio_fs_enqueue_req(fsvq, req); ret = virtio_fs_enqueue_req(fsvq, req);
@ -978,10 +979,6 @@ retry:
} }
req->out.h.error = ret; req->out.h.error = ret;
pr_err("virtio-fs: virtio_fs_enqueue_req() failed %d\n", ret); pr_err("virtio-fs: virtio_fs_enqueue_req() failed %d\n", ret);
spin_lock(&fpq->lock);
clear_bit(FR_SENT, &req->flags);
list_del_init(&req->list);
spin_unlock(&fpq->lock);
/* Can't end request in submission context. Use a worker */ /* Can't end request in submission context. Use a worker */
spin_lock(&fsvq->lock); spin_lock(&fsvq->lock);