Commit 9a4b612d authored by Laurent Vivier's avatar Laurent Vivier Committed by Michael S. Tsirkin

hwrng: virtio - always add a pending request

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: default avatarLaurent Vivier <lvivier@redhat.com>
Link: https://lore.kernel.org/r/20211028101111.128049-5-lvivier@redhat.comSigned-off-by: default avatarMichael S. Tsirkin <mst@redhat.com>
parent 5c8e9330
......@@ -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 */
......@@ -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. */
......@@ -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;
}
......@@ -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;
......@@ -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)
......@@ -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:
......@@ -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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment