Skip to content

Commit

Permalink
hwrng: virtio - always add a pending request
Browse files Browse the repository at this point in the history
If we ensure we have already some data available by enqueuing
again the buffer once data are exhausted, we can return what we
have without waiting for the device answer.

Signed-off-by: Laurent Vivier <lvivier@redhat.com>
Link: https://lore.kernel.org/r/20211028101111.128049-5-lvivier@redhat.com
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
  • Loading branch information
vivier authored and mstsirkin committed Nov 1, 2021
1 parent 5c8e933 commit 9a4b612
Showing 1 changed file with 12 additions and 14 deletions.
26 changes: 12 additions & 14 deletions drivers/char/hw_random/virtio-rng.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ struct virtrng_info {
struct virtqueue *vq;
char name[25];
int index;
bool busy;
bool hwrng_register_done;
bool hwrng_removed;
/* data transfer */
Expand All @@ -44,16 +43,18 @@ static void random_recv_done(struct virtqueue *vq)
return;

vi->data_idx = 0;
vi->busy = false;

complete(&vi->have_data);
}

/* The host will fill any buffer we give it with sweet, sweet randomness. */
static void register_buffer(struct virtrng_info *vi)
static void request_entropy(struct virtrng_info *vi)
{
struct scatterlist sg;

reinit_completion(&vi->have_data);
vi->data_avail = 0;
vi->data_idx = 0;

sg_init_one(&sg, vi->data, sizeof(vi->data));

/* There should always be room for one buffer. */
Expand All @@ -69,6 +70,8 @@ static unsigned int copy_data(struct virtrng_info *vi, void *buf,
memcpy(buf, vi->data + vi->data_idx, size);
vi->data_idx += size;
vi->data_avail -= size;
if (vi->data_avail == 0)
request_entropy(vi);
return size;
}

Expand Down Expand Up @@ -98,13 +101,7 @@ static int virtio_read(struct hwrng *rng, void *buf, size_t size, bool wait)
* so either size is 0 or data_avail is 0
*/
while (size != 0) {
/* data_avail is 0 */
if (!vi->busy) {
/* no pending request, ask for more */
vi->busy = true;
reinit_completion(&vi->have_data);
register_buffer(vi);
}
/* data_avail is 0 but a request is pending */
ret = wait_for_completion_killable(&vi->have_data);
if (ret < 0)
return ret;
Expand All @@ -126,8 +123,7 @@ static void virtio_cleanup(struct hwrng *rng)
{
struct virtrng_info *vi = (struct virtrng_info *)rng->priv;

if (vi->busy)
complete(&vi->have_data);
complete(&vi->have_data);
}

static int probe_common(struct virtio_device *vdev)
Expand Down Expand Up @@ -163,6 +159,9 @@ static int probe_common(struct virtio_device *vdev)
goto err_find;
}

/* we always have a pending entropy request */
request_entropy(vi);

return 0;

err_find:
Expand All @@ -181,7 +180,6 @@ static void remove_common(struct virtio_device *vdev)
vi->data_idx = 0;
complete(&vi->have_data);
vdev->config->reset(vdev);
vi->busy = false;
if (vi->hwrng_register_done)
hwrng_unregister(&vi->hwrng);
vdev->config->del_vqs(vdev);
Expand Down

0 comments on commit 9a4b612

Please sign in to comment.