mirror of
https://github.com/apache/nuttx.git
synced 2026-05-20 04:16:35 +08:00
virtio-blk.c: change virtio blk req and resp to local variables
So we can remove the mutex lock to improve the virtio-block driver performance Signed-off-by: wangyongrong <wangyongrong@xiaomi.com>
This commit is contained in:
+45
-64
@@ -115,8 +115,6 @@ begin_packed_struct struct virtio_blk_config_s
|
||||
struct virtio_blk_priv_s
|
||||
{
|
||||
FAR struct virtio_device *vdev; /* Virtio deivce */
|
||||
FAR struct virtio_blk_req_s *req; /* Virtio block out header */
|
||||
FAR struct virtio_blk_resp_s *resp; /* Virtio block in header */
|
||||
mutex_t lock; /* Lock */
|
||||
uint64_t nsectors; /* Sectore numbers */
|
||||
uint32_t block_size; /* Block size */
|
||||
@@ -230,10 +228,35 @@ static ssize_t virtio_blk_rdwr(FAR struct virtio_blk_priv_s *priv,
|
||||
FAR struct virtio_device *vdev = priv->vdev;
|
||||
FAR struct virtqueue *vq = vdev->vrings_info[0].vq;
|
||||
FAR struct virtqueue_buf vb[3];
|
||||
struct virtio_blk_resp_s resp;
|
||||
struct virtio_blk_req_s req;
|
||||
sem_t respsem;
|
||||
ssize_t ret;
|
||||
int readnum;
|
||||
|
||||
nxsem_init(&respsem, 0, 0);
|
||||
|
||||
/* Build the block request */
|
||||
|
||||
req.type = write ? VIRTIO_BLK_T_OUT : VIRTIO_BLK_T_IN;
|
||||
req.reserved = 0;
|
||||
req.sector = startsector * priv->block_size >> VIRTIO_BLK_SECTOR_BITS;
|
||||
resp.status = VIRTIO_BLK_S_IOERR;
|
||||
|
||||
/* Fill the virtqueue buffer:
|
||||
* Buffer 0: the block out header;
|
||||
* Buffer 1: the read/write buffer;
|
||||
* Buffer 2: the block in header, return the status.
|
||||
*/
|
||||
|
||||
vb[0].buf = &req;
|
||||
vb[0].len = VIRTIO_BLK_REQ_HEADER_SIZE;
|
||||
vb[1].buf = buffer;
|
||||
vb[1].len = nsectors * priv->block_size;
|
||||
vb[2].buf = &resp;
|
||||
vb[2].len = VIRTIO_BLK_RESP_HEADER_SIZE;
|
||||
readnum = write ? 2 : 1;
|
||||
|
||||
if (up_interrupt_context())
|
||||
{
|
||||
virtqueue_disable_cb(vq);
|
||||
@@ -247,29 +270,6 @@ static ssize_t virtio_blk_rdwr(FAR struct virtio_blk_priv_s *priv,
|
||||
}
|
||||
}
|
||||
|
||||
nxsem_init(&respsem, 0, 0);
|
||||
|
||||
/* Build the block request */
|
||||
|
||||
priv->req->type = write ? VIRTIO_BLK_T_OUT : VIRTIO_BLK_T_IN;
|
||||
priv->req->reserved = 0;
|
||||
priv->req->sector = startsector *
|
||||
priv->block_size >> VIRTIO_BLK_SECTOR_BITS;
|
||||
priv->resp->status = VIRTIO_BLK_S_IOERR;
|
||||
|
||||
/* Fill the virtqueue buffer:
|
||||
* Buffer 0: the block out header;
|
||||
* Buffer 1: the read/write buffer;
|
||||
* Buffer 2: the block in header, return the status.
|
||||
*/
|
||||
|
||||
vb[0].buf = priv->req;
|
||||
vb[0].len = VIRTIO_BLK_REQ_HEADER_SIZE;
|
||||
vb[1].buf = buffer;
|
||||
vb[1].len = nsectors * priv->block_size;
|
||||
vb[2].buf = priv->resp;
|
||||
vb[2].len = VIRTIO_BLK_RESP_HEADER_SIZE;
|
||||
readnum = write ? 2 : 1;
|
||||
ret = virtqueue_add_buffer(vq, vb, readnum, 3 - readnum, &respsem);
|
||||
if (ret < 0)
|
||||
{
|
||||
@@ -283,7 +283,7 @@ static ssize_t virtio_blk_rdwr(FAR struct virtio_blk_priv_s *priv,
|
||||
|
||||
virtio_blk_wait_complete(vq, &respsem);
|
||||
|
||||
if (priv->resp->status != VIRTIO_BLK_S_OK)
|
||||
if (resp.status != VIRTIO_BLK_S_OK)
|
||||
{
|
||||
vrterr("%s Error\n", write ? "Write" : "Read");
|
||||
ret = -EIO;
|
||||
@@ -412,28 +412,31 @@ static int virtio_blk_flush(FAR struct virtio_blk_priv_s *priv)
|
||||
FAR struct virtio_device *vdev = priv->vdev;
|
||||
FAR struct virtqueue *vq = vdev->vrings_info[0].vq;
|
||||
FAR struct virtqueue_buf vb[2];
|
||||
struct virtio_blk_resp_s resp;
|
||||
struct virtio_blk_req_s req;
|
||||
sem_t respsem;
|
||||
int ret;
|
||||
|
||||
nxsem_init(&respsem, 0, 0);
|
||||
|
||||
/* Build the block request */
|
||||
|
||||
req.type = VIRTIO_BLK_T_FLUSH;
|
||||
req.reserved = 0;
|
||||
req.sector = 0;
|
||||
resp.status = VIRTIO_BLK_S_IOERR;
|
||||
|
||||
vb[0].buf = &req;
|
||||
vb[0].len = VIRTIO_BLK_REQ_HEADER_SIZE;
|
||||
vb[1].buf = &resp;
|
||||
vb[1].len = VIRTIO_BLK_RESP_HEADER_SIZE;
|
||||
|
||||
ret = nxmutex_lock(&priv->lock);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
nxsem_init(&respsem, 0, 0);
|
||||
|
||||
/* Build the block request */
|
||||
|
||||
priv->req->type = VIRTIO_BLK_T_FLUSH;
|
||||
priv->req->reserved = 0;
|
||||
priv->req->sector = 0;
|
||||
priv->resp->status = VIRTIO_BLK_S_IOERR;
|
||||
|
||||
vb[0].buf = priv->req;
|
||||
vb[0].len = VIRTIO_BLK_REQ_HEADER_SIZE;
|
||||
vb[1].buf = priv->resp;
|
||||
vb[1].len = VIRTIO_BLK_RESP_HEADER_SIZE;
|
||||
ret = virtqueue_add_buffer(vq, vb, 1, 1, &respsem);
|
||||
if (ret < 0)
|
||||
{
|
||||
@@ -445,7 +448,7 @@ static int virtio_blk_flush(FAR struct virtio_blk_priv_s *priv)
|
||||
/* Wait for the request completion */
|
||||
|
||||
nxsem_wait_uninterruptible(&respsem);
|
||||
if (priv->resp->status != VIRTIO_BLK_S_OK)
|
||||
if (resp.status != VIRTIO_BLK_S_OK)
|
||||
{
|
||||
vrterr("Flush Error\n");
|
||||
ret = -EIO;
|
||||
@@ -512,22 +515,6 @@ static int virtio_blk_init(FAR struct virtio_blk_priv_s *priv,
|
||||
vdev->priv = priv;
|
||||
nxmutex_init(&priv->lock);
|
||||
|
||||
/* Alloc the request and in header from tansport layer */
|
||||
|
||||
priv->req = virtio_alloc_buf(vdev, sizeof(*priv->req), 16);
|
||||
if (priv->req == NULL)
|
||||
{
|
||||
ret = -ENOMEM;
|
||||
goto err_with_lock;
|
||||
}
|
||||
|
||||
priv->resp = virtio_alloc_buf(vdev, sizeof(*priv->resp), 16);
|
||||
if (priv->resp == NULL)
|
||||
{
|
||||
ret = -ENOMEM;
|
||||
goto err_with_req;
|
||||
}
|
||||
|
||||
/* Initialize the virtio device */
|
||||
|
||||
virtio_set_status(vdev, VIRTIO_CONFIG_STATUS_DRIVER);
|
||||
@@ -542,18 +529,14 @@ static int virtio_blk_init(FAR struct virtio_blk_priv_s *priv,
|
||||
if (ret < 0)
|
||||
{
|
||||
vrterr("virtio_device_create_virtqueue failed, ret=%d\n", ret);
|
||||
goto err_with_resp;
|
||||
goto err;
|
||||
}
|
||||
|
||||
virtio_set_status(vdev, VIRTIO_CONFIG_STATUS_DRIVER_OK);
|
||||
virtqueue_enable_cb(vdev->vrings_info[0].vq);
|
||||
return OK;
|
||||
|
||||
err_with_resp:
|
||||
virtio_free_buf(vdev, priv->resp);
|
||||
err_with_req:
|
||||
virtio_free_buf(vdev, priv->req);
|
||||
err_with_lock:
|
||||
err:
|
||||
nxmutex_destroy(&priv->lock);
|
||||
return ret;
|
||||
}
|
||||
@@ -568,8 +551,6 @@ static void virtio_blk_uninit(FAR struct virtio_blk_priv_s *priv)
|
||||
|
||||
virtio_reset_device(vdev);
|
||||
virtio_delete_virtqueues(vdev);
|
||||
virtio_free_buf(vdev, priv->resp);
|
||||
virtio_free_buf(vdev, priv->req);
|
||||
nxmutex_destroy(&priv->lock);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user