virtio-blk: support called read/write in interrupt

Coredump need call the block read/write ops in interrupt
Not consider the ops called in thread and intterupt simultaneously.
Only used for coredump now.

Signed-off-by: Bowen Wang <wangbowen6@xiaomi.com>
This commit is contained in:
Bowen Wang 2023-12-06 19:37:10 +08:00 committed by Xiang Xiao
parent cd86499e83
commit 0fbfcf4caf
1 changed files with 53 additions and 5 deletions

View File

@ -175,6 +175,38 @@ static int g_virtio_blk_idx = 0;
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: virtio_blk_wait_complete
*
* Description:
* Wait the virtio block request complete
*
****************************************************************************/
static void virtio_blk_wait_complete(FAR struct virtqueue *vq,
FAR sem_t *respsem)
{
if (up_interrupt_context())
{
for (; ; )
{
FAR sem_t * tmpsem = virtqueue_get_buffer(vq, NULL, NULL);
if (tmpsem == respsem)
{
break;
}
else if (tmpsem != NULL)
{
nxsem_post(tmpsem);
}
}
}
else
{
nxsem_wait_uninterruptible(respsem);
}
}
/****************************************************************************
* Name: virtio_blk_rdwr
*
@ -194,10 +226,17 @@ static ssize_t virtio_blk_rdwr(FAR struct virtio_blk_priv_s *priv,
ssize_t ret;
int readnum;
ret = nxmutex_lock(&priv->lock);
if (ret < 0)
if (up_interrupt_context())
{
return ret;
virtqueue_disable_cb(vq);
}
else
{
ret = nxmutex_lock(&priv->lock);
if (ret < 0)
{
return ret;
}
}
nxsem_init(&respsem, 0, 0);
@ -233,7 +272,8 @@ static ssize_t virtio_blk_rdwr(FAR struct virtio_blk_priv_s *priv,
/* Wait for the request completion */
nxsem_wait_uninterruptible(&respsem);
virtio_blk_wait_complete(vq, &respsem);
if (priv->resp->status != VIRTIO_BLK_S_OK)
{
vrterr("%s Error\n", write ? "Write" : "Read");
@ -241,7 +281,15 @@ static ssize_t virtio_blk_rdwr(FAR struct virtio_blk_priv_s *priv,
}
err:
nxmutex_unlock(&priv->lock);
if (up_interrupt_context())
{
virtqueue_enable_cb(vq);
}
else
{
nxmutex_unlock(&priv->lock);
}
return ret >= 0 ? nsectors : ret;
}